Best practice reading from `Socket` / `NetworkStream`?
I've got a C# application in which I want to read data from a Unix domain socket (on the sending side I have a Java application which sends buffered data). I want to read all data into a
MemoryStream
, as I subsequently want to parse that using CborReader
(unfortunately I didn't find any way getting the CborReader
itself to read the data directly from the socket).
Now, to my question: I can't figure out what the best practice should be for fully reading the data from the Unix domain socket into a MemoryStream
. My tests indicate that I can't rely solely on NetworkStream.DataAvailable
but also need to call Socket.Poll()
, so I've come up with the following code:
Does this make sense or is there a better / more idiomatic way?4 Replies
you are trying to read until the socket is closed? in general, when
stream.Read
returns 0, it means that there is no more data
so, the way to do this loop is while (stream.Read(...) is var bytesRead and not 0)
. you don't need Poll or DataAvailable. (by the way, you can access the Socket from stream.Socket
, you don't need to pass it around)
however. what you really want here is I've tried this, but I think this requires the sending application to somehow close the socket, because whenever I try this, the operation is blocking with the following stack trace:
I was able to get the sending application to shutdown the connection for writing without closing the socket (as I still want to send a response on the C# side). That way your approach with
CopyTo()
then works as expected. Thanks!ahh, i see... you were using the timeout on Poll so that you didn't have to close the socket
that's a bit of a cheap hack, i do prefer what you have now
though, if you need any more flexibility than that, i would use a basic length-prefixed protocol
just, like, read one int, and then read that many bytes from the socket
Indeed. I just couldn't figure out before why the
CopyTo()
call was always blocking.
Ideally, I would prefer if the CborReader
could read directly from the stream.