Sockets 自动重新连接套接字客户端的设计选择

Sockets 自动重新连接套接字客户端的设计选择,sockets,tcpclient,asyncsocket,Sockets,Tcpclient,Asyncsocket,我正在使用C#中的windows窗体应用程序。我使用的是一个套接字客户端,它以异步方式连接到服务器。如果连接因任何原因中断,我希望套接字立即尝试重新连接到服务器。解决问题的最佳设计是什么?我是否应该构建一个线程,持续检查连接是否丢失并尝试重新连接到服务器 下面是处理套接字通信的XcomClient类的代码: public void StartConnecting() { socketClient.BeginConnect(this.remoteEP, ne

我正在使用C#中的windows窗体应用程序。我使用的是一个套接字客户端,它以异步方式连接到服务器。如果连接因任何原因中断,我希望套接字立即尝试重新连接到服务器。解决问题的最佳设计是什么?我是否应该构建一个线程,持续检查连接是否丢失并尝试重新连接到服务器

下面是处理套接字通信的XcomClient类的代码:

        public void StartConnecting()
    {
        socketClient.BeginConnect(this.remoteEP, new AsyncCallback(ConnectCallback), this.socketClient);
    }

    private void ConnectCallback(IAsyncResult ar)
    {
        try
        {
            // Retrieve the socket from the state object.
            Socket client = (Socket)ar.AsyncState;

            // Complete the connection.
            client.EndConnect(ar);

            // Signal that the connection has been made.
            connectDone.Set();

            StartReceiving();

            NotifyClientStatusSubscribers(true);
        }
        catch(Exception e)
        {
            if (!this.socketClient.Connected)
                StartConnecting();
            else
            { 

            }
        }
    }

    public void StartReceiving()
    {
        StateObject state = new StateObject();
        state.workSocket = this.socketClient;
        socketClient.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(OnDataReceived), state);
    }

    private void OnDataReceived(IAsyncResult ar)
    {
        try
        {
            StateObject state = (StateObject)ar.AsyncState;
            Socket client = state.workSocket;

            // Read data from the remote device.
            int iReadBytes = client.EndReceive(ar);
            if (iReadBytes > 0)
            {
                byte[] bytesReceived = new byte[iReadBytes];
                Buffer.BlockCopy(state.buffer, 0, bytesReceived, 0, iReadBytes);
                this.responseList.Enqueue(bytesReceived);
                StartReceiving();
                receiveDone.Set();
            }
            else
            {
                NotifyClientStatusSubscribers(false);
            }
        }
        catch (SocketException e)
        {
            NotifyClientStatusSubscribers(false);
        }
    }

今天,我试图通过检查接收的字节数或捕获套接字异常来捕获断开连接。

如果您的应用程序只接收套接字上的数据,那么在大多数情况下,您永远不会检测到断开的连接。如果您长时间没有收到任何数据,您就不知道是因为连接中断,还是因为另一端根本没有发送任何数据。当然,您将以正常方式检测(作为套接字上的EOF)另一端关闭的连接,尽管如此

为了检测断开的连接,您需要一个keepalive。您需要:

  • 让另一端保证它将按照设定的时间表发送数据,如果您没有收到数据,您将超时并关闭连接,或者
  • 每隔一段时间向另一端发送一个探测器。在这种情况下,操作系统将注意到断开的连接,如果套接字断开,您将在读取套接字时出错,无论是立即(由对等方重置连接)还是最终(连接超时)
不管怎样,你都需要一个计时器。将计时器实现为事件循环中的事件还是休眠线程取决于您,最佳解决方案可能取决于应用程序其余部分的结构。如果您有一个运行事件循环的主线程,那么最好是连接到它


您还可以在套接字上启用TCP keepalives选项,但应用程序层keepalive通常被认为更健壮。

这取决于您使用的类。你最好把你的代码贴在这里或者给我们更多的信息。