2016-05-27 32 views
0

我写了一个tcp服务器,每次接受客户端连接时,由AcceptEndAccept返回的套接字实例被称为处理程序和许多其他信息收集在名为TcpClientConnection的对象中,我需要确定是否连接是否连接或在某些特定间隔时间,Socket.Connected属性是不可靠的,根据文档我应该使用Poll方法与SelectRead选项来执行此操作。 与测试场景我拔掉客户端电缆,并等待破损的报警建立在handler.Poll(1, SelectMode.SelectRead)上,它应该返回true,但从未发生过。确定TCP服务器中的断开连接

+1

你能否提供一些代码? – Henningsson

回答

1

根据Socket.Poll的文档:

这种方法不能检测某些种连接问题,例如一个破碎网络电缆,或远程主机被非正常关闭。您必须尝试发送或接收数据以检测这些类型的错误。

换句话说 - 轮询对于检查是否有数据到达并可用于本地OS网络堆栈很有用。 如果你需要检测连接问题,你需要调用阻塞读取(例如Socket.Receive

你也可以建立一个简单的初始化miniprotocol来交换一些同意的'hello'来回消息。 下面是一个简单的例子,你可以怎么做:

private bool VerifyConnection(Socket socket) 
    { 
     byte[] b = new byte[1]; 
     try 
     { 
      if (socket.Receive(b, 0, 1, SocketFlags.None) == 0) 
       throw new SocketException(System.Convert.ToInt32(SocketError.ConnectionReset)); 
      socket.NoDelay = true; 
      socket.Send(new byte[1] { SocketHelper.HelloByte }); 
      socket.NoDelay = false; 
     } 
     catch (Exception e) 
     { 
      this._logger.LogException(LogLevel.Fatal, e, "Attempt to connect (from: [{0}]), but encountered error during reading initialization message", socket.RemoteEndPoint); 
      socket.TryCloseSocket(this._logger); 
      return false; 
     } 


     if (b[0] != SocketHelper.HelloByte) 
     { 
      this._logger.Log(LogLevel.Fatal, 
       "Attempt to connect (from: [{0}]), but incorrect initialization byte sent: [{1}], Ignoring the attempt", 
       socket.RemoteEndPoint, b[0]); 
      socket.TryCloseSocket(this._logger); 
      return false; 
     } 

     return true; 
    }