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

 _Yoha 发布于 2023-02-12 15:06

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

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

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

据我所知,在使用时async_receive_from,一次只调用一个数据包,因为数据包边界在UDP中保留.那么,有没有办法给空缓冲区async_receive_from,Asio会增长到适合数据包大小

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

1 个回答
  • 有关更精确的答案,请参阅详细说明的代码.

    首先,我们需要在不填充缓冲区的情况下调用接收处理程序.这是使用boost::asio::null_buffer()(参见反应堆式操作以获取更多信息,如Tanner所述).

    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;
    

    有了socket.available(),我们可以得到要读取的字节数.重要提示:此数字不一定是数据包的大小!对于我的测试,这个数字总是大于数据包大小(即使是8 kB数据包,这是我的计算机可以处理的最大数据包).

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

    魔术发生在这里:"真正的"接收呼叫在这里完成,并且通常会很快,因为它只会填充一个缓冲区.此调用只会使一个数据包出列(即使在调用时,套接字中有多个数据包).返回值在这里很重要,因为只有缓冲区的一部分可能已被填充.例如:可用= 50,packetSize = 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();
    }
    

    2023-02-12 15:09 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有