Search code examples
c#socketstcpblockingblocked

C# socket blocking with zero data


I have implemented C# tcp-ip client (both synchronous & async reading socket). After each SocketException, I'm automatically reconnecting connection with server.

Then I have tested communication of client with ncat in windows. Here, if I kill ncat, it throws SocketException in C# client and everything works as I imagine.

But then I have tested it with ncat in linux - here communication works OK, but if I kill ncat server (the same settings like at Windows - ncat -l -k -p xxxx), huge amount of empty data (zero B) is received in callback (or waiting on socket in sync version) and no exception is thrown.

One thing is that Windows / Unix version of ncat can have different behavior. But still I need to solve this weird behavior for any version of tcp-ip server.

    /* ------------------------------------------------------------------------- */
    public void WaitForData()
    {
        try
        {
            if (callback == null)
                callback = new AsyncCallback(OnDataReceived);

            SocketPacket packet = new SocketPacket();
            packet.thisSocket = socket;

            m_result = socket.BeginReceive
                (packet.dataBuffer, 0, 256,
                SocketFlags.None, callback, packet);
        }
        catch (SocketException ex) { ///reconnecting }
    }

    /* ------------------------------------------------------------------------- */
    public class SocketPacket
    {
        public System.Net.Sockets.Socket thisSocket;
        public byte[] dataBuffer = new byte[256];
    }

    /* ------------------------------------------------------------------------- */
    public void OnDataReceived(IAsyncResult asyn)
    {
        try
        {
            SocketPacket theSockId = (SocketPacket)asyn.AsyncState;
            int iRx = theSockId.thisSocket.EndReceive(asyn);
            char[] chars = new char[iRx];
            System.Text.Decoder d = System.Text.Encoding.UTF8.GetDecoder();
            int charLen = d.GetChars(theSockId.dataBuffer, 0, iRx, chars, 0);
            string szData = new string(chars);
            szData = szData.Replace("\n", String.Empty);

            processMessage(szData);

            WaitForData();
        }

        catch (ObjectDisposedException) { }
        catch (SocketException ex) { ///reconnecting }
    }

Thank you!


Solution

  • Solved

    In OnDataReceived callback, I check amount of incoming data, so I do:

    if (iRx == 0)
       throw new SocketException(Convert.ToInt16(SocketError.HostDown));