Socket和TcpClient怎样才能知道跟对方断开了没有?
也就是说,采用Socket或TcpClient建立了连接,怎么来检测对方是否关闭了连接?没有人知道吗?TcpClient 的派生类可使用此属性(active)来确定连接尝试是否已成功。此属性不监视 TcpClient 连接的当前状态。如果远程主机关闭连接,将不更新 Active。
使用 Connected 属性来获取 Socket 的连接状态。此属性将返回 Socket 的最新已知状态。当它返回 false 时,表明 Socket 要么从未连接,要么已断开连接。即使 Connected 返回 true,也无法保证 Socket 仍处于 Connected 状态。true 值仅意味着在上次 I/O 操作时 Socket 处于连接状态。这两个属性都不行,还有什么办法啊?
希望当我的客户端关闭后,我的服务器端能马上知道。并且不能指望客户端在关闭前给发关闭指令.下面是个实验例子:
在TcpClient或socket已经建立连接后,甚至在Receive或Send数据时,远程的客户端如果己经关闭了连接,程序都不报错,如何才能知道客户端己经关闭了连接啊?Private Sub btnStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStart.Click
     tcpListener = New TcpListener(IPAddress.Any, txtListenPort.Text)
     tcpListener.Start()     thrListen = New Threading.Thread(AddressOf ListenService)
     thrServer = New Threading.Thread(AddressOf ReceiveService)
     thrListen.Start()
     thrServer.Start()     txtOutput.Text = "Server start ..."
End Sub
Private Sub ReceiveService()
     Dim netStream As NetworkStream
     Dim intRead As Integer     While True
         If Not socket Is Nothing Then
             Do
                 Try
                     Dim bytData(1024) As Byte
                     '这里无论socket是否Blocking,当客户端连接关闭时都不知道,也无异常
                     intRead = socket.Receive(bytData, bytData.Length, SocketFlags.None)
                        txtOutput.Text = txtOutput.Text & ControlChars.CrLf & codEncoding.GetString(bytData)
                 Catch es As SocketException
                     Exit Do
                 End Try
             Loop While intRead > 0
         End If
         System.Threading.Thread.Sleep(200)
     End While
End Sub

解决方案 »

  1.   

    /// <summary>
    /// 是否已经连接
    /// </summary>
    public virtual bool Connected
    {
     get
     {
      try
      {
       //检查socket的状态是否可读
       if(m_socket.Connected && m_socket.Poll(0, SelectMode.SelectRead))
       {
        byte[] aByte = new byte[1];
        //因为TCP/IP协议无法精确的判断网络是否可用
        //试读一个字符,Peek参数指定读取的字符不会从缓冲区中移除
        //假如可读则表示连接可用
        if(m_socket.Receive(aByte, 0, 1, SocketFlags.Peek) != 0)
         return true;
        Close("Disconnected.");
        return false;
       }
      }
      catch(SocketException e)
      {
       OnException(e);
      }
      return m_socket.Connected;
     }
    }
      

  2.   

    while(bools)
                {
                    try
                    {                    if(newSocket[i2].Poll(-1,SelectMode.SelectRead))
                        {
                            if(newSocket[i2].Available>0)
                            {
                                byteMessage=new byte[100];
                                newSocket[i2].Receive(byteMessage,SocketFlags.None);  
                                string msg=System.Text.Encoding.Unicode.GetString(byteMessage);
                                send(msg);
                            }
                            else
                            {
                                newSocket[i2].Shutdown(SocketShutdown.Both);
                                newSocket[i2].Close();
                                th1[i2].Abort();
                                return;
                            }
                        }
                    }
                    catch
                    {
                        Thread.Sleep(10);
                        continue;
                    }            }
      

  3.   

    如果客户端正常断开
    socket.Receive有两种情况:
    1、返回0
    2、触发异常还有一个情况,如果客户端不是正常断开,如停电
    那么,socket.Receive不会有什么反应,对于这种情况,只能做“心跳检测”:
    就是客户端定期发送一个自定义的特定包给服务端,如果服务器指定时间内没有收到
    客户端包,就认为客户端已经断开!
      

  4.   

    客户端如果断开连接以后,会send一条消息给服务器段,内容为null。
      

  5.   

    wmhnq() 能解释一下你那段程序是什么意思么?谢谢
      

  6.   

    我只知道当连接已断开,Read方法会引发System.IO.IOException异常...