当前位置:编程学习 > C#/ASP.NET >>

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#
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,