使用过滤输入流来增强tcp流会导致挂起

时间:2012-11-11 14:31:09

标签: c++ boost tcp stream boost-asio

请考虑以下事项:

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?我也想听一些解决方法来解决这个问题。

1 个答案:

答案 0 :(得分:1)

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

  

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

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