0

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!

Majak
  • 1,543
  • 1
  • 14
  • 28
  • 1
    Typically, a client sending data to a dead server process will result in a FIN or RST being sent back, thereby closing the connection. But if the server was suddenly terminated or if the network lost connectivity, and the client doesn't attempt to send anything, it could easily get hung waiting for data. You should make your client resilient to these kinds of issues. (timeouts, periodic keepalives, etc...) I suggest you post your code so we can see how the client behaves. – selbie Jul 15 '14 at 14:55
  • The problem is, that I don't know how to check whatever it's alive, because all seems like it's connected but server is down. – Majak Jul 15 '14 at 15:12

2 Answers2

0

Solved

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

if (iRx == 0)
   throw new SocketException(Convert.ToInt16(SocketError.HostDown));
Majak
  • 1,543
  • 1
  • 14
  • 28
0

TCP receiver can never get the exact status of the remote connection. Killing the process will send FIN (receive is zero) or RST(get exception) depending on the TCP/IP stack implementation. There are other condition where the application are completely unaware of the connection breakage. Suppose if the remote system is forcefully reset or the cable wire is unplugged or the IP address is changed, there is no way you can get to know the connection broken until you send some data. If your application need to know the status of the connection, it can send some dummy data every 1 minute to make sure the connection alive.

dvasanth
  • 1,337
  • 1
  • 9
  • 10
  • Yes I tried to send data in this case, and is was also processed without exception. I solved it by detecting if incoming data wasn't zero, anyway I throw exception. But I guess it's just kinda solution... – Majak Jul 17 '14 at 19:15