侦测socket clinet是否已经断线(TCP协定)

转自http://www.dotblogs.com.tw/lbwshift2/archive/2012/10/07/76320.aspx

 

TCP/IP協定下,當clinet 要中斷跟server的連線時,會有四個handshake步驟,跑完這四個步驟後socket  會通知你的server程式這個client已斷線

image

 

但…如果client沒做handshake卻斷線了 (ex:拔網路線),這時你的程式就不會即刻收到client斷線的通知  (要等非常之久才會收到, 預設是2小時)

所以,有人會自製類似 "ping" 的命令, 由你的server程式定時輪詢每個client是否還在連線。

其實到不用那麼麻煩, windows socket 有偵測的的參數可以做設定,就是利用 Socket.IOControl 來設定Socket的低階作業模式,現在,我們使用IOControlCode.KeepAliveValues參數值來設定:

1var listenSocket = new Socket(listenerEndPoint.AddressFamily
2                , SocketType.Stream
3                , ProtocolType.Tcp);
4 
5listenSocket.Bind(listenerEndPoint);
6listenSocket.Listen(100);
7listenSocket.IOControl(IOControlCode.KeepAliveValues, GetKeepAliveSetting(1, 5000, 5000), null);

GetKeepAliveSetting Method:

01/// <summary>
02/// 建立 keepalive 作業所需的輸入資料
03/// </summary>
04/// <param name="onOff">是否啟用1:on ,0:off</param>
05/// <param name="keepAliveTime">當沒收到client的ack時,等待多久才通知斷線(millisecond)</param>
06/// <param name="keepAliveInterval">偵測間隔(millisecond)</param>
07/// <returns></returns>
08private byte[] GetKeepAliveSetting(int onOff, int keepAliveTime, int keepAliveInterval)
09{
10    byte[] buffer = new byte[12];
11    BitConverter.GetBytes(onOff).CopyTo(buffer, 0);
12    BitConverter.GetBytes(keepAliveTime).CopyTo(buffer, 4);
13    BitConverter.GetBytes(keepAliveInterval).CopyTo(buffer, 8);
14    return buffer;
15}

 

Socket.IOControl 的用法在.net 上的MSDN寫的不清不楚,有寫跟沒寫一樣,GetKeepAliveSetting 之所以要傳回12個byte及它格式說明如下圖

image

 

加上這一行的設定後

1listenSocket.IOControl(IOControlCode.KeepAliveValues, GetKeepAliveSetting(1, 5000, 5000), null);

每5秒 socket server 就會送一個[Keep-Alive]的訊息,client如果還在連線就會回覆[Keep-Alive-ACK]:image

 

再來,讓我拔掉client的網路線,不用多久你的server程式就會收到client已斷線的通知了: image

 

 

posted on 2012-10-08 09:15 NET未来之路 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/lonelyxmas/archive/2012/10/08/2714738.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值