What is the reasoning behind passing a list of ArraySegment<byte>
to Socket.BeginReceive
/SocketAsyncEventArgs
?
MSDN for the Socket.BeginReceive
constructor doesn't even correctly describe the first argument):
public IAsyncResult BeginReceive(
IList<ArraySegment<byte>> buffers,
SocketFlags socketFlags,
AsyncCallback callback,
object state
)
Paremeters:
buffers
Type:System.Collections.Generic.IList<ArraySegment<Byte>>
An array of typeByte
that is the storage location for the received data.
...
I thought that the main idea was to allocate a large buffer on the Large Object Heap, and then pass a segment of this buffer to Socket.BeginReceive
, to avoid pinning small objects around the heap and messing up GC's work.
But why should I want to pass several segments to these methods? In case of SocketAsyncEventArgs
, it seems it will complicate pooling of these objects, and I don't see the reasoning behind this.
What I found out in this question and in MSDN:
There is an overloaded version of BeginReceive
that takes a Byte-Array. When this is full or a packet has been received (that is logically in order), the callback is fired.
As stated in the answer I linked:
Reads can be multiples of that because if packets arrive out of order all of them are made visible to application the moment the logically first one arrives. You get to read from all contiguous queued packets at once in this case.
That means: If there is an incoming packet which is out of order (i.e. with a higher sequence number than the one expected), it will be kept back. As soon as the missing packet has arrived, all available packets are written to your list and only one callback is fired instead of firing the callback over and over again for all packets already available, each filling your buffer as far as possible, and so on.
So that means, this implementation saves a lot of overhead by providing all available packets in an array list calling the callback only once instead of doing a lot of memcopies from the network stack to your buffer and repeatedly calling you callback.