TCP新手誤區 心跳的意義

2021-08-27 23:43:47 字數 1659 閱讀 8775

最近面試了很多的學生,發現很多tcp的新手對於tcp的使用有一些誤區,而這些坑也是當初我曾經疑惑過得地方。網上很少有文章對這些問題有過詳細的解析,即是有也只是直接給出結論和做法,沒有人將其中的來龍去脈講解清楚,所以我將這些問題的來龍去脈在這一系列的文章中講述出來,希望能讓廣大tcp的新手避開這些坑。

我面試時經常會問的乙個問題是當tcp兩端a、b建立了連線後,如果一端拔掉網線或者拔掉電源,那麼另一端能夠收到通知嗎? 

答案是不會,但是只有少數人能夠正確的回答這個問題。

tcp是一種有連線的協議,但是這個連線並不是指有一條實際的電路,而是一種虛擬的電路。tcp的建立連線和斷開連線都是通過傳送資料實現的,也就是我們常說的三次握手、四次揮手。tcp兩端儲存了一種資料的狀態,就代表這種連線,tcp兩端之間的路由裝置只是將資料**到目的地,並不知道這些資料實際代表了什麼含義,也並沒有在其中儲存任何的狀態資訊,也就是說中間的路由裝置沒有什麼連線的概念,只是將資料**到目的地,只有資料的傳送者和接受者兩端真正的知道傳輸的資料代表著一條連線。

但是這就說明了一點,如果不傳送資料那麼是無法斷開連線的。正常情況下當tcp的一端a呼叫了socket的close或者程序結束,作業系統就會按照tcp協議傳送fin資料報文。b端收到後就會斷開連線。但是當出現了上文所說的異常情況時:被拔掉網線或者斷掉電源,總結起來就是沒有機會發出斷開的fin資料報文。那麼和a直連的路由裝置雖然知道a裝置已經斷開了,但是路由裝置並沒有儲存連線的狀態資訊,所以路由裝置也就不可能去通知b端a端的斷開。而b端沒有收到斷開的資料報文就會依然保持連線。所以a端拔掉網線或者斷掉電源後b端是沒辦法收到斷開連線的通知的

保持連線並不是毫無代價的,如果這種異常斷開的連線有很多,那麼勢必會耗費大量的資源,必須要想辦法檢測出這種異常連線。 

檢測的方法很簡單,只要讓b端主動通過這個連線向a端繼續傳送資料即可。上文說過,a端異常斷開後,和a端直接連線的路由器是知道的。當b端傳送的資料經過**後到達這個路由器後,必然最終會返回b端乙個目的不可達。此時b端立刻就會知道這條連線其實已經異常斷開了。 

但是b端不可能知道什麼時候會出現這種異常,所以b端必須定時傳送資料來檢測連線是否異常斷開。資料的內容無關緊要,任何資料都能達到這個效果。這個資料就是我們經常在tcp程式設計中所說的心跳。

tcp協議本身就提供了一種這樣的機制來探測對端的存活。tcp協議有乙個keep_live開關,只要開啟這個開關就會定時傳送一些資料長度為零的探測心跳包,傳送的頻率和次數都可以設定,具體的方法在網上搜尋tcp keepalive即可,網上有很多文章,這裡不再贅述。

除了使用tcp協議本身的保活開關機制,還可以在應用層主動傳送心跳資料報,那麼在應用層主動傳送心跳資料報的方式和tcp協議本身的保活機制有什麼區別呢?

那麼是否只是一端向另一端傳送心跳就行了呢?顯然不行。因為兩端都有可能發生異常斷開的情況。所以tcp連線的兩端必須都向對端傳送心跳。

tcp中不使用心跳通常來說並沒有什麼問題,但是一旦遇到了連線異常斷開,那麼就會出現問題。所以任何乙個完善的tcp應用都應該使用心跳。 

心跳的意義對於很多tcp的初學者而言是個大坑,我寫這篇文章希望初學者能夠在編寫tcp程式時避免這個坑,同時也希望面試者能夠深入理解tcp的心跳機制,能夠取得更好的面試結果。

TCP新手誤區 粘包的處理

最近面試了很多的學生,發現很多tcp的新手對於tcp的使用有一些誤區,而這些坑也是當初我曾經疑惑過得地方。網上很少有文章對這些問題有過詳細的解析,即是有也只是直接給出結論和做法,沒有人將其中的來龍去脈講解清楚,所以我將這些問題的來龍去脈在這一系列的文章中講述出來,希望能讓廣大tcp的新手避開這些坑。...

效能測試新手誤區(一)

系列原創 效能測試新手誤區 有過一些效能測試經驗的人很容易進入此狀態,他們已經熟悉了效能測試的基本流程,能夠比較熟練的使用測試工具開展工作。我大概從事效能測試一年左右時遇到了這個問題,那時我覺得效能測試的過程沒有太多挑戰,遇到的每乙個系統,彷彿都可以用同樣的流程完成。半天時間填寫測試方案,一天時間來...

效能測試新手誤區(六) 效能監控

資料庫 或中介軟體 非常慢了,如何監控它的效能 你想得到什麼效能指標?就是 內部的效能指標 收到效能測試人員這樣的問題後,通常會發生上面的對話。我的觀點是,準確的說出你想要做什麼,比你會不會做更重要。那麼對於效能測試人員來說,效能監控 這門必修課,該從何下手呢?如果我給你乙個黑盒子,告訴你裡面是一部...