在前面的內容中咱們介紹了TCP鏈接管理中最多見的三次握手方式和四次揮手的方式。可是有可能A和B兩端同時執行主動打開並鏈接對方或者同時執行主動關閉鏈接(儘管發生這種狀況的可能性比較低低),這個時候的流程就略有不一樣了。下面咱們分別對同時打開(simultaneous open)鏈接和同時關閉(simultaneous)鏈接這兩種狀況分別進行介紹。linux
1、同時打開鏈接併發
同時打開鏈接是指通訊的雙方在接收到對方的SYN包以前,都進行了主動打開的操做併發出了本身的SYN包。如以前所說一個四元組標識一個TCP鏈接,所以若是一個TCP鏈接要同時打開須要通訊的雙方知曉對方的IP和端口信息才行,這種場景在實際狀況中不多發生(NAT穿透中可能會多一些)。同時打開的流程以下圖
tcp
具體流程咱們不在逐條消息進行介紹。注意上圖中,TCP鏈接同時打開的時候與三次握手的主要區別以下spa
2、同時關閉鏈接3d
同時關閉相對於咱們講過的四次握手過程基本相似,注意二者狀態轉換的區別,同時關閉是由ESTABLISHED->FIN_WAIT_1->CLOSING->TIME_WAIT->CLOSED。同時關閉的流程以下,不在作額外的講解。
orm
3、示例blog
1.tcp同開
因爲linux實現不支持TCP同時主動打開鏈接,所以咱們拿RFC793中的示意圖來舉例ip
TCP A TCP B 1. CLOSED CLOSED 2. SYN-SENT --> <SEQ=100><CTL=SYN> ... 3. SYN-RECEIVED <-- <SEQ=300><CTL=SYN> <-- SYN-SENT 4. ... <SEQ=100><CTL=SYN> --> SYN-RECEIVED 5. SYN-RECEIVED --> <SEQ=100><ACK=301><CTL=SYN,ACK> ... 6. ESTABLISHED <-- <SEQ=300><ACK=101><CTL=SYN,ACK> <-- SYN-RECEIVED 7. ... <SEQ=101><ACK=301><CTL=ACK> --> ESTABLISHED Simultaneous Connection Synchronization RFC793對示意圖中的相關符號說明以下,你們對照下面的說明仔細觀察一下上面RFC的文字示例圖,有沒有發現什麼問題呢?(參看補充說明部分第2點)
Right arrows (-->) indicate departure of a TCP segment from TCP A to TCP B, or arrival of a segment at B from A. Left arrows (<--), indicate the reverse. Ellipsis (...) indicates a segment which is still in the network (delayed).
下面看一下wireshark實際抓包get
2.tcp同關it
linux自己也是支持TCP同時關閉鏈接的,wireshark抓包以下
3.tcp經過三次數據包交換關閉鏈接
還有一種場景是TCP經過三次數據包交換來關閉鏈接,這種場景一樣不多遇到,咱們不作過多介紹,以一個wireshark實例來看一下相關的系列號seq和ack number的關係
補充說明
一、RFC793給的同時打開TCP鏈接的示意圖中,TCP B進入ESTABLISHED狀態前收到的包應該是<SEQ=100><ACK=301><CTL=SYN,ACK>。想借此提醒不要僅僅看協議自己,還要記得看協議是否由對應的勘誤表(errata)。原始的RFC793協議有不少
二、本篇文章給出的同時關閉時的tcp包時序圖是與RFC793一致的,可是注意一些資料包括我所參考的第二版 tcpip詳解,給的同時關閉的示意圖中最後兩條消息的系列號seq是錯誤的,或者乾脆沒有給出系列號seq的值。