我正在使用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/