【问题标题】:Multiple Boost::ASIO async_send_to in one go一次多次 Boost::ASIO async_send_to
【发布时间】:2017-08-10 03:04:08
【问题描述】:

我想增加使用 Boost ASIO 的 udp 游戏服务器的吞吐量。 现在,每次我需要发送数据包时,我都会将其放入队列中,然后检查是否有待处理的 async_send_to 操作,如果有,则什么也不做,如果没有,则调用 async_send_to。 然后我等待调用写处理程序,然后为队列中的下一个数据包调用 async_send_to(如果有)。

文档说这是“用于 TCP 套接字”的方法,但整个互联网上都没有关于 UDP 套接字的信息。 试试看,在stackoverflow上搜索,你会看到没人谈论这个,而你会发现的2个问题,这个问题被用户忽略了。

为什么要保密? 对于 100 万美元的问题,我可以安全地连续多次调用 async_send_to 而不等待调用写入处理程序吗?

提前致谢。

【问题讨论】:

    标签: c++ sockets boost udp asio


    【解决方案1】:

    这个逻辑对于 UDP 协议没有意义,因为它不需要阻塞发送操作。数据报要么被传送要么丢失。 UDP 不必将其存储在输出缓冲区中并无限期地重新发送多次,直到它得到 ACK 数据包。

    【讨论】:

    • 所以为了确保,我是否能够连续调用所有 async_send_to,而无需等待调用写入处理程序,当然在调用处理程序之前保持缓冲区有效?
    【解决方案2】:

    不,您不能在不等待调用写入处理程序的情况下连续多次安全地调用async_send_to。请参阅Asynchronous IO with Boost.Asio 了解确切原因。

    但是,asio 支持 scatter gather,因此您可以使用多个缓冲区调用 async_send_to,例如:

    typedef std::deque<boost::asio::const_buffer> ConstBuffers;
    
    std::string msg_1("Blah");
    ...
    std::string msg_n("Blah");
    
    ConstBuffers buffers;
    buffers.push_back(msg_1);
    ...
    buffers.push_back(msg_n);
    
    socket_.async_send_to(buffers, tx_endpoint_, write_handler);
    

    因此,您可以通过 double buffering 您的消息队列并使用收集的写入来增加吞吐量...

    【讨论】:

    • 分散聚集是否将所有缓冲区作为单个数据报发送?
    • 这取决于您需要传输多少数据,您的以太网框架有多大,等等,但它会尽力将其放入尽可能少的数据报中。
    • 一个大于接口MTU的UDP数据报可以在IP层拆分成多个分片。然后在将完整的数据报呈现给应用程序之前重新组装这些片段,例如通过recvfrom()。在发送数据时和在套接字 API 中精确指定将数据成帧的数据报,并且通常是使用 UDP 协议的关键部分。缓冲区不能以某种未知方式组合成多个 UDP 数据报。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-14
    • 2012-07-01
    相关资源
    最近更新 更多