考虑以下:

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);构造函数中发送数据,并在接收到数据后继续。 stream对象将数据从tcp流序列化到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是文件流,则它可以正常工作。

那么,为什么在使用tcp流时函数会卡在in stream(fis);上?它与zlib处理缓冲区的方式有关,还是filtering_istream特定?我也想听听一些解决此问题的方法。

最佳答案

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


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

10-08 12:49