Просмотр сообщения UDP в c ++ - PullRequest
6 голосов
/ 02 апреля 2011


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

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

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

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

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

Ответы [ 3 ]

6 голосов
/ 02 апреля 2011

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

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

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

3 голосов
/ 02 апреля 2011

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

0 голосов
/ 17 февраля 2015

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

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

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

...