0

我已经实现了 C# tcp-ip 客户端(同步和异步读取套接字)。在每个 SocketException 之后,我都会自动重新连接与服务器的连接。

然后我在windows中测试了客户端与ncat的通信。在这里,如果我杀死 ncat,它会在 C# 客户端中抛出 SocketException,一切都按我想象的那样工作。

但是后来我在 linux 中使用 ncat 对其进行了测试 - 这里通信正常,但是如果我杀死 ncat 服务器(与 Windows 相同的设置 - ncat -l -k -p xxxx),大量的空数据(零 B)是在回调中收到(或在同步版本中等待套接字)并且没有抛出异常。

一件事是 Windows / Unix 版本的 ncat 可以有不同的行为。但我仍然需要为任何版本的 tcp-ip 服务器解决这种奇怪的行为。

    /* ------------------------------------------------------------------------- */
    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 }
    }

谢谢!

4

2 回答 2

0

解决了

在 OnDataReceived 回调中,我检查传入数据的数量,所以我这样做:

if (iRx == 0)
   throw new SocketException(Convert.ToInt16(SocketError.HostDown));
于 2014-07-16T08:22:52.083 回答
0

TCP 接收器永远无法获得远程连接的确切状态。根据 TCP/IP 堆栈实现,终止进程将发送 FIN(接收为零)或 RST(获取异常)。还有其他情况,应用程序完全不知道连接中断。假设如果远程系统被强制重置或者电缆线被拔掉或者IP地址被改变,在你发送一些数据之前你是无法知道连接断开的。如果您的应用程序需要知道连接的状态,它可以每 1 分钟发送一些虚拟数据以确保连接处于活动状态。

于 2014-07-17T15:32:48.507 回答