Tcp在出現任何異常時候,會採用reset報文「復位」。RST報文的tcp頭裡RST標誌置位。
發送RST報文的場景包括以下幾種
1、 請求的tcp埠不存在
2、 協議棧任何異常
Tcp請求的埠不存在
對於udp,如果報文請求一個不存在的埠,將產生一個icmp報文通知埠不可達『
對於tcp報文,當請求一個不存在的埠,將會rst復位這個連結』
連結出現異常後
正常連結關閉,是通過fin方法「文雅」的方式關閉。Fin關閉所有數據已經發送完畢,沒有數據丟失。
使用rst關閉,一般出現異常情況了,這種關閉中途釋放連結,稱為異常關閉。
Rst關閉連結的特點:
1、 發送RST的一方,將丟棄任何待發送數據,立刻釋放連結。
2、 收到RST的連結將進入關閉狀態,不會回應任何響應
3、 收到RST後,協議棧通知應用程式api處理。
API 通過 "linger on close" 選項(即 SO_LINGER)提供了這種異常關閉的能力
Tcp狀態機裡的任何狀態收到RST都會關閉,但是Time_wait狀態收到RST報文,RFC 1337 提另一種方式,不關心這個RST,避免過早關閉。
協議棧在任何時間,覺得狀態不對或者莫名原因下,都會發送rst狀態。
比如,以前曾做一個項目,tcp報文被中間代理插入新數據,這樣tcp兩端發現序列號和ACK對應不起來,經過一番ack確認後,tcp協議棧發現序列號始終是錯誤的,就會RST復位連結。
半打開狀態
半打開連接是指,已經建鏈的連接,一端重啟,對方不知道,這種情況稱為半打開
比如工作中telnet場景,上班期間客戶端telnet伺服器,下班後客戶端關機後,如果伺服器不和客戶端發送數據,伺服器將不知道客戶端已經關閉。第二天上班客戶端重新telnet,那麼伺服器上將會有很多這種半打開的連結。這種情況,Tcp通過保活機制檢測對方是否正常工作。
比如,AB兩個協議棧正常建立了連結,A向B發送了FIN包要求關連接,B發送ACK後,這時網絡斷了,然後A重啟了。重啟後,網通了後,B又開始發數據包,A收到後就不知道這個(數據的)連接哪來的,A就會發RST包強制把連接關了。