立即检测客户端与服务器套接字的连接

如何检测客户端与我的服务器断开连接?

我在我的AcceptCallBack方法中有以下代码

static Socket handler = null;
public static void AcceptCallback(IAsyncResult ar)
{
  //Accept incoming connection
  Socket listener = (Socket)ar.AsyncState;
  handler = listener.EndAccept(ar);
}

我需要找到一种方法来尽快发现客户端与handler Socket断开连接。

我试过了:

  • handler.Available;
  • handler.Send(new byte[1], 0, SocketFlags.None);
  • handler.Receive(new byte[1], 0, SocketFlags.None);
  • 当您连接到服务器并希望检测服务器何时断开连接但当您是服务器并希望检测到客户端断开连接时它们不起作用时,上述方法可用。

    任何帮助将不胜感激。


    由于在插座断开连接时没有可用于发信号的事件,因此您必须以您可接受的频率轮询它。

    使用这种扩展方法,你可以有一个可靠的方法来检测套接字是否断开连接。

    static class SocketExtensions
    {
      public static bool IsConnected(this Socket socket)
      {
        try
        {
          return !(socket.Poll(1, SelectMode.SelectRead) && socket.Available == 0);
        }
        catch (SocketException) { return false; }
      }
    }
    

    这根本不可能。 您和服务器之间没有物理连接(除非在极少数情况下您使用回送电缆连接两台计算机)。

    当连接正常关闭时,通知另一方。 但是,如果连接断开连接(例如,用户连接断开),那么服务器在超时(或尝试写入连接并且确认超时)时才会知道。 这就是TCP的工作方式,你必须忍受它。

    因此,“即刻”是不现实的。 你可以做的最好的是在超时期限内,这取决于代码运行的平台。

    编辑:如果你只是寻找优雅的连接,那么为什么不直接发送一个“DISCONNECT”命令从客户端的服务器?


    有人提到了TCP Socket的keepAlive功能。 在这里很好地描述:

    http://tldp.org/HOWTO/TCP-Keepalive-HOWTO/overview.html

    我以这种方式使用它:在套接字连接之后,我调用这个函数,它设置keepAlive。 keepAliveTime参数指定超时(以毫秒为单位),直到发送第一个保持活动数据包时才会有活动。 keepAliveInterval参数指定在未收到确认时发送连续保持活动数据包的时间间隔(以毫秒为单位)。

        void SetKeepAlive(bool on, uint keepAliveTime , uint keepAliveInterval )
        {
            int size = Marshal.SizeOf(new uint());
    
            var inOptionValues = new byte[size * 3];
    
            BitConverter.GetBytes((uint)(on ? 1 : 0)).CopyTo(inOptionValues, 0);
            BitConverter.GetBytes((uint)time).CopyTo(inOptionValues, size);
            BitConverter.GetBytes((uint)interval).CopyTo(inOptionValues, size * 2);
    
            socket.IOControl(IOControlCode.KeepAliveValues, inOptionValues, null);
        }
    

    我也在使用同步阅读:

    socket.BeginReceive(packet.dataBuffer, 0, 128,
                        SocketFlags.None, new AsyncCallback(OnDataReceived), packet);
    

    并且在回调中,这里被捕获的超时SocketException ,当套接字在保持活动数据包后没有收到ACK信号时引发。

    public void OnDataReceived(IAsyncResult asyn)
    {
        try
        {
            SocketPacket theSockId = (SocketPacket)asyn.AsyncState;
    
            int iRx = socket.EndReceive(asyn);
        catch (SocketException ex)
        {
            SocketExceptionCaught(ex);
        }
    }
    

    这样,我可以安全地检测TCP客户端和服务器之间的断开连接。

    链接地址: http://www.djcxy.com/p/56563.html

    上一篇: Instantly detect client disconnection from server socket

    下一篇: Django form is not valid with django