Проблема приема файла на Winsock
Сегодня приступил к практическому изучению C++ на Visual Studio. Решил написать консольные проги для передачи и приема файла. Сразу оговорюсь что тестю на одном компе пока. Проблема заключается в том, что принимаемый файл создается на некоторое количество байт меньше, не слишком критично для txt и pdf, но к примеру архивы не передашь. Передаю функцией TransmitFile. Проблема как мне кажется на принимающей стороне, так что приведу кусок его кода:
char TempBuf [1024];
int l;
DWORD dwWritten;
sRecieve=accept(hSocket,(struct sockaddr*)&ClientAddr,&client_addr_size);
hFile=CreateFile("hi.rar",GENERIC_WRITE,FILE_SHARE_WRITE,NULL,CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
if(hFile != INVALID_HANDLE_VALUE)
{
SetFilePointer (hFile, 0, NULL, FILE_BEGIN);
int nReceivedFile = 0;
int k;
do {
l=recv(sRecieve,TempBuf,sizeof(TempBuf)-1,0);
if(l<0) break;
WriteFile (hFile, TempBuf, l, &dwWritten, NULL);
nReceivedFile+=l;
}
while (l>0);
printf("%8i",nReceivedFile);
CloseHandle(hFile);
}
к примеру пытаюсь передать архив размером 60 452 120 КБ, пишется всегда 60 451 840. Есть возможность что не успевает писать в файл и из-за этого тормозится прием. В общем голову сломал. Иногда файлы доходят, но это редкость. Также использовал вот это: setsockopt, стало работать стабильней по приему, но скорость упала оч сильно.
Надеюсь, что поможете мне разобраться в этом :)
P.S. После передачи различных файлов было выявлено, что максимальное отличие размера принятого файла от передаваемого 1024 байта, что наводит мысли о принимающем буфере, делать его оптимальным с помощью setsockopt мне бы не хотелось по причине приведенной выше. Кроме того файлы в случае одном из пяти передаются без проблем, на ура.
не обижайте тестя, он отец жены. И не надо его оговаривать.
а накуя это мне надо? Что бы подобный идиот как ты называл себя программистом? Читая мою подпись придурок, перед тем как флудить.
Код простой: создан сокет, присоединен, открыт файл, и передача одной функцией, почему именно ей? просто хочется посмотреть на ее работу, тем более не надо городить еще кода. Ну это про отправление. А при приеме точно так же создается сокет, потом еще один связывается с передающей стороной, ну а далее видно что происходит. Проследить за тем что передается возможно пожалуй с помощью сниффера и к примеру файрвола, чем завтра и займусь, также как невозможно и узнать на какой стадии находится передача файла. А вот на принимающей стороне возможно больше действий. К примеру известно что кол-во принятых байт nReceivedFile совпадает с записанным в файл. И вот тут у меня и ступор, где теряются, и в чем ошибка мне неизвестно.
…
P.S. После передачи различных файлов было выявлено, что максимальное отличие размера принятого файла от передаваемого 1024 байта
Рискну предположить(подкрепив предположение практическим расчётом),что размер файла округляется до этих самых 1024 байт,ибо 60451840/1024=59035.Стало быть,вам надо как-то получать реальный размер файла(например,внимательнее почитать про TransmitFile или setsockopt),или просто передавать информацию о реальном размере
Щастья вам в освоении сокетов!
ну так а что вы хотите? Я несколько раз ведь повторил вам - используйте отладчик. Помимо прочего - смешно обвинять меня в невнимательности - если только посмотреть на описание функции. У меня отсутсвуют телепатические способности. Я не могу догадатся - как и что вы отсылаете - поэтому это не грубость. Это просто констатация печального факта.
[COLOR="Gray"]Нешто там риальне такие проблемы?[/COLOR]
[COLOR="Gray"]Нешто там риальне такие проблемы?[/COLOR]
афтар памоему зачотный оленивод.
Вместо того. что бы проверить что и сколько отправляется на самом деле функцией, он исчисляет статистические закономерности сколько и чего у него не пришло.
Рекомендую так же учитывать фазу Луны и ее местоположение относительно Зодиака.
Я вызывал функцию Transmitfile с флагом TF_DISCONNECT, не то, чтобы так делать нельзя, но похоже в саму функцию не встроена проверка на то пришли ли все данные на что я в общем-то надеялся. Сама функция отсылает точное количество байт и после передачи последнего пакета разъединяет сокет. А вот на стороне приема эти данные почему-то не проходят (это для меня странно и рушит данную теорию, ведь тестировал в условиях идеальной сети, где потерь пакетов не должно быть), все изменяется если убрать данный флаг и поставить небольшую задержку до дисконекта. Файл передается полностью в этом случае. В общем проблема была в реализации самой TCP :), данные считаются дошедшими как только отправлены.
Вижу вы не очень внимательно прочитали мой первый пост "Передаю функцией TransmitFile". Более о передающей стороне писать то и нечего.
? :)
За то что разобрался - держи заслуженный плюс.
По поводу - "данные считаются дошедшими..." на самом опять же вероятно причина не в этом.