Reputation:
I am a little confused as to how i should use tcp streams in .net. Right now when i want to write lets say 40bytes i write it to a memorystream then call ToArray() and write the memorystream to networkstream + flush.
On serverside i use Read(buf, 0, len) and check if the length is exactly as i expect. Am i doing this in a silly way? Can i write as little bytes as i want and just flush when i i am ready to read?
When i Read() will i ALWAYS get the length i expect? (assuming the app is correct and no error has occured) Will it block until my size is ready? I dont need to loop over read and build my buffer do i? lets say i am expecting a large size like 10k or higher would i then need to build my buffer?.
Upvotes: 3
Views: 457
Reputation: 19956
I know that both previous answers are telling you that, but I'll repeat them and add something mine: if there is enough time between subsequent sends, it will work just as you expect, that might lead you to believe that it really DOES work that way. But it doesn't.
TCP is easily visualized as a WATER PIPE that you are filling with glasses of water on one end. Adding new glass of water doesn't tell you anything about it's size, just adds more water to the pipe.
So, you'll need to implement your own 'messaging' or 'packeting' in the stream.
However, it's not that bad. Stream is ROBUST so if you prefix your data with its length, you'll be able to get it working - just create some kind of 'packet gathering mechanism' on the receiving end - have some buffer that will hold partial packet data until you get everything you need.
EDIT:
To go through your questions:
Flush()
is irrelevant here.Write()
n on other endHere, you have some ideas on how to read the buffer: .NET blocking socket read until X bytes are available?
Upvotes: 2
Reputation: 171188
You will get a read size of 0 if the stream is depleted, or of at least 1 up to the size of your buffer. It can be any size at all in that range. Common sizes are multiples of the network MTU (about 1452 bytes).
You need to implement logic yourself to gradually fill a buffer up to the desired size.
There is no connection between the chunk size that was sent and the one received.
The file system is basically the only common Stream implementation which always fills up the requested buffer completely, except at the end of the file. Other Stream implementations don't make that guarantee.
All of this is a design choice made for the sake of performance.
Upvotes: 0
Reputation: 3697
Windows sockets have no internal synchronization mechanism. So you'll never be sure that the portion of bytes you got is final and no other data is expected. You'll always need to track all retrieved data and decide when retrieval can be stopped.
Upvotes: 0