1

考虑以下:

std::istream& operator>>(std::istream& is, message& p)
{
    typedef boost::archive::binary_iarchive in;  
    boost::iostreams::filtering_istream fis;
    fis.push(is, 0);
    in stream(fis);
    stream >> p;

    return is;
}

其中message& p是可序列化的结构,并且std::istream& is是 tcp 流。

服务器在构造函数中等待客户端发送数据in stream(fis);,并在收到数据后继续。对象将streamtcp 流中的数据序列化到message对象中。

现在,通过添加以下内容实际过滤接收到的数据时:

std::istream& operator>>(std::istream& is, message& p)
{
    typedef boost::archive::binary_iarchive in;  
    boost::iostreams::filtering_istream fis;
    fis.push(boost::iostreams::zlib_decompressor(), 0);
    fis.push(is, 0);
    in stream(fis);
    stream >> p;

    return is;
}

应该从 tcp 流中读取数据,将其解压缩并将其序列化为message对象。但相反,它会in stream(fis);在数据发送 10-20 次或客户端断开连接后挂起并返回。

我已经尝试将 zlib 解压器的内部缓冲区设置为 0 和 1,其中 0 使断言失败,而 1 以某种方式只工作一次(在第二次迭代时抛出)。我还将filtering_istream缓冲区设置为 0,因此不会导致挂起。我还注意到,如果它std::istream& is是一个文件流,它可以正常工作。

那么为什么函数in stream(fis);在使用 tcp 流时会挂起呢?它是否与 zlib 处理缓冲区的方式有关,或者它是filtering_istream特定的东西?我也想听听一些解决方法来解决这个问题。

4

1 回答 1

1

您已经自己回答了问题;)

我还注意到,如果 std::istream& 是文件流,它可以正常工作。

filtering_istream正在轮询直到它获得 EOF,所以因为 TCP 流仅在客户端断开连接时结束 - 它不会结束流读取。在ifstream它上面简单地得到他的EOF并结束处理。

于 2012-11-12T14:58:12.060 回答