【问题标题】:boost::asio async_read guarantee all bytes are readboost::asio async_read 保证读取所有字节
【发布时间】:2011-02-08 13:28:53
【问题描述】:

我有一个从客户端接收压缩字符串(用 zlib 压缩)的服务器,我使用 boost::asio 库中的 async_receive 来接收这个字符串,但事实证明,不能保证所有字节将被接收,所以我现在必须将其更改为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&lt;char, 1024&gt;

【问题讨论】:

    标签: c++ asynchronous boost-asio


    【解决方案1】:

    您希望如何使用任何其他方法来做到这一点?

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

    1. 按消息 - 表示您有一个定义预期消息长度的标头,后跟一个包含指定长度数据的正文。
    2. 按流 - 意味着您有一些标记(这是非常广泛的)方法来知道您何时获得了一个完整的数据包。
    3. 通过连接 - 每个完整的数据包都在单个连接中发送,一旦数据完成,该连接将关闭。

    所以你的数据可以被解析,或者发送一个长度等等......

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        【解决方案3】:

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

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

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

        【讨论】:

        • @b.g.您的评论不正确,只需阅读接受的答案,您就会发现第 1 项是 Content-Length 的一般情况。
        • @b.g.再次阅读代码并提问:它与TCP解析无关。用户需要知道来自 recv() 的数据是否都是发送者发送的。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-12-10
        • 2013-12-21
        • 1970-01-01
        • 1970-01-01
        • 2013-02-24
        相关资源
        最近更新 更多