tonynhan / protobuf-net

Automatically exported from code.google.com/p/protobuf-net
Other
0 stars 0 forks source link

Reading NetworkStream blocks forever #21

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
Please include an e-mail address if this might need a dialogue!
==============

What steps will reproduce the problem?
1. Create a TcpListener, server, and start listening for connections.
2. Create a TcpClient, clientside, and connect to the server.
3. Create another TcpClient, serverside, with server.AcceptTcpClient().
4. Get the clientside stream and serverside stream.
5. Serialize an object with the clientside stream
6. Deserialize the object on the serverside stream.

What is the expected output? What do you see instead?
I expect the object that I serialized to deserialize, instead, the
Serialize.Deserialize<T>(Stream source) method hangs.

What version of the product are you using? On what operating system?
I've reproduced this on the .Net 2.0 revision 164 download and using
revision 171.  Windows XP.

Please provide any additional information below.
I have a workaround for this.  I've attached a patch for review.

Original issue reported on code.google.com by danieldi...@gmail.com on 2 Oct 2008 at 10:09

Attachments:

GoogleCodeExporter commented 9 years ago
Thanks for the info and patch; before I commit the patch, I just want to 
quickly look  
into how DataAvailable behaves with respect to buffering - i.e. is it likely to 
incorrectly thing it has the end of the batch, when actually some is still 
buffered 
at the client.
For info - one option for network usage is the "...WithLengthPrefix" methods 
(in the 
HEAD, but maybe not in the downloadable dll) - this sends the length of each 
batch 
first, which makes network usage very simple: it knows it is expecting <x> 
bytes, so 
it stops cleanly after <x> bytes (see the QuickStart project for an example).

Thanks again - I may well end up applying that patch (once I have checked how 
it 
behaves: I'll be honest - raw sockets isn't my usual thing...).

Marc

Original comment by marc.gravell on 3 Oct 2008 at 6:02

GoogleCodeExporter commented 9 years ago
I've done some checking, and general consensus is that DataAvailable cannot be 
used 
(robustly) to prove that the batch is complete; it simply indicates that the 
receive 
buffer is empty, which isn't the same thing: if this happens to fall at the 
point  
between fields, then data corruption will occur.

The recommendation given was to use a length-prefix if working with batches, 
which is 
what the QuickStart already does. Of course, if you are just sending one batch 
you 
can serialize and Close() the stream, which will work just as well - but if you 
want 
a dialogue over the socket it should use a length prefix.

If I've got it wrong, please say...

Original comment by marc.gravell on 3 Oct 2008 at 7:46

GoogleCodeExporter commented 9 years ago
Thanks for looking into it.  I didn't try the WithLengthPrefix methods, as it 
wasn't
in revision 164, and i just updated to 171 to see if the bug I was experiencing 
was
fixed in the newer version...  Tested again with these methods and it works.

Original comment by danieldi...@gmail.com on 3 Oct 2008 at 9:44

GoogleCodeExporter commented 9 years ago
You are right, of course - it [a conversation over a NetworkStream] simply 
didn't 
work in r164, which I found when putting together the quick start example; 
these 
methods were added exactly to fill this gap.

Any other problems, let me know.

Marc

Original comment by marc.gravell on 4 Oct 2008 at 8:24

GoogleCodeExporter commented 9 years ago

Original comment by marc.gravell on 8 Nov 2008 at 9:27