查看 c++ 中的 UDP 消息

发布于 2024-10-29 12:42:57 字数 429 浏览 1 评论 0原文


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

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

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

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

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

I'm trying to receive a UDP message using sockets in c++.
I'm sending the size of the message in the header, so I can know how much memory should I allocate, so I try to peek at the beggining of the message like this:

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

but I keep getting system error 10040 :

"A message sent on a datagram socket
was larger than the internal message
buffer or some other network limit, or
the buffer used to receive a datagram
into was smaller than the datagram
itself."

Is there a way to peek just at the begging of the message?
thanks :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

£烟消云散 2024-11-05 12:42:57

鉴于 UDP 数据包的最大大小65507,您可以为您的所有 recvfrom() 调用分配一个 64k 的“反弹缓冲区” - 一旦您复制了它,读取大小,分配一个新的缓冲区,并复制您的数据包尺寸完全正确。

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

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

Given that the maximum size of a UDP packet is 65507, you could just allocate a single 64k 'bounce buffer' for all your recvfrom() calls -- once you've copied it in, read the size, allocate a new buffer, and make a copy of your packet at exactly the right size.

It is a little wasteful to be copying packet data around so much, but it would let you allocate buffers at the right size.

Or, if you know your peer will never generate packets larger than 8k because of the architecture of your application, you could just allocate 8k buffers and waste the space. Being conscious of memory use is important, but sometimes just burning an extra page leads to simpler code.

薄凉少年不暖心 2024-11-05 12:42:57

您可以尝试WSARecvMsg(..., MSG_PEEK)。您将在结果中获得设置的 MSG_TRUNC 标志,但您还应该具有所需的标头字节。

You could try WSARecvMsg(..., MSG_PEEK). You'll get the MSG_TRUNC flag set in the result, but you should also have the header bytes you asked for.

九公里浅绿 2024-11-05 12:42:57

你的代码实际上完全没问题。您应该已阅读 recvfrom

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

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

Your code is actually perfectly fine. You should have read the description of the error code WSAEMSGSIZE (that's your 10040) on the page of recvfrom.

The message was too large to fit into the buffer pointed to by the buf parameter and was truncated.

In your case the error code WSAEMSGSIZE is not really an error, because you are intentionally reading less than the full packet. Just parse your header and then read the full packet without MSG_PEEK to remove the packet from the input queue.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文