Вопрос конечно ламерский, но гугл не помог.
Windows, MFC.
На слушающий UDP сокет приходит пакет неизвестного формата, нужно узнать его размер и корректно вычитать. Как?
Или как гарантированно почистить буфера после операции Receive, когда я вычитал всю информацию?
Здравствуйте, Аноним, Вы писали:
А>Вопрос конечно ламерский, но гугл не помог. А>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.
Что это может быть? Как узнать причину остановки?
Аноним 653 wrote:
> На слушающий UDP сокет приходит пакет неизвестного формата, нужно > узнать его размер и корректно вычитать. Как?
Использовать ioctlsocket с опцией FIONREAD
Кстати, recv вернёт ошибку WSAEMSGSIZE если переданный буфер мал.
> Или как гарантированно > почистить буфера после операции Receive, когда я вычитал всю > информацию?
Вызвать в цикле ioctlsocket и recv пока не получим 0.