有办法在处理之前接收所有数据包吗?

时间:2014-09-10 08:42:53

标签: c++ boost-asio

我有一个具有以下循环的应用程序:

void receive() {
    socket.async_receive_from( asio::buffer(buffer,buffer_len),recv_endpoint,
    [&)(const ec& error, size_t recvd_len) {
        if( error ) throw error;
        new_packet(buffer,recvd_len);
        handle_received();
        receive();
    });
};

我的handle_received()函数非常慢,当它完成时,UDP缓冲区中已经有很多数据包在等待。我想要实现的是接收首先可用的所有内容,然后只调用handle_received()一次。

1 个答案:

答案 0 :(得分:2)

是的,有办法做到这一点。但是,您仍然需要支付每个数据包的系统调用费用。

  1. 确保您的UDP套接字处于非阻塞模式。
  2. 接收处理程序中的

    1. 将刚收到的数据包推入队列。
    2. 只要receive_from()非异步版本未返回asio::error::would_block错误,就会
    3. 循环。
    4. 每次转过循环,排队刚收到的数据包。
    5. 循环之后,在整个队列上运行处理函数。
    6. 此技术对TCP套接字也非常有用,因为它可以降低拾取下一个数据包/缓冲区的延迟。

      如果receive_from()返回另一个错误,您可能也希望打破循环,并可能以某种方式处理错误。

      使函数更加统一的一种方法是使用boost :: asio :: null_buffers`发出async_receive_from()。这将在套接字变为可读时调用您的处理程序,而不会将数据包交给您。这样,您的所有数据包都会在循环中读取。