用于接收 UDP 数据包的可变大小缓冲区

2024-03-28

我有一个 UDP 套接字,它将接收一些可能不同大小的数据包,并且我异步处理它:

socket.async_receive_from(boost::asio::buffer(buffer, 65536), senderEndpoint, handler);

这里的问题是,为了处理不同的大小,我有一个大缓冲区,可以使用可变大小的缓冲区来解决。

据我了解,当使用async_receive_from,一次仅使用一个数据包调用处理程序,因为数据包边界保留在 UDP 中。所以,有没有办法给一个空缓冲区async_receive_fromAsio 将增长以适应数据包大小 ?

另请注意,我包装了数据包,因此对于传输到此套接字的每个数据包,前 4 个字节是数据包的长度。


为了获得更准确的答案,这里有详细且解释的代码。

首先,我们需要调用接收处理程序而不填充缓冲区。这是使用完成的boost::asio::null_buffer() (see 反应堆式操作 http://www.boost.org/doc/libs/1_55_0/doc/html/boost_asio/overview/core/reactor.html欲了解更多信息,如坦纳所述)。

void UDPConnection::receive()
{
    socket.async_receive(boost::asio::null_buffers(), receive_handler);
}

现在,当收到数据包时,receive_handler将在没有任何缓冲区被填充的情况下被调用。

现在,对于处理程序:

void UDPConnection::handleReceive(const boost::system::error_code& error, unsigned int)
{
    // Standard check: avoid processing anything if operation was canceled
    // Usually happens when closing the socket
    if(error == boost::asio::error::operation_aborted)
        return;

With socket.available() http://www.boost.org/doc/libs/1_55_0/doc/html/boost_asio/reference/basic_datagram_socket/available.html,我们可以得到要读取的字节数。重要提示:这个数字不一定是数据包的大小!对于我的测试,这个数字总是大于数据包大小(即使是 8 kB 的数据包,这是我的计算机可以处理的最大数据包)。

    // Prepare buffer
    unsigned int available = socket.available();
    unsigned char* buffer = new unsigned char[available];

神奇的事情发生了:“真正的”接收调用在这里完成,并且通常会很快,因为它只会填充一个缓冲区。此调用只会使一个数据包出列(即使在调用时套接字中有多个数据包)。返回值在这里很重要,因为可能只填充了缓冲区的一部分。前任:可用=50,数据包大小=13.

    // Fill it
    boost::asio::ip::udp::endpoint senderEndpoint;
    boost::system::error_code ec;
    unsigned int packetSize = socket.receive_from(boost::asio::buffer(buffer, available), senderEndpoint, 0, ec);

现在,只需标准错误检查/处理/等等......

    if(ec)
    {
        // ...
    }

    // Process packet
    // ...
    receive();
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

用于接收 UDP 数据包的可变大小缓冲区 的相关文章

随机推荐