блин... ну а как с ней обращаться? Как с девушкой чтоли? Мягко и нежно? Шутка... Ты имеешь ввиду c memcpy и т.п. все копировать?
да. Если ты хочешь написать действительно качественное сетевое приложение то сначала почитай эту книгу: Йон Снейдер "Эффективное программирование TCP/IP"
Понятно. TransmitFile посмотрел. Хорошо конечно. Но я так и не смог заставить ее работать. Возвращает какую-то ошибку с номером 6. На мсдн нет даже ее. Плюс еще размер программы увеличился. Было около 50кб а стало 173! За книжку спасибо - посмотрим...
С TransmitFile все предельно просто надо просто 2 указателя открытого приконекченного сокета и открытого файла. Code: char fname[1024]; SOCKET s;WSADATA wsd; SOCKADDR_IN adr; WSAStartup(MAKEWORD(2,0),&wsd); adr.sin_family=AF_INET; adr.sin_port=htons(1060); adr.sin_addr.s_addr=inet_addr("127.0.0.1"); s=socket(AF_INET,SOCK_STREAM,0); connect(s,(sockaddr*)&adr,sizeof(adr)); HANDLE f=CreateFile(fname,GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_FLAG_RANDOM_ACCESS,0); TransmitFile(s,f,0,1024*1024,NULL,0,TF_USE_KERNEL_APC);//файл передается кусками по мегабайту closesocket(s); CloseHadle(f); Принимать то же просто.То есть в бесконечном цикле пока recv возвращяет значения больше 0.
Ну вот как у меня было: Code: HANDLE hFile=CreateFile("12321sa.txt",GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); ///////HANDLE hFile=OpenFile(filename,&os,OF_READ); if(!TransmitFile(client,hFile,0,1024,NULL,0,TF_DISCONNECT)){ switch(WSAGetLastError()){ ........ default:strcpy(temp,"Unknown Code Error...");break; } ... } Вроде все норм, но по-любому выводился "ERROR 6: Unknown Code Error", ну или как вы говорите неверный дескриптор ... Ну ладно... Вообщем сделал я, народ, передачу файлов "своим способом". Спасибо кстати Бонсу за совет про строки. Теперь и бинарные и текстовые передает. Плюс конечно же в том, ЧТО ПРОЦЕСС ОТПРАВКИ МОЖНО ОТСЛЕДИТЬ Вот конечный вариант кода: Code: // Посылаем файл int sendfile(int ptr, char filename[255]) { char temp[300]=""; SOCKET client=(SOCKET)ptr; char filebuff[1024]; char sendbuff[2048]; OFSTRUCT os; os.cBytes = sizeof os; int err,i,size=0; FILE *fp; if(FileExists(filename)==True){ fp=fopen(filename,"rb"); int t=0; printf("\nSending file started..."); ZeroMemory (filebuff, sizof (filebuff)); Zero_Memory (sendbuff, sizeof (sendbuff)); long l=GetFSize(filename); sprintf(sendbuff,"%d",l); send(client,sendbuff,strlen(sendbuff),0); ZeroMemory (&sendbuff, sizeof (sendbuff)); while(1){ Sleep(10); err=fread(filebuff,1,768,fp); t++; if((size = send(client,filebuff,768,0))== SOCKET_ERROR) return -1; printf("\nPacket #%d>> %d bytes read, %d of %d bytes send",t,err,size,768); ZeroMemory (&filebuff, sizeof (filebuff)); if (err<768) beak; } printf("\nSending file completed successfully..."); fclose(f); return 1; }else{ sprintf(temp,"ERROR_SENDING_FILE_TO_CLIENTFile does not exist: %s",filename); printf("\n%s",temp); send(client,temp,sizePoh(temp),0); } } Code: //Принимаем файл /* a-сколько принято в данный момент l-сколько нужно принять =) А эти функции вам придется самим написать ии найти нечто похожее в нете (так сказать, тест такой ;) ): Str2Int - переводит строку в число до первого символа (первой встретившееся буквы) info - просто выводит текст в мемо ExtractFilename- извлекает имя файла из полного к нему пути ....... Все.... дальше сами разберетесь... */ int ReceiveFile() { int ret=0;char temp[20 * 1024]="";int i=0,j=0,t=0,k=0;long a=0; FILE *fp;char buff_x[20 * 1024]; MkDir("RcvdFiles"); sprintf(temp,"RcvdFiles\\%s",ExtractFilename(Edit4->Text.c_str())); unlink(temp); fp=fopen(temp,"wb"); Zero_Memory (szRecvBuff, sizeof (szRecvBuff)); ret = recv(s, szRecvBuff, 100, 0); if(strstr(szRecvBuff,"ERROR_SENDING_FILE_TO_CLIENT")){info(&szRecvBuff[28]);return 2;} long l=Str2Int(szRecvBuff); sprintf(temp,"Размер файла: %d байт",l); info(temp); ZeroMemory (&szRecvBuff, sizeof (szRecvBuff)); info("Начинаю принимать..."); ret=512; t=0; while(ret>0) { Sleep(10); strcpy(szRecvBuff,""); strcpy(tmp,""); t++; ZeroMemory (&buff_x, sizeof (buff_x)); ZeroMemory (szRecvBuff, sizeof (szRecvBuff)); ret = recv(s, szRecvBuff, 768, 0); a=a+ret; if(ret<=0){info("Прием файла успешно завершен");fclose(fp);return 1;} if (ret != SOCKET_EROR){ if(a>l){ret=ret-(a-l);a=l;} sprintf(temp,"Пакет #%d>> Получено: %d байтов. Уже записано: %d из всего возможных %d байтов",t,ret,a,l); info(temp); fwrite(szRecvBuff,ret,1,fp); if(a>=l-1){info("Прием файла успешно завершен");fclose(fp);return 1;} }else{ fputs("\nSOCKET ERROR",fp);return -1; } } fclose(fp); return 1; } Ну с ошибками там сами че-нибудь "помыслите"... Вот то что делает программа вкратце: -Посылаем с клиента команду на принятие файла (элементарно, сами напишите) -Передаем путь к файлу и уже подключенный сокет в ReceiveFile() -Та отправляет клиенту размер файла, если файл существует или "ERROR_SENDING_FILE_TO_CLIENT" если его нет. -А дальше просто передается файл, как обычно, частями. В результате получается нечто похожее на:
Code: HANDLE hFile=CreateFile("\\\\.\\C:\\12321sa.txt",GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,F ILE_ATTRIBUTE_NORMAL,NULL); http://msdn.microsoft.com/en-us/library/aa363858(VS.85).aspx
А теперь читаем: "\\?\" используется, чтобы распознавать строку с путем как уникод-строку и вследствие этого "удалить ограничение в 256 символов" в именах файлов и директорий. Можно конечно написать у меня в коде CreateFile("\\?\C:\\123sa.txt",...), но здесь то в любом случае меньше 256 сиволов строчка...
Че-то я такого там не вижу Ладно... Мне в-принципе итак как щас устраивает (даже мне кажется так по-лучше будет). Ну я говорю смысл в этом "префиксе" - избавиться от ограничений, но у меня то "123sa.txt" занимает всего 9 символов, а не 32767