TCP的狀態變遷及RST報文段產生與處理

2021-06-19 15:28:01 字數 1727 閱讀 7285

close:                socket的初始狀態,沒有進行任何操作(connect, listen)之前的狀態

listen:               可以接受syn的狀態,伺服器等待連線

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

syn_sent:            發出連線請求,等待確認

establised:      連線建立成功,可以進行資料通訊 

close_wait:       對方已關閉連線,等待本地使用者關閉

fin_wait_1:         應用程式關閉連線

fin_wait_2:         對方已經知道本端不會再傳送資料

closing:              對待對方的連線終止請求確認

time_wait:          雙方都嘗試關閉連線,等待一段時間,以防止ack丟失

last_ack:         等待對方確認關閉連線

同步狀態:established, fin_wait_1, fin_wait_2, close_wait, closing, last_ack, time_wait

非同步狀態:listen,syn_received, syn_sent

從listen到syn_sent的變遷是正確的,但伯克利的tcp軟體並不支援它。這裡也沒有畫出。

從程式開發者的角度來看rst的產生和rst的處理

向不存在的埠發起連線

一些延遲的包導致連線無法正常建立,例如乙個舊的syn副本

程式異常終止(依賴於系統,有的會傳送fin, 有的傳送rst)

設定了so_linger選項支援異常關閉,並呼叫close

已關閉的埠(呼叫close)收到資料

核心對rst的處理由下面這個函式完成

/* when we get a reset we do this. */

void

tcp_reset  (

struct

sock  *

sk  ) 

/* this barrier is coupled with smp_rmb() in tcp_poll() */

smp_wmb();

if(!sock_flag(

sk , sock_dead))

sk->sk_error_report(

sk );tcp_done(

sk);}

對rst的處理結果最終要反應給上層應用。通過設定errno告訴上層tcp的當前狀態。對於與tcp_reset函式

我們可以得到如下的處理流程圖

即,如果在建立連線的過程中收到rst,上層得到的錯誤就是econnrefused,一般就是connect返回失敗,errno

的值被設定為econnrefused。

如果對方已經關閉連線(呼叫了close, 本端處於close_wait狀態),繼續呼叫send傳送資料,就會收到rst,這種情況

下設定錯誤號為epipe。

其它情況下,收到rst,都設定錯誤號為econnreset

掉用close函式的tcp會進入close狀態,呼叫shutdown可能進入fin_wait_2狀態。

TCP產生復位報文段RST的三種情況

在某些特殊情況下,tcp連線的一端會向另一端傳送攜帶rts標誌的報文段,即復位報文段,以通知對方關閉連線或重新建立連線。訪問不存在的埠 當客戶端程式訪問乙個不存在的埠時,目標主機將給他傳送乙個復位報文段。異常終止連線 tcp提供了異常終止連線的方法,即給對方傳送乙個復位報文段。一旦傳送了復位報文段,...

TCP報文段的首部格式

源埠 目的埠 序號確認號 資料偏移 保留urg ackpsh rstsyn fin視窗 校驗和緊急指標 選項 長度可變 填充tcp報文段首部的前20個位元組是固定,後面有4n位元組是根據需要而增加的選項,因此tcp首部最小長度20位元組。1.源埠和目的埠 各佔2個位元組,分別寫入源埠號和目的埠號。埠...

在TCP傳輸中,什麼時候會收到RST報文段?

rst即復位字段。1.連線請求到達時,目的埠不存在。2.向乙個已經關閉的連線傳送資料。3.向乙個已經崩潰的對端傳送資料。4.請求超時。接收端在接收資料超時時,會傳送rst包。5.關閉socket時,直接丟棄接收緩衝區未讀取的資料,並給對方發乙個rst。6.tcp收到了乙個根本不存在的連線上的報文。7...