TCP服務端如何判斷客戶端斷開連線學習

2021-09-28 16:28:15 字數 1139 閱讀 1377

keepalive是很多的tcp實現提供的一種機制,它允許連線在空閒的時候雙方會傳送一些特殊的資料段,並通過響應與否來判斷連線是否還存活著(所謂keep~~alive)。其實keepalive在實際的應用中並不常見。為何如此?這得歸結於keepalive設計的初衷。keepalive適用於清除死亡時間比較長的連線。

比如這樣的場景:乙個使用者建立tcp連線訪問了乙個web伺服器,當使用者完成他執行的操作後,很粗暴的直接撥了網線。這種情況下,這個tcp連線已經斷開了,但是web伺服器並不知道,它會依然守護著這個連線。如果web server設定了keepalive,那麼它就能夠在使用者斷開網線的大概幾個小時以後,確認這個連線已經中斷,然後丟棄此連線,**資源。

採用keepalive,它會先要求此連線一定時間沒有活動(一般是幾個小時),然後發出資料段,經過多次嘗試後(每次嘗試之間也有時間間隔),如果仍沒有響應,則判斷連線中斷。可想而知,整個週期需要很長的時間。

所以,如前面的場景那樣,需要一種方法能夠清除和**那些在系統不知情的情況下死去了很久的連線,keepalive是非常好的選擇。

但是,在大部分情況下,特別是分布式環境中,我們需要的是乙個能夠快速或者實時監控連線狀態的機制,這裡,heart-beat才是更加合適的方案。

heart-beat(心跳),按我的理解,它的原理和keepalive非常類似,都是傳送乙個訊號給對方,如果多次傳送都沒有響應的話,則判斷連線中斷。它們的不同點在於,keepalive是tcp實現中內建的機制,是在建立tcp連線時通過設定引數啟動keepalive機制;而heart-beat則需要在tcp之上的應用層實現。乙個簡單的heart-beat實現一般測試連線是否中斷採用的時間間隔都比較短,可以很快的決定連線是否中斷。並且,由於是在應用層實現,因為可以自行決定當判斷連線中斷後應該採取的行為,而keepalive在判斷連線失敗後只會將連線丟棄。

關於heart-beat,乙個非常有趣的問題是,應該在傳輸真正資料的連線中傳送「心跳」訊號,還是可以專門建立乙個傳送「心跳」訊號的連線。比如說,a,b兩台機器之間通過連線m來傳輸資料,現在為了能夠檢測a,b之間的連線狀態,我們是應該在連線m中傳輸「心跳」訊號,還是建立新的連線n來專門傳輸「心跳」呢?我個人認為兩者皆可。如果擔心的是端到端的連線狀態,那麼就直接在該條連線中實現「心跳」。但很多時候,關注的是網路狀況和兩台主機間的連線狀態,這種情況下, 建立專門的「心跳」連線也未嘗不可。

JAVA NIO寫服務端判斷客戶端斷開連線的方法

不過這個方法有個問題,就是 1 能偵測到客戶端主動斷開與服務端的連線,但是如果客戶端掉線,服務端就接收不到了。2 如果處於等待狀態,就會出問題。比如說客戶端的資料還沒有準備好傳送,這樣你就已經關閉了鏈結。最近學習nio,一直有個疑問,怎麼知道客戶端斷開了連線.在上網找和試驗之後發現下面的方法可以實現...

JAVA NIO寫服務端判斷客戶端斷開連線的方法

最近學習nio,一直有個疑問,怎麼知道客戶端斷開了連線.在上網找和試驗之後發現下面的方法可以實現這個目的.我們一般會在服務端有個大的while,然後在裡面迴圈判斷是否有客戶端連線 ssc serversocketchannel sk.channel sc ssc.accept system.out....

TCP客戶端服務端demo

服務端程式 include include include include include include include int main 列印握手成功的客戶端 struct sockaddr in servaddr socklen t nservlen sizeof servaddr getso...