[winsock] recv с таймаутом
select ?
Да, я думал о select. Но мне ситуация видится так. Вот я вызываю select он говорит, что есть данные для чтения. Но ведь не факт, что их хватит, чтобы заполнить мой буфер. Значит надо опять же реализовывать цикл, в цикле делать select/read и при этом наблюдать, не пропустили ли мы таймаут. То есть почти то же самое, что я предложил в первом посте. А хочется как-то без цикла обойтись...
либо select и неблокирующийся recv, либо блокирующийся recv и сигнал от таймера который разблокирует по таймауту.
либо select и неблокирующийся recvКак?
либо сигнал от таймера который разблокирует по таймаутуНе дашь ссылки на соответствующие winapi функции?
вычитывай по столько, по сколько приходит и собирай в свой буфер, как только накопится необходимое количество - обрабатывай.
вот (ioctlsocket) похоже на то, что тебе нужно
вообще, может там есть recv с таймаутом. но если он и есть то не работает.
в общем запили цикл вокруг неблокирующегося recv и не мучайяся.
Осталось проверить, сработает ли.
SO_RCVTIMEO
The timeout, in milliseconds, for blocking receive calls. The default for this option is zero, which indicates that a receive operation will not time out. If a blocking receive call times out, the connection is in an indeterminate state and should be closed.
If the socket is created using the WSASocket function, then the dwFlags parameter must have the WSA_FLAG_OVERLAPPED attribute set for the timeout to function properly. Otherwise the timeout never takes effect.
если не по таймауту придет немного байтов, как их обратно запихивать будешь?
Ну я сейчас использую recv с MSG_WAITALL. Надеюсь, это решит проблему, и у меня будет либо полный буфер, либо таймаут. К сожалению, сейчас нет под руками оборудования, на котором все это должно работать, так что проверить не могу.
select нужен затем, чтобы процессор не молотил цикл в пустую.
Что такое SO_RCVTIMEO точно не знаю, но думаю это настройка таймаута индикации ошибки при работе с оверлаппед сокетом. В общем, явно не то, что тебе нужно.
Что такое SO_RCVTIMEO точно не знаю,Но оно работает как надо, тем не менее
Оставить комментарий
olega
Нужно реализовать функцию наподобие recv со следующим поведением: она или считывает заданное количество байт из сокета за указанное время (или быстрее или вываливается по таймауту, если не может. Использовать многопоточность и message loop нельзя.Мне не пришло в голову ничего умнее, чем включить у сокета неблокирующий режим, а потом в цикле читать из него и в то же время смотреть, сколько времени прошло с момента вызова функции, и, если время вышло, прекращать цикл и выходить по таймауту.
Но наверняка должно быть более толковое решение, а?