筆記 TCP有限狀態機分析

2021-09-05 08:48:07 字數 4468 閱讀 2340

一、tcp狀態轉換圖

tcp涉及連線建立和連線終止的操作可以用狀態轉換圖(state transition diagram)來說明:

中文**:

tcp狀態及描述

closed:無連線是活動的或正在進行

listen:伺服器在等待進入呼叫

syn_recv:乙個連線請求已經到達,等待確認

syn_sent:應用已經開始,開啟乙個連線

established:正常資料傳輸狀態

fin_wait1:應用說它已經完成

fin_wait2:另一邊已同意釋放

itmed_wait:等待所有分組死掉

closing:兩邊同時嘗試關閉

time_wait:另一邊已初始化乙個釋放

last_ack:等待所有分組死掉

tcp為乙個連線定義了11種狀態,這些狀態可使用netstat顯示,它是乙個在除錯客戶/伺服器應用時很有用的工具,並且tcp規則規定如何基於當前狀態及在該狀態下所接收的分節從乙個狀態轉換到另乙個狀態。舉例來說,當某個應用程序在closed狀態下執行主動開啟時,tcp將傳送乙個syn,且新的狀態是syn_sent。如果這個tcp接著接收到乙個帶ack的syn,它將傳送乙個ack,且新的狀態是established。這個最終狀態是絕大多數資料傳送發生的狀態。

自established狀態引出的兩個箭頭處理連線的終止。如果某個應用程序在接收到乙個fin之前呼叫close(主動關閉),那就轉換到fin_wait_1狀態。但如果某個應用程序在established狀態期間接收到乙個fin(被動關閉),那就轉換到close_wait狀態。

我們用粗實線表示通常的客戶狀態轉換,用粗虛線表示通常的伺服器狀態轉換。圖中還註明存在兩個我們未曾討論的轉換:乙個為同時開啟(simultaneous open),發生在兩端幾乎同時傳送syn並且這兩個syn在網路中交錯的情形下,另乙個為同時關閉(simultaneous close),發生在兩端幾乎同時傳送fin的情形下。

二、tcp的三次握手建立連線

建立乙個tcp連線時會發生下述情形

1、客戶端傳送乙個帶syn標誌的tcp報文到伺服器。這是三次握手過程中的報文1。

2、伺服器端回應客戶端的,這是三次握手中的第2個報文,這個報文同時帶ack標誌和syn標誌。因此它表示對剛才客戶端syn報文的回應;同時又標誌syn給客戶端,詢問客戶端是否準備好進行資料通訊。

3、客戶必須再次回應服務段乙個ack報文,這是報文段3。

這種交換至少需要3個分組,因此稱之為tcp的三路握手(three-way handshake)。

三、tcp四次握手關閉連線

由於tcp連線是全雙工的,因此每個方向都必須單獨進行關閉。這原則是當一方完成它的資料傳送任務後就能傳送乙個fin來終止這個方向的連線。收到乙個 fin只意味著這一方向上沒有資料流動,乙個tcp連線在收到乙個fin後仍能傳送資料。首先進行關閉的一方將執行主動關閉,而另一方執行被動關閉。

1、tcp客戶端傳送乙個fin,用來關閉客戶到伺服器的資料傳送(報文段4)。

2、伺服器收到這個fin,它發回乙個ack,確認序號為收到的序號加1(報文段5)。和syn一樣,乙個fin將占用乙個序號。

3、伺服器關閉客戶端的連線,傳送乙個fin給客戶端(報文段6)。

4、客戶段發回ack報文確認,並將確認序號設定為收到序號加1(報文段7)。

四、tcp 11種狀態詳細解釋

closed:這個沒什麼好說的了,表示初始狀態。

listen:這個也是非常容易理解的乙個狀態,表示伺服器端的某個socket處於監聽狀態,可以接受連線了。

syn_rcvd:這個狀態表示接受到了syn報文,在正常情況下,這個狀態是伺服器端的socket在建立tcp連線時的三次握手會話過程中的乙個中間狀態,很短暫,基本上用netstat你是很難看到這種狀態的,除非你特意寫了乙個客戶端測試程式,故意將三次tcp握手過程中最後乙個ack報文不予傳送。因此這種狀態時,當收到客戶端的ack報文後,它會進入到established狀態。

syn_sent:這個狀態與syn_rcvd遙想呼應,當客戶端socket執行connect連線時,它首先傳送syn報文,因此也隨即它會進入到了syn_sent狀態,並等待服務端的傳送三次握手中的第2個報文。syn_sent狀態表示客戶端已傳送syn報文。

established:這個容易理解了,表示連線已經建立了。

