Tcp的斷線(xiàn)檢測(cè)
tcp的斷線(xiàn)檢測(cè),分為兩種:
① 利用tcp自帶的keep –alive機(jī)制
② 自己組建心跳包的方式向?qū)Χ税l(fā)送
通過(guò)Keep-alive機(jī)制對(duì)tcp的連接保持,也就是Tcp的心跳包,見(jiàn)MSDN:
If keep-alive is enabled for a TCP socket with SO_KEEPALIVE, then the default TCP settings are used for the keep-alive timeout and interval unless these values have been changed by calling the WSAIoctl function with the SIO_KEEPALIVE_VALS option. The default settings when a TCP socket is initialized sets the keep-alive timeout to 2 hours and the keep-alive interval to 1 second.
也就是說(shuō)協(xié)議棧會(huì)在2小時(shí)后發(fā)送向?qū)Χ税l(fā)送請(qǐng)求包。默認(rèn)情況下,此Keep-alive機(jī)制是關(guān)閉的。
Keep-alive默認(rèn)下是關(guān)閉的,也就是本端與對(duì)端是除非程序主動(dòng)send,是不會(huì)發(fā)送數(shù)據(jù)包(心跳包),既是,處理本端與對(duì)端的系統(tǒng)里的socket狀態(tài)是不會(huì)變化,這里,如果對(duì)端當(dāng)機(jī)(或者網(wǎng)線(xiàn)斷掉),本端是無(wú)法知道對(duì)端socket已經(jīng)關(guān)閉,所以本端的socket會(huì)一直的存在。
通過(guò)實(shí)驗(yàn)發(fā)現(xiàn),客戶(hù)端網(wǎng)線(xiàn)拔掉之后,此時(shí)服務(wù)端的連接依然存在。
所以,tcp只是數(shù)據(jù)的發(fā)送與接收,包括握手,斷開(kāi)以及rst,time_wait,close_wait 等等。
心跳包機(jī)制
心跳包之所以叫心跳包是因?yàn)椋核裥奶粯用扛艄潭〞r(shí)間發(fā)一次,以此來(lái)告訴服務(wù)器,這個(gè)客戶(hù)端還活著。事實(shí)上這是為了保持長(zhǎng)連接,至于這個(gè)包的內(nèi)容,是沒(méi)有什么特別規(guī)定的,不過(guò)一般都是很小的包,或者只包含包頭的一個(gè)空包。
在TCP的機(jī)制里面,本身是存在有心跳包的機(jī)制的,也就是TCP的選項(xiàng):SO_KEEPALIVE。系統(tǒng)默認(rèn)是設(shè)置的2小時(shí)的心跳頻率。但是它檢查不到機(jī)器斷電、網(wǎng)線(xiàn)拔出、防火墻這些斷線(xiàn)。而且邏輯層處理斷線(xiàn)可能也不是那么好處理。一般,如果只是用于保活還是可以的。
心跳包一般來(lái)說(shuō)都是在邏輯層發(fā)送空的echo包來(lái)實(shí)現(xiàn)的。下一個(gè)定時(shí)器,在一定時(shí)間間隔下發(fā)送一個(gè)空包給客戶(hù)端,然后客戶(hù)端反饋一個(gè)同樣的空包回來(lái),服務(wù)器如果在一定時(shí)間內(nèi)收不到客戶(hù)端發(fā)送過(guò)來(lái)的反饋包,那就只有認(rèn)定說(shuō)掉線(xiàn)了。 其實(shí),要判定掉線(xiàn),只需要send或者recv一下,如果結(jié)果為零,則為掉線(xiàn)。
但是,在長(zhǎng)連接下,有可能很長(zhǎng)一段時(shí)間都沒(méi)有數(shù)據(jù)往來(lái)。理論上說(shuō),這個(gè)連接是一直保持連接的,但是實(shí)際情況中,如果中間節(jié)點(diǎn)出現(xiàn)什么故障是難以知道的。更要命的是,有的節(jié)點(diǎn)(防火墻)會(huì)自動(dòng)把一定時(shí)間之內(nèi)沒(méi)有數(shù)據(jù)交互的連接給斷掉
。在這個(gè)時(shí)候,就需要我們的心跳包了,用于維持長(zhǎng)連接,保活。
在獲知了斷線(xiàn)之后,服務(wù)器邏輯可能需要做一些事情,比如斷線(xiàn)后的數(shù)據(jù)清理呀,重新連接呀……當(dāng)然,這個(gè)自然是要由邏輯層根據(jù)需求去做了。
總的來(lái)說(shuō),心跳包主要也就是用于長(zhǎng)連接的?;詈蛿嗑€(xiàn)處理。一般的應(yīng)用下,判定時(shí)間在30-40秒比較不錯(cuò)。如果實(shí)在要求高,那就在6-9秒。
心跳檢測(cè)步驟
1、 客戶(hù)端每隔一個(gè)時(shí)間間隔發(fā)生一個(gè)探測(cè)包給服務(wù)器
2、 客戶(hù)端發(fā)包時(shí)啟動(dòng)一個(gè)超時(shí)定時(shí)器
3、 服務(wù)器端接收到檢測(cè)包,應(yīng)該回應(yīng)一個(gè)包
4、 如果客戶(hù)機(jī)收到服務(wù)器的應(yīng)答包,則說(shuō)明服務(wù)器正常,刪除超時(shí)定時(shí)器
5、 如果客戶(hù)端的超時(shí)定時(shí)器超時(shí),依然沒(méi)有收到應(yīng)答包,則說(shuō)明服務(wù)器掛了