Просмотр сообщения UDP в С++


Я пытаюсь получить UDP-сообщение, используя сокеты в C++.
Я отправляю размер сообщения в заголовке, поэтому я могу знать, сколько памяти мне нужно выделить, поэтому я пытаюсь просмотреть начало сообщения такое:

int bytesRead = recvfrom(m_socketId, (char*)&header, Message::HeaderSize, MSG_PEEK, (struct sockaddr *)&fromAddr, &addrSize);  

но я продолжаю получать системную ошибку 10040:

«Сообщение, отправленное в сокет дейтаграммы, было больше, чем внутренний буфер сообщений или какое-либо другое сетевое ограничение, или буфер, используемый для приема дейтаграммы, был меньше, чем сама дейтаграмма».

Есть ли способ заглянуть в начало сообщения?
спасибо :)


person Idov    schedule 02.04.2011    source источник


Ответы (3)


Учитывая, что максимальный размер UDP-пакета равен 65507, вы можете просто выделить один 64k ' bounce buffer» для всех ваших вызовов recvfrom() — после того, как вы его скопировали, прочтите размер, выделите новый буфер и сделайте копию вашего пакета точно в нужном размере.

Копировать пакетные данные в таком количестве немного немного расточительно, но это позволит вам выделить буферы нужного размера.

Или, если вы знаете, что ваш одноранговый узел никогда не будет генерировать пакеты размером более 8 КБ из-за архитектуры вашего приложения, вы можете просто выделить буферы 8 КБ и тратить место впустую. Важно помнить об использовании памяти, но иногда просто запись дополнительной страницы приводит к более простому коду.

person sarnold    schedule 02.04.2011
comment
+1 Это распространенный шаблон, я не знаю, в Windows, но в некоторых ОС чтение только части сообщения отбрасывает остальную его часть, поэтому общий шаблон пытается прочитать 64 КБ (вернет сколько сообщение на самом деле принял) - person David Rodríguez - dribeas; 02.04.2011
comment
@David: я надеюсь, что флаг MSG_PEEK предотвращает отбрасывание чего-либо. - person Ben Voigt; 02.04.2011

Вы можете попробовать WSARecvMsg(..., MSG_PEEK). В результате вы получите установленный флаг MSG_TRUNC, но у вас также должны быть запрошенные байты заголовка.

person Ben Voigt    schedule 02.04.2011

Ваш код на самом деле в порядке. Вы должны были прочитать описание кода ошибки WSAEMSGSIZE (это ваш 10040) на странице получено от.

Сообщение было слишком большим, чтобы поместиться в буфер, указанный параметром buf, и было усечено.

В вашем случае код ошибки WSAEMSGSIZE на самом деле не является ошибкой, потому что вы намеренно читаете меньше, чем полный пакет. Просто проанализируйте свой заголовок, а затем прочитайте полный пакет без MSG_PEEK, чтобы удалить пакет из входной очереди.

person Max Truxa    schedule 17.02.2015