Reputation: 134
Consider the following:
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;
}
where message& p
is a serializable structure, and std::istream& is
is a tcp stream.
The server waits for the client to send data inside the in stream(fis);
constructor, and it continues when data has been received. The stream
object serializes the data from the tcp stream to the message
object.
Now, when actually filtering the received data by adding the following:
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;
}
it should read the data from the tcp stream, decompress it and serialize it to the message
object. But instead, it hangs on in stream(fis);
and returns after the data has been sent 10-20 times or the client disconnects.
I've already tried to set zlib decompressor's internal buffer to both 0 and 1, where 0 fails an assert and 1 somehow works only once(throws on second iteration). I've also set filtering_istream
buffers to 0, so that shouldn't cause the hang. I also noticed, that if the std::istream& is
is a file stream, it works correctly.
So why does the function hang on the in stream(fis);
when using tcp stream? Does it have something to do with the zlib's way it handles the buffer, or is it something filtering_istream
specific? I'd also like to hear some workaround to fix this problem.
Upvotes: 1
Views: 496
Reputation: 7357
You already answered question by yourself ;)
I also noticed, that if the std::istream& is is a file stream, it works correctly.
filtering_istream
is polling until it get EOF, so because TCP stream ends only on client disconnect - it does not end stream reading. On ifstream
it simple get his EOF and ends processing.
Upvotes: 1