Узнать размер пришедшего UDP пакета
От: Аноним  
Дата: 17.10.11 09:24
Оценка:
Вопрос конечно ламерский, но гугл не помог.
Windows, MFC.
На слушающий UDP сокет приходит пакет неизвестного формата, нужно узнать его размер и корректно вычитать. Как?
Или как гарантированно почистить буфера после операции Receive, когда я вычитал всю информацию?
Re: Узнать размер пришедшего UDP пакета
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 17.10.11 10:25
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Вопрос конечно ламерский, но гугл не помог.

А>Windows, MFC.
А>На слушающий UDP сокет приходит пакет неизвестного формата, нужно узнать его размер и корректно вычитать. Как?

В буфер 64KB гарантированно влезет любой UDP пакет.
Если у вас не жестокое embedded, этого достаточно.
Конкретный размер принятого будет вернут из функции recv() или аналога. Имейте в виду, что он может быть равен 0, и это допустимая ситуация (пустые UDP-пакеты активно используются, например, как echo reply для NAT keepalive).

Если нужно адаптироваться под размер, тот же recv() с флагом MSG_PEEK читает пакет, но не удаляет из головы очереди. Получив размер, можно дать уже нормальный буфер и повторить вызов.

А>Или как гарантированно почистить буфера после операции Receive, когда я вычитал всю информацию?


Без MSG_PEEK оно чистится автоматически. Надо, наоборот, ставить флаг, чтобы не чистилось.
Но очистка идёт по 1 пакету за чтение.
Если вы не знаете, сколько пришло пакетов, то читать про select() и неблокирующий ввод/вывод.
The God is real, unless declared integer.
Re[2]: Узнать размер пришедшего UDP пакета
От: Аноним  
Дата: 18.10.11 07:35
Оценка:
Здравствуйте, netch80, Вы писали:

N>Без MSG_PEEK оно чистится автоматически. Надо, наоборот, ставить флаг, чтобы не чистилось.

N>Но очистка идёт по 1 пакету за чтение.
N>Если вы не знаете, сколько пришло пакетов, то читать про select() и неблокирующий ввод/вывод.

Да, я протупил с тем что Receive возвращает размер.
Но проблема осталась.
Выглядит это так: есть некоторый источник UDP пакетов, который фигачит UDP пакеты одинакового размера с большой частотой.
Есть принимающий код на MFC (свой класс, унаследованный от слушающего сокета с виртуальной функцией OnReceive), который принимает эти пакеты и подсчитывает их количество.
В этом коде я корректно вычитываю все что пришло (т.е. с помощью MSG_PEEK узнаю размер и вычитываю ровно столько, сколько нужно).
Программа вычитывает некоторое количество пакетов (каждый раз по разному — от нескольких сотен до тысяч) и прекращает их вычитывать. Пробовал вычитывать коды ошибок — все по нулям.
WireShark при этом продолжает ловить эти пакеты, т.е. источник работает корректно.
Перезапуск программы помогает на какое-то время, она вновь начинает вычитывать пакеты... опять несколько сотен и опять останавливается. Но не зависает, просто перестает возникать событие OnReceive.
Что это может быть? Как узнать причину остановки?
Re: Узнать размер пришедшего UDP пакета
От: avp_  
Дата: 18.10.11 07:40
Оценка:
Аноним 653 wrote:

> На слушающий UDP сокет приходит пакет неизвестного формата, нужно

> узнать его размер и корректно вычитать. Как?

Использовать ioctlsocket с опцией FIONREAD
Кстати, recv вернёт ошибку WSAEMSGSIZE если переданный буфер мал.

> Или как гарантированно

> почистить буфера после операции Receive, когда я вычитал всю
> информацию?

Вызвать в цикле ioctlsocket и recv пока не получим 0.
Posted via RSDN NNTP Server 2.1 beta
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.