TCP正常的斷開,通信雙方(服務(wù)端和客戶端)都是能知道的。但是非正常的斷開,比如直接拔掉了網(wǎng)線,就只能靠如下兩種方法,實現(xiàn)短時間內(nèi)的檢測。
一,心跳包機制
心跳包機制,是網(wǎng)游設(shè)計中的常用機制。從用戶層面,自己發(fā)包去判斷對方連線狀態(tài)??梢愿鶕?jù)情況,很靈活的使用。比如,20秒發(fā)送一個最小的數(shù)據(jù)包(也可以根據(jù)實際情況稍帶一些其他數(shù)據(jù))。如果發(fā)送沒有回應(yīng),就判斷對方掉線了。
二,利用tcp_keepalive機制
利用TCP的機制,通過設(shè)置系統(tǒng)參數(shù),從系統(tǒng)層面,監(jiān)測tcp的連接狀態(tài)。以下為linux下的方法:
1,首先查看系統(tǒng)tcp_keepalive相關(guān)參數(shù)(centos和Ubuntu)
# sysctl -a|grep tcp_keepalive
顯示如下:
net.ipv4.tcp_keepalive_intvl = 75
net.ipv4.tcp_keepalive_probes = 9
net.ipv4.tcp_keepalive_time = 7200
分別說一下這三個參數(shù):
tcp_keepalive_time 參數(shù):
是指TCP發(fā)送keepalive消息的頻度,默認為7200秒,也就是兩個小時。
keepalive_intvl 參數(shù):
當(dāng)探測沒有確認時,重新發(fā)送探測的頻度。默認是75秒。
keepalive_probes 參數(shù):
在認定連接失效之前,發(fā)送多少個TCP的keepalive探測包。默認值是9次。
--------------------------------------------------------------------
2,修改系統(tǒng)的tcp_keepalive相關(guān)參數(shù)
在知道以上三個系統(tǒng)參數(shù)的定義和作用之后,我們來修改一下這三個參數(shù):
修改/etc/sysctl.conf文件:
# vi /etc/sysctl.conf
在打開的文件中,加入如下三行:
net.ipv4.tcp_keepalive_intvl = 1
net.ipv4.tcp_keepalive_probes = 1
net.ipv4.tcp_keepalive_time = 5
保存文件。
--------------------------------------------------------------------
3,重啟服務(wù)器。
# reboot
附注:或者臨時使系統(tǒng)設(shè)置生效也行:# sysctl -p
--------------------------------------------------------------------
4,修改程序代碼部分。
注意:僅僅配置內(nèi)核參數(shù)是不夠的,還必須在編程的時候設(shè)置套接字的選項,調(diào)用函數(shù)是
socket.setsockopt(level, optname, value)
示例:
level為SOL_SOCKET的話,選項為SO_KEEPALIVE,值為布爾。
socket.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, True)
此外還可以設(shè)置TCP選項(設(shè)置的level為SOL_TCP而不是SOL_SOCKET)覆蓋系統(tǒng)全局設(shè)置
TCP_KEEPCNT 與tcp_keepalive_probes 對應(yīng)
TCP_KEEPIDLE 與tcp_keepalive_time 對應(yīng)
TCP_KEEPINTVL 與tcp_keepalive_intvl 對應(yīng)
--------------------------------------------------------------------