6


我正在尝试使用 c++ 中的套接字接收 UDP 消息。
我在标头中发送消息的大小,所以我可以知道我应该分配多少内存,所以我尝试像这样查看消息的开头:

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

但我不断收到系统错误 10040 :

“在数据报套接字上发送的消息大于内部消息缓冲区或其他网络限制,或者用于接收数据报的缓冲区小于数据报本身。”

有没有办法只看消息的乞求?
谢谢 :)

4

3 回答 3

6

鉴于UDP 数据包的最大大小65507,您可以为所有调用分配一个 64k 的“反弹缓冲区” recvfrom()——一旦将其复制进去,读取大小,分配新缓冲区,然后复制您的数据包尺寸正好合适。

复制大量数据包数据有点浪费,但它可以让您以正确的大小分配缓冲区

或者,如果您知道由于应用程序的体系结构,您的对等方永远不会生成大于 8k 的数据包,您可以分配 8k 缓冲区并浪费空间。意识到内存使用很重要,但有时只是烧掉一个额外的页面会导致代码更简单。

于 2011-04-02T06:34:21.377 回答
3

你可以试试WSARecvMsg(..., MSG_PEEK)。您将MSG_TRUNC在结果中设置标志,但您还应该有您要求的标头字节。

于 2011-04-02T06:41:55.380 回答
0

您的代码实际上非常好。您应该已经阅读了recvfrom页面上的错误代码描述WSAEMSGSIZE(那是您的) 。10040

消息太大,无法放入 buf 参数指向的缓冲区并被截断。

在您的情况下,错误代码WSAEMSGSIZE并不是真正的错误,因为您故意读取的内容少于完整的数据包。只需解析您的标头,然后读取完整MSG_PEEK的数据包,而无需从输入队列中删除数据包。

于 2015-02-17T09:54:29.853 回答