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.
- you will NOT get the size you expect. You will get anything in range of 0 to whatever is left in the transit
- it won't block until your size is ready. It will get you as much as it has (0 is possibility) - I think that that behavior can be changed, but it doesn't again have anything with number of bytes
Write()
n on other end
- you need to build your buffer
- and yes, you really need to build your buffer manually, by prefixing your data with its length
Here, you have some ideas on how to read the buffer: .NET blocking socket read until X bytes are available?