Say I want to arrange bytes in the internal buffer in a certain way. I
receive those bytes in the socket.
One solution is to read in socket in pieces:
byte[] buffer = new byte[65536];
int index = 0;
m_socket.Receive(buffer , 8, SocketFlags.None);
index += 8;
//read the rest of the message
//int msgLength is remaining number of bytes inthe buffer
m_socket.Receive(buffer , index, msgLen - index,
SocketFlags.None);
1. How to calculate msgLength ?
If by "remaining number of bytes in the buffer", you mean ready to be read
from the socket, the answer is "you don't". For the same reason that
using a method like Poll() or Select() cannot provide any guarantees about
what will happen when you actually try to read from the socket, there's no
reliable way to calculate the bytes yet unread in the socket buffer in a
way that will allow you to depend on the calculation in a later call to
Receive().
The best you can do is provide a buffer to Receive() that is just large
enough for the remaining bytes you expect to get for a given message (I'm
assuming that the data in the first eight bytes in some way allow you to
calculate that). Then just keep reading in a loop until you've read that
many bytes, decreasing the length you offer to Receive() with each
iteration to take into account the number of bytes read already.
That said, this is only something you should be doing if you don't need
efficient i/o. There's a lot of overhead going back and forth between
your code and the network buffers, and if there's a lot of data coming
through, you can wind up forcing the network driver to have to throw out
incoming data, and making the other end send it again.
A much better approach is for the network i/o code to always just read as
much data as it can, and let another layer of your code deal with parsing
that out into usable messages. Doing so won't actually necessarily
address the above question directly (after all, the network i/o layer is
probably still going to be delivering data as a stream), but it does shift
it into a domain where you have a bit more control.
2. How to make this operation when reading data in asynchronously,
using BeginReceive()
The same way you'd deal with any transition in design from synchronous to
asynchronous. State that is kept in local variables simply has to be
moved into instance variables that can be accessed as each network
operation completes.
Pete