Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Проблема приема файла на Winsock

56K
20 июня 2010 года
Hekeus
8 / / 18.03.2010
Всем Здравствуйте!
Сегодня приступил к практическому изучению C++ на Visual Studio. Решил написать консольные проги для передачи и приема файла. Сразу оговорюсь что тестю на одном компе пока. Проблема заключается в том, что принимаемый файл создается на некоторое количество байт меньше, не слишком критично для txt и pdf, но к примеру архивы не передашь. Передаю функцией TransmitFile. Проблема как мне кажется на принимающей стороне, так что приведу кусок его кода:

Цитата:
HANDLE hFile;
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 мне бы не хотелось по причине приведенной выше. Кроме того файлы в случае одном из пяти передаются без проблем, на ура.

1
20 июня 2010 года
kot_
7.3K / / 20.01.2000
Цитата: Hekeus
Сразу оговорюсь что тестю на одном компе пока.


не обижайте тестя, он отец жены. И не надо его оговаривать.

1
20 июня 2010 года
kot_
7.3K / / 20.01.2000
а по вашему вопросу - все конечно жутко рады что вы открыли для себя "С++ на Visual Studio". Было бы не плохо, если бы вместе с этим, вы бы открыли для себя дебагер, инструменты среды разработки, некоторые мозги - весь этот комплект позволит вам наверняка избежать издевательств в этих самых интернетах.
56K
21 июня 2010 года
Hekeus
8 / / 18.03.2010
Уважаемый kot_. Несмотря на ваше критические замечания, я рад что получен хоть какой-то отклик. Простите меня за излишний вопрос, но как пользоваться дебаггером в реальном времени если посылка пакетов шлется в реальном времени и при неплохой скорости. Как ни крути, а у меня не получалось получить нормальный результат. Хмм, инструменты среды, в будущем пожалуй и открою, ну а мозги, какие уж имеются. Так что раз уж вы являетесь таким мозговитым программистом, поделитесь своими знаниями с окружающими. Спасибо за критику, постараюсь в дальнейшем лучше изучать среду программирования прежде, чем задавать вопрос совершенно к этому не относящийся.
1
21 июня 2010 года
kot_
7.3K / / 20.01.2000
Вы шлете пакеты не в реальном времени - вы работаете в ОС, которая использует разнообразные приоритеты. Но кстати, заявление про мозги - весьма голословно - потому как вы не посчитали нужным приводить - как вы пакеты шлете. Например. Вам проще писать на форум, вместо того, что бы проверить - чего и куда вы шлете. Вы считаете что за вас это кто то должен сделать? Я ж говорю - про свои мозги вы весьма завышенного мнения.
1
21 июня 2010 года
kot_
7.3K / / 20.01.2000
Цитата: Hekeus
Так что раз уж вы являетесь таким мозговитым программистом, поделитесь своими знаниями с окружающими.


а накуя это мне надо? Что бы подобный идиот как ты называл себя программистом? Читая мою подпись придурок, перед тем как флудить.

56K
21 июня 2010 года
Hekeus
8 / / 18.03.2010
Опять же грубость, и только. Вижу вы не очень внимательно прочитали мой первый пост "Передаю функцией TransmitFile". Более о передающей стороне писать то и нечего. Флудим господин kot_ мы вместе и эт мне оч не нравится. Программистом я себя не считаю это лишь хобби не более. Ну а оскорбления лишь выражение собственной беспомощности, здесь уж я ничего поделать не могу.
Код простой: создан сокет, присоединен, открыт файл, и передача одной функцией, почему именно ей? просто хочется посмотреть на ее работу, тем более не надо городить еще кода. Ну это про отправление. А при приеме точно так же создается сокет, потом еще один связывается с передающей стороной, ну а далее видно что происходит. Проследить за тем что передается возможно пожалуй с помощью сниффера и к примеру файрвола, чем завтра и займусь, также как невозможно и узнать на какой стадии находится передача файла. А вот на принимающей стороне возможно больше действий. К примеру известно что кол-во принятых байт nReceivedFile совпадает с записанным в файл. И вот тут у меня и ступор, где теряются, и в чем ошибка мне неизвестно.
7
21 июня 2010 года
@pixo $oft
3.4K / / 20.09.2006
Цитата: Hekeus
к примеру пытаюсь передать архив размером 60 452 120 КБ, пишется всегда 60 451 840

