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

标签 sockets tcpclient asyncsocket

我正在使用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)另一端关闭的连接。

为了检测断开的连接,您需要保持连接。您需要:

  • 确保另一端将按设定的时间表发送数据,如果超时,则超时并关闭连接,否则,
  • 偶尔将探测发送到另一端。在这种情况下,操作系统会注意连接断开的情况,如果套接字断开(立即(由对等方重置连接)或最终(连接超时)),您将在读取套接字时遇到错误。

  • 无论哪种方式,您都需要一个计时器。是否将计时器实现为事件循环中的事件还是休眠的线程取决于您,最佳解决方案可能取决于应用程序其余部分的结构。如果您有一个运行事件循环的主线程,那么最好将其挂接到该线程上。

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

    关于sockets - 自动重新连接套接字客户端的设计选择,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9943659/

    相关文章:

    java - 如何将多个客户端连接到单个服务器?

    c# - 如何将端口 IAX2 的 UDP header 转换为可读字符串

    sockets - 从 Unix 本地套接字接收错误的地址(抽象命名空间)

    c# - 如何检查 TcpClient 连接是否关闭?

    .NET NetworkStream.EndWrite() 字节写入

    c# - 是否存在 TcpClient.Close 或 Socket.Close(0) 可能阻止我的代码的情况?

    c# - 在 Windows Server 2008 R2 上使用异步套接字导致 100% CPU 使用率

    java - 每个连接线程模型

    iphone - GCDAsyncSocket - 未接收数据 - AsyncSocket 工作正常

    swift - 如何在swift中有效地表示htonl?