Tcp之心跳包
Tcp之心跳包
心跳包
跳包之所以叫心跳包是因為:它像心跳一樣每隔固定時間發一次,以此來告訴服務器,這個客戶端還活著。
事實上這是為了保持長連接,至于這個包的內容,是沒有什么特別規定的,不過一般都是很小的包,或者只包含包頭的一個空包。
在TCP的機制里面,本身是存在有心跳包的機制的,也就是TCP的選項:SO_KEEPALIVE。系統默認是設置的2小時的心跳頻率。但是它檢查不到機器斷電、網線拔出、防火墻這些斷線。而且邏輯層處理斷線可能也不是那么好處理。一般,如果只是用于?;钸€是可以的。
心跳包一般來說都是在邏輯層發送空的echo包來實現的。下一個定時器,在一定時間間隔下發送一個空包給客戶端,然后客戶端反饋一個同樣的空包回來,服務器如果在一定時間內收不到客戶端發送過來的反饋包,那就只有認定說掉線了。
其實,要判定掉線,只需要send或者recv一下,如果結果為零,則為掉線。但是,在長連接下,有可能很長一段時間都沒有數據往來。理論上說,這個連接是一直保持連接的,但是實際情況中,如果中間節點出現什么故障是難以知道的。更要命的是,有的節點(防火墻)會自動把一定時間之內沒有數據交互的連接給斷掉。在這個時候,就需要我們的心跳包了,用于維持長連接,保活。
在獲知了斷線之后,服務器邏輯可能需要做一些事情,比如斷線后的數據清理呀,重新連接呀……當然,這個自然是要由邏輯層根據需求去做了。
?總的來說,心跳包主要也就是用于長連接的?;詈蛿嗑€處理。一般的應用下,判定時間在30-40秒比較不錯。如果實在要求高,那就在6-9秒。
?
為什么需要心跳包?
TCP的KeepAlive?;顧C制
因為要考慮到一個服務器通常會連接多個客戶端,因此由用戶在應用層自己實現心跳包,代碼較多 且稍顯復雜,而利用TCP/IP協議層為內置的KeepAlive功能來實現心跳功能則簡單得多。 不論是服務端還是客戶端,一方開啟KeepAlive功能后,就會自動在規定時間內向對方發送心跳包, 而另一方在收到心跳包后就會自動回復,以告訴對方我仍然在線。 因為開啟KeepAlive功能需要消耗額外的寬帶和流量,所以TCP協議層默認并不開啟KeepAlive功 能,盡管這微不足道,但在按流量計費的環境下增加了費用,另一方面,KeepAlive設置不合理時可能會 因為短暫的網絡波動而斷開健康的TCP連接。并且,默認的KeepAlive超時需要7,200,000 MilliSeconds, 即2小時,探測次數為5次。對于很多服務端應用程序來說,2小時的空閑時間太長。因此,我們需要手工開啟KeepAlive功能并設置合理的KeepAlive參數。
?
如何開啟KeepAlive?
KeepAlive并不是默認開啟的,在Linux系統上沒有一個全局的選項去開啟TCP的KeepAlive。需要開啟KeepAlive的應用必須在TCP的socket中單獨開啟。Linux Kernel有三個選項影響到KeepAlive的行為:
1.net.ipv4.tcpkeepaliveintvl = 75
2.net.ipv4.tcpkeepaliveprobes = 9
3.net.ipv4.tcpkeepalivetime = 7200
tcpkeepalivetime的單位是秒,表示TCP鏈接在多少秒之后沒有數據報文傳輸啟動探測報文; tcpkeepaliveintvl單位是也秒,表示前一個探測報文和后一個探測報文之間的時間間隔,tcpkeepaliveprobes表示探測的次數。
TCP socket也有三個選項和內核對應,通過setsockopt系統調用針對單獨的socket進行設置:
TCPKEEPCNT: 覆蓋 tcpkeepaliveprobes
TCPKEEPIDLE: 覆蓋 tcpkeepalivetime
TCPKEEPINTVL: 覆蓋 tcpkeepalive_intvl
舉個例子,以我的系統默認設置為例,kernel默認設置的tcpkeepalivetime是7200s, 如果我在應用程序中針對socket開啟了KeepAlive,然后設置的TCP_KEEPIDLE為60,那么TCP協議棧在發現TCP鏈接空閑了60s沒有數據傳輸的時候就會發送第一個探測報文。
?
?
心跳包實現為什么要在服務端?
心跳包所以實現在服務器側,是因為與客戶端相比,服務器側的壽命更長,因為服務器側需要不間斷地提供服務,而客戶端可能由于用戶下班而合上電腦(TCP沒有來得及發送FIN關閉連接),這樣的話,服務器側就會有很多不可用的TCP連接(established),這樣的連接依然會占用服務器內存資源,于是就設計這個keepalive 來檢測客戶端是否可用,如果幾次重傳keepalive ,客戶端沒有相應,刪除連接,釋放資源。需要指出的是,超時時間是指TCP連接沒有任何數據、控制字傳輸的時間,如果有任何數據傳輸,會刷新定時器,重新走表。
為什么需要實現應用層心跳包?
KeepAlive是實現在TCP協議棧(四層),我們需要自己實現的應用層心跳在第七層,本質沒有任何區別。
心跳除了說明應用程序還活著,進程還在,網絡通暢,更重要的是表明應用程序還能正常工作,而TCP keepalive由操作系統負責探測,即便進程死鎖或者阻塞,操作系統也會如常收發TCP keepalive消息,對方無法得知這一異常。
它檢查不到機器斷電、網線拔出、防火墻這些斷線。而且邏輯層處理斷線可能也不是那么好處理。一般,如果只是用于?;钸€是可以的。
應用層需要獨立實現自己的心跳,是因為超時時間較長,無法給應用層提供快速的反饋,不能滿足人們的實時性的要求。另外應用層需要自己來定義心跳包格式。
?
?
心跳包的實現
心跳協議的基本形式:如果進程C依賴S,那么S應該按固定周期向C發送心跳,而C按固定周期來檢測心跳。換言之,通常是服務端向客戶端發送心跳。
心跳包的檢測步驟:
1服務端每隔一個時間間隔發生一個探測包給客戶端
2服務端發包時啟動一個超時定時器
3客戶端端接收到檢測包,應該回應一個包
4如果服務端收到客戶端的應答包,則說明客戶端正常,刪除超時定時器
5如果服務端端的超時定時器超時,依然沒有收到應答包,則說明客戶端掛了
TCP心跳包的實現可以參考一下這篇博文:https://www.cnblogs.com/scy251147/p/3333957.html
?
轉載于:https://www.cnblogs.com/-wenli/p/11161111.html
總結
- 上一篇: WPAN(无线个域网)和WLAN(无线局
- 下一篇: python怎么换背景_python –