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


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