unp第七章補充之TCP半開連接與半閉連接


半打開(Half-Open)連接和半關閉(Half-Close)連接。TCP是一個全雙工(Full-Duplex)協議,因此這里的半連接"半"字就是相對於全雙工的"全"來說的。

全雙工傳輸

 

 

英文寫法是:Full-Duplex Transmissions

是指交換機在發送數據的同時也能夠接收數據,兩者同步進行,這好像我們平時打電話一樣,說話的同時也能夠聽到對方的聲音。目前的交換機都支持全雙工。

全雙工的好處在於遲延小,速度快。

與之對應的是【半雙工】這個概念:就是指一個時間段內只有一個動作發生,舉個簡單例子,一天窄窄的馬路,同時只能有一輛車通過,當目前有兩量車對開,這種 情況下就只能一輛先過,等到頭兒后另一輛再開,這個例子就形象的說明了半雙工的原理。早期的對講機、以及早期集線器等設備都是實行半雙工的產品。隨着技術 的不斷進步,半雙工會逐漸退出歷史舞台。 

全雙工與半雙工

 

   在串行通信中,數據通常是在兩個站(如終端和微機)之間進行傳送,按照數據流的方向可分成三種基本的傳送方式:全雙工、半雙工、和單工.但單工目前已很少采用,下面僅介紹前兩種方式. 

1 、全雙工方式( full duplex )
   當數據的發送和接收分流,分別由兩根不同的傳輸線傳送時,通信雙方都能在同一時刻進行發送和接收操作,這樣的傳送方式就是全雙工制.在全雙工方式下,通信 系統的每一端都設置了發送器和接收器,因此,能控制數據同時在兩個方向上傳送.全雙工方式無需進行方向的切換,因此,沒有切換操作所產生的時間延遲,這對 那些不能有時間延誤的交互式應用(例如遠程監測和控制系統)十分有利.這種方式要求通訊雙方均有發送器和接收器,同時,需要 2 根數據線傳送數據信號.(可能還需要控制線和狀態線,以及地線). 

   比如,計算機主機用串行接口連接顯示終端,而顯示終端帶有鍵盤.這樣,一方面鍵盤上輸入的字符送到主機內存;另一方面,主機內存的信息可以送到屏幕顯示. 通常,往鍵盤上打入 1 個字符以后,先不顯示,計算機主機收到字符后,立即回送到終端,然后終端再把這個字符顯示出來.這樣,前一個字符的回送過程和后一個字符的輸入過程是同時 進行的,即工作於全雙工方式. 

2 、半雙式方式( half duplex ) 
   若使用同一根傳輸線既作接收又作發送,雖然數據可以在兩個方向上傳送,但通信雙方不能同時收發數據,這樣的傳送方式就是半雙工制.采用半雙工方式時,通信 系統每一端的發送器和接收器,通過收 / 發開關轉接到通信線上,進行方向的切換,因此,會產生時間延遲.收 / 發開關實際上是由軟件控制的電子開關. 
當計算機主機用串行接口連接顯示終端時,在半雙工方式中,輸入過程和輸出過程使用同一通路.有些計算機和顯示終端之間采用半雙工方式工作,這時,從鍵盤打 入的字符在發送到主機的同時就被送到終端上顯示出來,而不是用回送的辦法,所以避免了接收過程和發送過程同時進行的情況. 

   目前多數終端和串行接口都為半雙工方式提供了換向能力,也為全雙工方式提供了兩條獨立的引腳.在實際使用時,一般並不需要通信雙方同時既發送又接收,像打印機這類的單向傳送設備,半雙工甚至單工就能勝任,也無需倒向.

 

一、半開連接

        從協議定義的角度來說,TCP的半開連接是指TCP連接的一端異常崩潰,或者在未通知對端的情況下關閉連接,這種情況下不可以正常收發數據,否則會產生RST(后面內容我們在介紹RST)。比如一個常見的情況是TCP連接的一端異常斷電,就會導致TCP的半開連接。如果沒有數據傳輸,對端就不會知道本端的異常而一直處於ESTABLISHED狀態(TCP有存活檢測機制,后面內容我們會進行介紹)。

        另外從linux實現的角度來說,因為linux內部有個半連接隊列,TCP半開連接是指發送了TCP連接請求,等待對方應答的狀態,此時連接並沒有完全建立起來,雙方還無法進行通信交互的狀態,此時就稱為半連接。由於一個完整的TCP連接需要經過三次握手才能完成,這里把三次握手之前的連接都稱之為半連接。

二、半關連接

        TCP的半關連接是指TCP連接只有一方發送了FIN,另一方沒有發出FIN包,仍然可以在一個方向上正常發送數據。這種場景並不常見,一般來說Berkeley sockets API調用shutdown()接口時候就會進入半關閉狀態(調用常規的close()一般是期待完整的雙向關閉這個TCP連接),shutdown()接口相當指示程序,本端已經沒有數據待發送,所以我發送一個FIN到對端,但是我仍然想要從對端接收數據,直到對端發送一個FIN指示關閉連接為止。如下圖所示,在紅色背景文本框標注的數據傳輸場景下就是TCP的半關連接


 

三、wireshrk抓包示例

首先注意半開連接是不能正常傳輸數據的,而半關連接是可以在其中的一個方向上傳輸數據的。下面簡單附一下wireshark的抓包圖示,限於篇幅僅作簡要介紹,詳細請參考對應的wireshark抓包文件

1.TCP半開

 

通過單台筆記本的雙無線網卡測試tcp連接的半開,步驟如下

  • server綁定網卡A的地址

  • client綁定網卡B的地址並連接server 對應截圖中的No 1--No 3包

  • client發送"hello"消息 對應截圖中的No 4包

  • server正常接收到后"hello"消息后 拔掉網卡A 

  • kill掉server進程 使server的FIN消息不能發送到client

  • 插上網卡A  注意在路由器中綁定IP地址和MAC地址,使得網卡A的地址和之前是一致的,此時client和server即處於半開連接狀態

  • client向server發送"world"消息   對應截圖中的No 6包

  • server回復rst消息

 

 

2.TCP半關

正常建立連接后,client首先發送"hello"消息給server,然后server發送FIN給client,關閉了server到client方向的數據傳輸,但是client仍然可以向server傳輸數據,此時client和server之間的連接即處於半關連接的狀態,接下來client向server發送"world"消息,然后發送FIN給server關閉client到server方向的數據傳輸。

 

 

補充說明:

1.目前linux最新的實現已經沒有半連接隊列了,連接請求的pseudo sock已經插入ehash(e代表establish,ehash即已連接hash隊列)中了


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM