boost :: asio async_read保证读取所有字节

时间:2011-02-08 13:28:54

标签: c++ asynchronous boost-asio

我有一个服务器从客户端接收压缩字符串(使用zlib压缩),我使用async_receive库中的boost::asio来接收此字符串,但事实证明不保证将收到所有字节,因此我现在必须将其更改为async_read。我面临的问题是接收的字节大小是可变的,所以我不知道如何在不知道要接收的字节数的情况下使用async_read。使用async_receive我只有boost::array<char, 1024>,但这是一个不一定完全填充的缓冲区。

我想知道是否有人可以建议我可以使用async_read的解决方案,即使我不知道提前收到的字节数?

void tcp_connection::start(boost::shared_ptr<ResolverQueueHandler> queue_handler)
{
    if (!_queue_handler.get())
        _queue_handler = queue_handler;

    std::fill(buff.begin(), buff.end(), 0);

    //socket_.async_receive(boost::asio::buffer(buff), boost::bind(&tcp_connection::handle_read, shared_from_this(), boost::asio::placeholders::error));
    boost::asio::async_read(socket_, boost::asio::buffer(buff), boost::bind(&tcp_connection::handle_read, shared_from_this(), boost::asio::placeholders::error));
}

buffboost::array<char, 1024>

3 个答案:

答案 0 :(得分:20)

您是如何期望使用任何其他方法执行此操作的?

在异步庄园中发送可变大小的数据有一些通用的方法:

  1. 通过消息 - 意味着您有一个标题,用于定义预期消息的长度,后跟包含指定长度数据的正文。
  2. 通过流 - 意味着您有一些标记(这是非常广泛的)方法,可以知道何时获得完整的数据包。
  3. 通过连接 - 每个完整的数据包都在一个连接中发送,一旦数据完成就会关闭。
  4. 您的数据也可以被解析,或者发送长度等等......

答案 1 :(得分:2)

使用async_read_until并创建自己的match condition,或更改协议以发送包含压缩字符串中预期字节数的标头。

答案 2 :(得分:0)

单个IP数据包限制为~1500字节的MTU大小,但您仍然可以从您喜爱的网站下载千兆字节大文件,并在YouTube上观看兆字节大小的视频。

您需要发送一个标题,指示原始数据的实际大小,然后在较小的块上接收数据,直到您完成接收所有字节为止。

例如,当您通过HTTP下载大型文件时,标题上会有一个字段,指示文件的大小:Content-Length: