Socket.EndReceive of IAsyncResult is collecting more TCP messages than one

103 Views Asked by At

I have a situation here. I'm using System.Net.Sockets.Socket to read and send TCP messages. Using the recursion for receiving the data and reading again new data.

void rcvTCP(IAsyncResult ar)
    {
        var socket = (Socket)ar.AsyncState;
        try
        {
            var bytesRead = socket.EndReceive(ar);

            if (bytesRead > 0)
            {
                var data = new byte[bytesRead];
                Array.Copy(this.mBuffer, data, data.Length);
                dataReceived(this, mMaster.SlaveAddress, data);
            }
            socket.BeginReceive(mBuffer, 0, mBuffer.Length, SocketFlags.None, new AsyncCallback(rcvTCP), socket);
        }
        catch (Exception ex)
        {
            Debug.WriteLine(ex.Message);
        }
    }

I'm sending messages from a device to my app, each 10ms, 8 bytes each message. I'm receiving the messages ok, so the "bytesRead" is 8, until a certain point when the app freezes randomly, and "bytesRead" is 768. When I look inside the data that came, I see that I have 96 messages in one.

I've read in the internet, like the messages are coming Sync instead of Async, so checking the "CompletedSinchronously" gives true at previous messages and this message also...

if (ar.CompletedSynchronously)
{
    Debugger.Break();
}

I tried with TcpClient + NetworkStream instead of Socket(I know that TcpClient is pretty the same as Socket), and I have the same result. Please help me. I want all the messages separated instead of collected, but I can't find any solution to this... Any idea how to do this?

PS: I am already putting the flag - NoDelay to true.

FIX: For me the fix was splitting the collected messages after the receive, and running the splitting in a separate thread, so the UI does not freeze. Keep in mind, if you have a property used in different Threads, don't forget to use "lock".

0

There are 0 best solutions below