第一次握手:建立連接時,客戶端發送syn包和一個隨機序列號seq=x到服務器,并進入SYN_SEND狀態,等待服務器進行確認。(syn,同 步序列編號)。第二次握手,服務器收到syn包,必須確認客戶的SYN,然后服務器發送一個ACK=1, SYN=1, seq=y的隨機數和ack=x+1的確認數的包發送回去。第三次握手是客戶端收到服務器端的SYN+ACK包,然后向服務器端發送確認包 ack=y+1, seq=x+1, ACK=1,客戶端和服務器端進入ESTABLISHED狀態,完成三次握手。具體圖示如下:


這里多說一點,既然提到了連接時的三次握手,就順便把斷開連接時的四次揮手也復習一下。首先客戶端主動發送Fin=1,seq=u,它等于前面已傳 送過去的最后一個字節的序號加1.這是A進入FIN-WAIT-1狀態,等待B的確認。B收到連接后立即發出確認,確認號是ack=u+1,而這個報文段 自己的序號是v,等于B前面已傳送過的數據的最后一個字節的序號加1.然后B即進入CLOSE-WAIT狀態。因而A到B的這個鏈接現在已經斷開了,這時 的TCP連接處于半關閉狀態,即A已經沒有數據需要發送了。但B若發送數據,A還是要接受的。A收到來自B的確認之后就進入了FIN-WAIT-2狀態等 待B發出連接釋放報文段。若B已經沒有要向A發送數據,其應用進程就通知TCP釋放連接。這是B發出的連接釋放報文段必須使用FIN=1.現在假定B的序 號為w,B還必須重復上次已發送過的確認號ack=u+1.這時B就進入了LAST-ACK狀態,等待A確認。A在收到B的連接釋放之后必須對此發出確 認。在確認號中把ACK置1,確認號ack=w+1,而自己的序號是seq=u+1。接著A進入TIME-WAIT狀態。為了保證B可以收到確認釋放報文 段。如上圖:
是不是所有執行主動關閉的socket都會進入TIME_WAIT狀態呢?
有沒有什么情況使主動關閉的socket直接進入CLOSED狀態呢?
主動關閉的一方在發送最后一個 ack 后
就會進入 TIME_WAIT 狀態 停留2MSL(max segment lifetime)時間
這個是TCP/IP必不可少的,也就是“解決”不了的。
也就是TCP/IP設計者本來是這么設計的
主要有兩個原因
1。防止上一次連接中的包,迷路后重新出現,影響新連接
(經過2MSL,上一次連接中所有的重復包都會消失)
2。可靠的關閉TCP連接
在主動關閉方發送的最后一個 ack(fin) ,有可能丟失,這時被動方會重新發
fin, 如果這時主動方處于 CLOSED 狀態 ,就會響應 rst 而不是 ack。所以
主動方要處于 TIME_WAIT 狀態,而不能是 CLOSED 。