C/S Socket关于客户端捕获服务端断开的问题
客户端用的是 TcpClient 对象服务端是 Socket 对象
在C#.Net WinForm 下
现在的情况是,客户端有一个 [断开连接] 的按钮,服务端有一个 [关闭服务器] 的按钮
当我正常连接两端后,分别点两端的窗体关闭按钮,另外一方都能捕捉到一方断开的连接的异常;
当我点客户端的 [断开连接] 按钮,执行 TcpClient.Close()的方法是,在服务端的 EndReceive(IAsyncResult iar) 方法里面能接受到一个 length == 0 的包,从而捕捉到客户端断开的异常
问题是:本人点击[关闭服务器] 的按钮,执行服务端的 Socket.Close()方法时,客户端的 TcpClient.Client.EndReceive(IAsyncResult iar)却没能收到 length == 0 的包
附上自己的一段关闭按钮的代码,我觉得是自己的逻辑没处理,希望大家帮忙看看,谢谢了!
//服务端关闭按钮执行的代码:
private void btnStop_Click(object sender, RoutedEventArgs e)
{
if (socketServer != null)
{
socketServer.Dispose();
cbReceiver.Items.Clear();
}
}
public void Dispose()
{
if (!m_disposed)
{
m_disposed = true;
this.Close(); //主要应该是这个Close里面的逻辑,希望大家看看
this.Dispose(true);
GC.SuppressFinalize(this);
}
}
private void Close()
{
if (m_serverClosed)
{
return;
}
m_serverClosed = true;
m_serverListenPaused = true;
m_checkAcceptListenResetEvent.WaitOne(); // 等待3个线程
m_checkSessionTableResetEvent.WaitOne();
m_checkDatagramQueueResetEvent.WaitOne();
if (m_databaseObj != null)
{
m_databaseObj.Close();
}
if (m_sessionTable != null)
{
lock (m_sessionTable)
{
foreach (TSession session in m_sessionTable.Values)
{
session.Close(); //每个已经连接客户端为一个Session
}
}
}
//m_serverSocket 为Socket对象
m_serverSocket.Close(); //这里关闭服务端的Socket
if (m_sessionTable != null) // 清空会话列表
{
lock (m_sessionTable)
{
m_sessionTable.Clear();
}
}
this.OnServerClosed();
}
另外我想问一下,已建立通信连接的双方是怎么通知对方自己断开连接的呢?具体的原理是什么?
--------------------编程问答-------------------- TCP断了就断了 连接在时双方知道 断了 自然也知道 不用特意通知吧
你只要需要监听连接断开后 做你要做的工作就行了 --------------------编程问答-------------------- TCP双方可以通过结束握手来结束一个连接。
结束握手使得对方有机会把还没有接收的接收完毕,使得对方有机会进行退场清理。
典型的结束握手为(Finish, Acknowledge)
FIN packet ->
<- FIN & ACK
ACK ->
有兴趣可以阅读TCP协议介绍。
补充:.NET技术 , C#