P.S. После передачи различных файлов было выявлено, что максимальное отличие размера принятого файла от передаваемого 1024 байта

Рискну предположить(подкрепив предположение практическим расчётом),что размер файла округляется до этих самых 1024 байт,ибо 60451840/1024=59035.Стало быть,вам надо как-то получать реальный размер файла(например,внимательнее почитать про TransmitFile или setsockopt),или просто передавать информацию о реальном размере

Щастья вам в освоении сокетов!

1
21 июня 2010 года
kot_
7.3K / / 20.01.2000
Цитата: Hekeus
Опять же грубость, и только.


ну так а что вы хотите? Я несколько раз ведь повторил вам - используйте отладчик. Помимо прочего - смешно обвинять меня в невнимательности - если только посмотреть на описание функции. У меня отсутсвуют телепатические способности. Я не могу догадатся - как и что вы отсылаете - поэтому это не грубость. Это просто констатация печального факта.

56K
21 июня 2010 года
Hekeus
8 / / 18.03.2010
Еще раз проштудировал MSDN по Transmitfile. На всякий случай перевел на русский, в замечаниях нашел много нового, но к сожалению не относящиеся к данному случаю. @pixo $oft предположение очень интересное и сразу ухватился за него, но оно не оправдалось. После некоторых тестов, некоторые из них прошли весьма удачно даже с файлами в 1,5 гига, выяснил что разброс между первоначальным файлом и полученным составляет от 0 до 1024 байт. (если бы он все время составлял 0 байт то проблемы бы и не было :)). Впоследствии решил добавить к отправке файла функцию WSAGetLastError через switch. И я оч удивился когда передал различные файлы пять раз подряд, но на 6-й опять пошел разброс и главное ошибка неизвестная у WSAGetLastError. Правда работает уже с 50% успехом. Добавление Sleep(1000) не помогло, а то я уж решил что ему время надо. Не хотел я увеличивать передающий и принимающий код, но боюсь придется, пока иного выхода я не вижу. Расчет у меня такой. Если он не передает конец файла то просто дополнительно прислать ему этот недостающий конец и записать его, но если сбой случается где-то в середине ... .
7
21 июня 2010 года
@pixo $oft
3.4K / / 20.09.2006
Афтар,вы меня заинтриговали!Сдам сессию и сразу возьмусь за написание файлопередающего клиента!:D
[COLOR="Gray"]Нешто там риальне такие проблемы?[/COLOR]
1
22 июня 2010 года
kot_
7.3K / / 20.01.2000
Цитата: @pixo $oft
Афтар,вы меня заинтриговали!Сдам сессию и сразу возьмусь за написание файлопередающего клиента!:D
[COLOR="Gray"]Нешто там риальне такие проблемы?[/COLOR]


афтар памоему зачотный оленивод.
Вместо того. что бы проверить что и сколько отправляется на самом деле функцией, он исчисляет статистические закономерности сколько и чего у него не пришло.
Рекомендую так же учитывать фазу Луны и ее местоположение относительно Зодиака.

56K
22 июня 2010 года
Hekeus
8 / / 18.03.2010
Наконец-то выяснил в чем проблема.
Я вызывал функцию Transmitfile с флагом TF_DISCONNECT, не то, чтобы так делать нельзя, но похоже в саму функцию не встроена проверка на то пришли ли все данные на что я в общем-то надеялся. Сама функция отсылает точное количество байт и после передачи последнего пакета разъединяет сокет. А вот на стороне приема эти данные почему-то не проходят (это для меня странно и рушит данную теорию, ведь тестировал в условиях идеальной сети, где потерь пакетов не должно быть), все изменяется если убрать данный флаг и поставить небольшую задержку до дисконекта. Файл передается полностью в этом случае. В общем проблема была в реализации самой TCP :), данные считаются дошедшими как только отправлены.
1
22 июня 2010 года
kot_
7.3K / / 20.01.2000
ну слава Богу. И что теперь - ты по прежнему уверено заявишь:
Цитата:

Вижу вы не очень внимательно прочитали мой первый пост "Передаю функцией TransmitFile". Более о передающей стороне писать то и нечего.


? :)
За то что разобрался - держи заслуженный плюс.
По поводу - "данные считаются дошедшими..." на самом опять же вероятно причина не в этом.

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог