![]() |
Модераторы: feodorv |
![]() ![]() ![]() |
|
Alexander06 |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 90 Регистрация: 28.7.2006 Репутация: нет Всего: нет |
Здравствуйте.
Использую функцию recv для получения данных по TCP установил таймаут 2 сек на прием данных. Отправляющая сторона шлет пакеты фиксированной длинны с частотой 100 Гц Функции recv указываю получить число байт, соответствующее размеру пакета. В возвращаемом значении согласно описанию - число принятых байт. Почему-то иногда функция recv считывает меньшее число байт, дочитывая оставшуюся часть пакета за следующий вызов. Не могу понять..если данные приходят неравномерно, то должен же таймаут заставлять ее ожидать прихода оставшейся части? Тем более что он значительно больше предполагаемых задержек. И почему в следующий заход recv читает именно оставшуюся часть пакета, даже если указать ему считать полную длину? Зараннее спасибо. |
|||
|
||||
ptr |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 661 Регистрация: 31.5.2006 Где: Новосибирск Репутация: 9 Всего: 14 |
recv возвращает уже пришедшие данные вплоть до запрошенного объема, он не ждет пока придут все данные.
Нет. Таймаут служит не для того, чтобы указывать сколько времени ждать всех данных , а указывает максимальное время работы recv. Т.е. если данные не пришли, то через указанное время таймаута recv выйдет из блокировки. Это сообщение отредактировал(а) ptr - 19.5.2008, 05:46 -------------------- Единственный способ определить границы возможного - это выйти за эти границы, в невозможное. Артур Кларк. |
||||
|
|||||
Олег2005 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 421 Регистрация: 26.5.2005 Где: Рига Латвия Репутация: 6 Всего: 11 |
Назначение recv() - копировать из приемного буфера модуля TCP то, что имеется в нем на момент обращения к функции. Сколько в приемном буфере накапало с канального уровня - сие науке неизвестно - это сеть. Насчет таймаута. По жизни у recv() cвоего таймаута нет - по вполне понятной причине - лишь некоторые стеки позволяют его устанавливать. Значит, таймаут устанавливается внешней функцией - например select(). Она вообще никакого отношения к сети не имеет - и сколько там байтов и где - ей глубоко безразлично. |
|||
|
||||
Arrowdodger |
|
|||
Новичок Профиль Группа: Участник Сообщений: 4 Регистрация: 21.5.2008 Репутация: нет Всего: нет |
может немного оффтоп, но такой вопрос - recv при вызове блокирует выполнение программы.
а мне нужно чтобы если в буфере ничего нет то программа выполнялась дальше. как это сделать? |
|||
|
||||
Олег2005 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 421 Регистрация: 26.5.2005 Где: Рига Латвия Репутация: 6 Всего: 11 |
Два варианта:
Первый: Запускаем recv() с флагом MSG_PEEK
Или использовать ioctlsocket(socket, FIONREAD, count) для той же цели. Есть одно но - значение 0 в буфере может трактоваться по разному - или пришло 0 байтов или сервер закончил передачу и закрыл сокет Второй вариант - самый лучший. Сделать операцию recv() асинхронной - те объявить сокет асинхронным при помощи того же ioctlsocket() и команды FIONBIO. Тогда recv() можно запустить и она сразу вернет управление в программу, которую можно дальше продолжать. Затем функцией select() через некоторое время проверить результат завершения recv() |
|||
|
||||
Arrowdodger |
|
|||
Новичок Профиль Группа: Участник Сообщений: 4 Регистрация: 21.5.2008 Репутация: нет Всего: нет |
да, второй вариант ниче так, только вот насчет select():
у меня recv() стоит в бесконечном цикле вот так:
выходит я могу не вызывать select() позже, а просто дожидаться следующей итерации цикла? |
|||
|
||||
Олег2005 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 421 Регистрация: 26.5.2005 Где: Рига Латвия Репутация: 6 Всего: 11 |
Если recv() стоит в цикле, дожидаясь признака конца передачи (возврат 0) на блокирующем сокете, то использование селекта не дает ничего. Это сообщение отредактировал(а) Олег2005 - 24.5.2008, 20:47 |
|||
|
||||
![]() ![]() ![]() |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Сети | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |