自动重新连接套接字客户端的设计选择
问题描述:
我正在使用C#中的窗体应用程序。我正在使用以异步方式连接到服务器的套接字客户端。我希望套接字在出于任何原因断开连接时尝试立即重新连接到服务器。哪种解决问题的最佳设计?我应该建立一个不断检查连接是否丢失并尝试重新连接到服务器的线程?自动重新连接套接字客户端的设计选择
这里是我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 keepalives选项,但通常认为应用程序层keepalive更健壮。
这取决于你使用的是什么类。你最好在这里发布你的代码或给我们更多的信息。 – 2012-03-30 13:12:15