查看 c++ 中的 UDP 消息
我正在尝试使用 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
鉴于 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 yourrecvfrom()
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.
您可以尝试
WSARecvMsg(..., MSG_PEEK)
。您将在结果中获得设置的MSG_TRUNC
标志,但您还应该具有所需的标头字节。You could try
WSARecvMsg(..., MSG_PEEK)
. You'll get theMSG_TRUNC
flag set in the result, but you should also have the header bytes you asked for.你的代码实际上完全没问题。您应该已阅读 recvfrom。
在您的情况下,错误代码
WSAEMSGSIZE
并不是真正的错误,因为您故意读取少于完整的数据包。只需解析标头,然后读取不带MSG_PEEK
的完整数据包即可从输入队列中删除该数据包。Your code is actually perfectly fine. You should have read the description of the error code
WSAEMSGSIZE
(that's your10040
) on the page of recvfrom.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 withoutMSG_PEEK
to remove the packet from the input queue.