10深刻理解TCP IP的11種協議狀態

2021-08-28 07:32:02 字數 2834 閱讀 8547

在呼叫listen(int socked, int backlog)函式的時候,做了2件事情:

(1)將主動套接字轉換為被動套接字。tcp狀態轉換圖從closed狀態轉換為listen狀態

(2)backlog規定了核心應該為相應的套接字排隊的最大連線個數。核心為這個監聽套接字維護兩個佇列:(兩個佇列之和不能超過backlog)

a:未完成連線佇列:此時這個佇列中的套接字處於syn_recv狀態。

b:已完成連線佇列:此時這個佇列中的套接字處於established狀態。

也就是說在listen()的時候,套接字有2種狀態syn_recv 和 established。

accept()是從已完成佇列中的隊頭中獲取已經處於established狀態的套接字,然後accept()返回給使用者程序,若隊列為空,則accept()投入睡眠,直到已完成佇列中有新的一項。

tcp/ip是全雙工、雙通道協議,既可以收也可以發,是乙個雙向認證的

過程,雙方必須確保對端確實收到了自己傳送的包,這樣全雙工通道完全

建立起來了。 先呼叫close的那一端,最終socket狀態推進到time_wait

狀態,會等一會再close,這裡使用了io復用技術。

因為要給對等方乙個確認,但是在公網上有可能這個確認不是那麼順利,出現了網路擁塞和異常處理,此時不把先close的一方推到closed狀態,是因為讓確認包在異常的情況下進行幾次重新傳送,保證對方真正的進入closed狀態,然後釋放該釋放的資源。就是讓最後乙個確認包在網路不通暢的情況下真正的進入確認狀態。

注意:tcp/ip協議是雙通道的,客戶端關閉與服務端關閉沒有任何的關係,tcp/ip是乙個流協議,server端呼叫read()返回0,則通知對方寫斷了,a端關閉了socket並不代表b端不能往socket寫資料,頂多寫失敗了。linux核心也是有緩衝區的(傳送緩衝區、接收緩衝區),緩衝區達到了低水位才會往對端傳送資料。

time_wait時間是2msl,(2倍的最大生命期時間),原因是(ack y+1) 如果傳送失敗可以重發。服務端處於close狀態,不等於客戶端也處於close狀態。

因為對等方沒有顯示的呼叫close,伺服器掛掉也相當於顯示的呼叫close函式,若a端一直是fin_wait_2,需要查b端為什麼沒有呼叫close函式,有可能是阻塞在某一函式上,也有可能忘記了close。

任一對等方都可以顯示的呼叫close(),當雙方同時呼叫close時,這時就會出現第11種狀態closing。客戶端 服務端同時呼叫close時,tcp/ip協議能檢測出來,因為都需要對方的確認,此時tcp/ip協議將狀態置為短暫的closing。當收到對方的確認時,雙方都進入到了time_wait狀態,因為雙方都主動的呼叫了close()函式,都進入到了time_wait狀態,經過n時間後,雙方都消失。

對方能收到,而且是保證可靠的能收到。因為tcp/ip協議是乙個流協議。清空緩衝區才會呼叫close。資料報在快取區裡面,呼叫close函式,tcp/ip就會處理緩衝區,將資料推到對等方,最後有個fin也會跑到對等方緩衝區裡面,然後對等方乙個乙個的收報文,當收到fin後,發現是乙個流水結束符,此時檢測到了對方的socket已經關閉了,此時把資料給到使用者空間,至此,tcp/ip的工作已經全部做完,然後使用者程式處理。

tcp/ip能保證"abcd"給到對端,而且也能保證告訴對端socket已經關閉了。

演示1:多個客戶端與單個伺服器(不支援併發)連線,此時多個客戶端仍然可以連線上伺服器

為什麼3個客戶端都能與單伺服器建立連線,但只有乙個客戶端能通訊?

答:因為accept函式放在了for迴圈的上邊,這樣主程序只能發包收包,不能accept

沒有機會呼叫accept 即 沒有機會從已完成三次握手的佇列中拿到連線,所以不支援

併發,只支援單連線。正確的做法是將accept放在迴圈裡面

**實現請看:

演示2:還是用上面的**

(1)啟動服務端,然後啟動客戶端,狀態如下

(2)現在ctrl+ c掉服務端

殺死server,相當於伺服器主動的close,然後對等方收到fin後,tcp/ip協議在上層應用不知道的情況下向對方發了乙個確認包

對MapReduce Yarn的深刻理解

1.mapreduce詳細工作流程之map階段 2.mapreduce流程之reduce階段巨集觀上看 reducetask分為四個階段 1.copy 2.merge 3.sort 4.reduce 1.copy reducetask將遠端從maptask上覆制過來要處理的資料,針對某一片資料,如果...

深刻理解Vue中的元件

今天看了下vue官網上關於元件的教程,感覺內容還挺多,現在把元件中基本的知識梳理一下。註冊元件就是利用vue.component 方法,先傳入乙個自定義元件的名字,然後傳入這個元件的配置。vue.component mycomponent 如上方式,就已經建立了乙個自定義元件,然後就可以在vue例項...

深刻理解MyBatis中 和 的區別

首先看一下下面這兩個sql語句的區別 select id,username,password,role from user where username and password select id,username,password,role from user where username an...