【问题标题】:Peeking at a UDP message in c++在 C++ 中查看 UDP 消息
【发布时间】:2011-04-02 06:23:13
【问题描述】:


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

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

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

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

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

【问题讨论】:

    标签: c++ windows udp peek


    【解决方案1】:

    鉴于maximum size of a UDP packet65507,您可以为所有recvfrom() 调用分配一个64k 的“反弹缓冲区”——一旦您将其复制进去,读取大小,分配一个新缓冲区,并以正确的大小复制您的数据包。

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

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

    【讨论】:

    • +1 这是常见的模式,我在windows中不知道,但是在某些操作系统中,只读取部分消息会丢弃其余部分,所以常见的模式是试图读取 64k (将返回消息实际占用了多少)
    • @David:我希望MSG_PEEK 标志可以防止任何东西被丢弃。
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-09-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-12-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多