Is there a setting I can use to prevent merging multiple TCP packets into a single buffer inside Socket.BeginReceive
callback?
Your knee-jerk reaction will be that there is nothing I can do to prevent TCP from splitting/merging the data, but this is not what I asking; I can clearly see individual packets being received in Wireshark, and my only concern is latency, i.e. to process the segment as soon as it arrives. This doesn't mean I don't know how to process split/merged segment, but it means I want to avoid the delay.
My code looks like this:
void WaitForData(ISocketInfo soc)
{
if (socket != null && socket.Connected)
socket.BeginReceive(buffer, 0, buffer.Length,
SocketFlags.None, OnPacketReceived, socket);
}
void OnPacketReceived(IAsyncResult asyn)
{
try
{
var socket = (ISocketInfo)asyn.AsyncState;
numberOfBytesReceived = socket.EndReceive(asyn);
if (numberOfBytesReceived > 0)
{
_queue.Enqueue(buffer, 0, numberOfBytesReceived);
OnNewDataReceived();
}
WaitForData(socketInfo);
}
catch (SocketException ex)
{
Log.Warn("Socket error while receiving packet", ex);
Close();
}
}
When I examine these packets in WireShark, I can see individual TCP packets being received every 50ms, each of them (say) 100 bytes. But sometimes in my app there is a delay of 100ms, and the OnPacketReceived
methods gets 200 bytes.
Since WireShark confirms that this is not a OS/networking issue, what could be the problem here? The OnPacketReceived
just fires on a background thread so it doesn't block the method, and the program doesn't really consume much CPU.
(Update)
It seems like I didn't convey my question clearly enough. My problem is not how to parse the data if it gets split across segments. My protocol is well defined (i.e. START_COOKIE, LENGTH, DATA, CRC), and I enqueue the data into a byte FIFO as soon as I receive it (the _queue.Enqueue
call inside the snippet above), so I can easily parse it asynchronously.
The question is, if I am seeing packet no. 1 (100 bytes) at +50ms in Wireshark, and packet no. 2 (100 bytes) at +100ms in Wireshark, and my application is not blocking the OnPacketReceived
method and consuming no CPU, how come does .NET, every once in a while, invoke OnPacketReceived
at +100ms and merge two packets into one?