c#中如何探测网络连接是否断开?

最近遇到一个问题,linux 的client端改变IP地址后再次连接Windows server端, server不会得到任何连接关闭的通知,用命令:

netstat -anop tcp | find "4114" ,发现连接依然是established状态:

C:\Documents and Settings\riverli>netstat -anop tcp | find "4114"
  TCP    0.0.0.0:4114           0.0.0.0:0              LISTENING       9056
  TCP    172.26.0.99:4114       172.26.0.244:35578     ESTABLISHED     9056

这样如果client端不断地变换IP,那么server端将会有大量的假连接,这是我们不希望看到的。我们希望server也能及时关闭连接释放这些资源。那么如何做呢?

经过google和多方位的实际测试,以下方式是可行的,希望对大家有帮助:

首先需要指定tcp连接的心跳机制,

  tcpServer = new TcpServer(4114);
            tcpServer.Connected += new TcpServer.TcpServerEventDlgt(OnConnected);
            tcpServer.StartListening();

   void OnConnected(object sender, TcpServerEventArgs e)
        {
            // Handle the connection here by starting your own worker thread
            // that handles communicating with the client.
            
           try
            {
              e.ConnectionState.Connection.IOControl(IOControlCode.KeepAliveValues,
                              Constants.Constant.KEEPALIVE_VALUES_FB, null);
            }
            catch (System.Exception ex)
            {
              log("Exception occurred in setting TCP KeepAlive exp={0}", ex.Message);
            }

            Thread t = new Thread(new ThreadStart(WorkerThread));
            t.Start();
        }

其次在线程函数WorkerThread中不断检测socket的状态

    internal void WorkerThread()
            {
                try
                {
                    netstream = new NetworkStream(e.ConnectionState.Connection);
                    {
                     
                        int nCount = 0;
                        while (isRunning && isKeepRunningFromRunCommand)
                        {
                          nCount++;
                          if (nCount == 100)
                          {
                            nCount = 0;
                            if (!e.ConnectionState.isConnected())
                              break;
                          }
                          while (netstream.DataAvailable)
                          {
                              processIncomingData();
                          }
                          Thread.Sleep(100);
                        }
                        log(remoteHost + ": Closing connection");
                    }
                }
                catch (Exception exp)
                {
                    //an error happened, log it and close the thread
                    log("The remote host has disconnected. Exception={0}", getExceptionMessage(exp));
		}
		e.ConnectionState.Close();


注意看上面的代码,每10 秒钟调用e.ConnectionState.isConnected()去探测一下socket的连接状态,此函数的代码参考msdn,如下:

 // This is how you can determine whether a socket is still connected.
        public bool isConnected()
        {
          bool blockingState = connection.Blocking;
          try
          {
            byte[] tmp = new byte[1];

            connection.Blocking = false;
            connection.Send(tmp, 0, 0);
            return connection.Connected;
          }
          catch (SocketException e)
          {
            // 10035 == WSAEWOULDBLOCK
            if (e.NativeErrorCode.Equals(10035))
            {
             //Still Connected, but the Send would block
              return true;
            }
            else
            {
              //Disconnected: error code {0}!", e.NativeErrorCode);
              return false;
            }
          }
          finally
          {
            connection.Blocking = blockingState;
          }
        }

connection是Socket类型。
这样如果client端改变IP,几秒钟后调用send函数就会抛出连接关闭的异常。


  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值