網絡編程釋疑之:TCP連接拔掉網線後會發生什麼

背景:前些天團隊在進行終端設備和服務器端長連接業務的測試時,發現了這麼一個情況:在拔掉設備端的網線後,再插上網線,有時可以繼續正常的進行長接連請求,而且用的還是拔掉網線之前的那個長連接。但是有時卻不能繼續正常的長連接請求,需要重新建立一個新的長連接。讓我尤感詫異的是第一種網線斷開再插上後長連接可以恢復的情況,徹底顛覆了我一直抱有的一個所謂的“物理連接”的觀念。究竟怎麼回事,我們來探個究竟。


首先說說我自己發明的“物理連接”這個名詞,不管怎麼說我都是一個網絡編程的"老手"。經常會給新人和其他有問題諮詢我的同事灌輸一個觀念,只要網線拔掉了,說明物理連接都斷了,更別提邏輯上的TCP長連接,再插上網線也只能再建立一個新的連接來繼續進行請求。我做個簡單的比喻:我理解的TCP長連接好比以前我們用的有線電話,甲和乙通話的過程中,倘若其中一人的電話線被拔掉了,連接就徹底斷了。即使再插上電話線也不可能自動恢復通話,我們不得不重新撥通。

發現了插上網線後連接還會恢復的情況,我起初以爲是簡單的TCP套接字複用的情況,但是發現設備端並未編寫自動重連的邏輯,這就太讓我好奇和疑慮了。於是我找了一個同事配合我進行了多次測試,發現了拔掉網線後針對此TCP長連接可能會出現的 兩種情況。

首先做下鋪墊,做過網絡編程的朋友應該都知道這麼一個情況

當客戶端與服務器建立起正常的TCP連接後,如果客戶主機網線斷開、電源掉電、或系統崩潰,服務器進程將永遠不會知道(通過我們常用的select,epoll監測不到斷開或錯誤事件),如果不主動處理或重啓系統的話對於服務端來說會一直維持着這個連接,任憑服務端進程如何望穿秋水,也永遠再等不到客戶端的任何迴應。這種情況就是半開連接,浪費了服務器端可用的文件描述符。

說明網線斷開對端是不能做任何感知的,除非我們配置操作系統的SO_KEEPALIVE選項,或者進行應用層心跳檢測。請參考文章《網絡編程釋疑之:TCP半開連接的處理》

  1. 如果網線斷開的時間短暫,在SO_KEEPALIVE設定的探測時間間隔內,並且兩端在此期間沒有任何針對此長連接的網絡操作。當連上網線後此TCP連接可以自動恢復,繼續進行正常的網絡操作。

  2. 如果網線斷開的時間很長,超出了SO_KEEPALIVE設定的探測時間間隔,或者兩端期間在此有了任何針對此長連接的網絡操作。當連上網線時就會出現ETIMEDOUT或者ECONNRESET的錯誤。你必須重新建立一個新的長連接進行網絡操作。

這件事後,我再也不敢隨便發明名詞了,嗚嗚......

發現一篇好文:《tcp連接斷連問題剖析》


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章