fin_wait_1:這個狀態要好好解釋一下,其實fin_wait_1和fin_wait_2狀態的真正含義都是表示等待對方的fin報文。而這兩種狀態的區別是:fin_wait_1狀態實際上是當socket在established狀態時,它想主動關閉連線,向對方傳送了fin報文,此時該socket即進入到fin_wait_1狀態。而當對方回應ack報文後,則進入到fin_wait_2狀態,當然在實際的正常情況下,無論對方何種情況下,都應該馬上回應ack報文,所以fin_wait_1狀態一般是比較難見到的,而fin_wait_2狀態還有時常常可以用netstat看到。

fin_wait_2:上面已經詳細解釋了這種狀態,實際上fin_wait_2狀態下的socket,表示半連線,也即有一方要求close連線,但另外還告訴對方,我暫時還有點資料需要傳送給你,稍後再關閉連線。

time_wait:表示收到了對方的fin報文,並傳送出了ack報文,就等2msl後即可回到closed可用狀態了。如果fin_wait_1狀態下,收到了對方同時帶fin標誌和ack標誌的報文時,可以直接進入到time_wait狀態,而無須經過fin_wait_2狀態。

closing:這種狀態比較特殊,實際情況中應該是很少見,屬於一種比較罕見的例外狀態。正常情況下,當你傳送fin報文後,按理來說是應該先收到(或同時收到)對方的ack報文,再收到對方的fin報文。但是closing狀態表示你傳送fin報文後,並沒有收到對方的ack報文,反而卻也收到了對方的fin報文。什麼情況下會出現此種情況呢?其實細想一下,也不難得出結論:那就是如果雙方幾乎在同時close乙個socket的話,那麼就出現了雙方同時傳送fin報文的情況,也即會出現closing狀態,表示雙方都正在關閉socket連線。

close_wait:這種狀態的含義其實是表示在等待關閉。怎麼理解呢?當對方close乙個socket後傳送fin報文給自己,你系統毫無疑問地會回應乙個ack報文給對方,此時則進入到close_wait狀態。接下來呢,實際上你真正需要考慮的事情是察看你是否還有資料傳送給對方,如果沒有的話,那麼你也就可以close這個socket,傳送fin報文給對方,也即關閉連線。所以你在close_wait狀態下,需要完成的事情是等待你去關閉連線。

last_ack:這個狀態還是比較容易好理解的,它是被動關閉一方在傳送fin報文後,最後等待對方的ack報文。當收到ack報文後,也即可以進入到closed可用狀態了。

五、問題

1、 為什麼建立連線協議是三次握手,而關閉連線卻是四次握手呢?

這是因為服務端在listen狀態下的socket當收到syn報文的建連請求後,它可以把ack和syn(ack起應答作用,而syn起同步作用)放在乙個報文裡來傳送。但關閉連線時,當收到對方的fin報文通知時,它僅僅表示對方沒有資料傳送給你了;但未必你所有的資料都全部傳送給對方了,所以你可以未必會馬上會關閉socket,也即你可能還需要傳送一些資料給對方之後,再傳送fin報文給對方來表示你同意現在可以關閉連線了,所以它這裡的ack報文和fin報文多數情況下都是分開傳送的。

2、 為什麼time_wait狀態還需要等2msl後才能返回到closed狀態?

這是因為雖然雙方都同意關閉連線了,而且握手的4個報文也都協調和傳送完畢,按理可以直接回到closed狀態(就好比從syn_send狀態到establish狀態那樣);但是因為我們必須要假想網路是不可靠的,你無法保證你最後傳送的ack報文會一定被對方收到,因此對方處於last_ack狀態下的socket可能會因為超時未收到ack報文,而重發fin報文,所以這個time_wait狀態的作用就是用來重發可能丟失的ack報文。

TCP有限狀態機

狀 態 描 述 closed 關閉狀態,沒有連線活動或正在進行 listen 監聽狀態,伺服器正在等待連線進入 syn rcvd 收到乙個連線請求,尚未確認 syn sent 已經發出連線請求,等待確認 established 連線建立,正常資料傳輸狀態 fin wait 1 主動關閉 已經傳送關閉...

TCP有限狀態機

4 有限狀態機 上圖是 tcp 的狀態機,看了很久,感覺還是理解得不深。先在這裡打個點。1 closed 狀態時初始狀態。2 listen 被動開啟,伺服器端的 狀態變為listen 監聽 被動開啟的概念 連線的一端的應用程式通知作業系統,希望建立乙個傳入的連線。這時候作業系統為連線的這一端建立乙個...

有限狀態機

有限狀態機 finite state machine,fsm 又稱有限狀態自動機,簡稱狀態機,是表示有限個狀態以及在這些狀態之間的轉移和動作等行為的數學模型。狀態儲存關於過去的資訊,就是說 它反映從系統開始到現在時刻的輸入變化。轉移指示狀態變更,並且用必須滿足來確使轉移發生的條件來描述它。動作是在給...