??TCP(傳輸控制協(xié)議)是一種面向連接,確保數(shù)據(jù)在端到端之間可靠傳輸?shù)膮f(xié)議,面向連接指的是在發(fā)送數(shù)據(jù)前,需要先建立一條虛擬的鏈路,然后讓數(shù)據(jù)在這條鏈路上傳輸,為了確保數(shù)據(jù)的可靠傳輸,不僅需要對發(fā)出的每個字節(jié)進行編號確認,檢驗每一個數(shù)據(jù)包的有效性,在出現(xiàn)超時情況時進行重傳,還需要通過實現(xiàn)滑動窗口和擁塞控制機制,避免網(wǎng)絡情況惡化而最終影響數(shù)據(jù)傳輸?shù)臉O端情形,每個TCP數(shù)據(jù)包都是封裝在IP包中。每一個IP頭的后面緊接著是TCP頭,TCP報文格式如下:

三次握手
??協(xié)議第一行的兩個端口號各占兩個字節(jié),分別表示了源機器的端口號和目標機器的端口號。這個兩個端口號和IP報頭中的源IP地址和目標IP地址所組成的四元組可唯一標示一條TCP連接,由于TCP是面向連接的,因此有服務端和客戶端之分。需要服務端先在相應的端口進行監(jiān)聽,準備好接受客戶端發(fā)起的建立連接請求。當客戶端發(fā)起第一個請求建立連接的TCP報時,目標機器端口就是服務端所監(jiān)聽的端口號,比如代表HTTP服務的80端口,代表SSH服務的22端口,代表HTTPS服務的443端口。
??TCP的FLAG位由6個bit組成,分別代表ACK,SYN,FIN,URG,PSH,RST,都以置1表示有效,我們重點關注SYN,ACK和FIN。SYN(Synchronize Sequence Numbers)用作建立連接時的同步信號,ACK(Acknowledgement)用于對收到的數(shù)據(jù)進行確認,所確認的數(shù)據(jù)由確認序列號表示,F(xiàn)IN(finish)表示后面沒有數(shù)據(jù)需要發(fā)送,通常意味著所建立的連接需要關閉了。

- A機器發(fā)出一個數(shù)據(jù)包并將SYN置1,表示希望建立連接,包序列號假設為x。
- B機器收到A機器發(fā)送過來的數(shù)據(jù)包后,通過SYN得知這是一個建立連接的請求,于是發(fā)送一個響應包并將SYN和ACK標記都置1,假設這個包的序列號是y,而確認序列號必須是x+1,表示收到了A收到了A發(fā)送過來的SYN。在TCP中,SYN被當作數(shù)據(jù)部分的一個字節(jié)。
-A收到B的響應包后需要進行確認,確認包中將ACK置1,并將確認序列號設置為y+1,表示收到了來自B的SYN。
這里為什么需要三次握手?主要有兩個目的,信息對等和防止超時。先從信息對等角度來看,雙方需要互相確認自己的發(fā)報能力,自己的收報能力,對方的發(fā)報能力,對方的收報能力。

連接三次握手也是防止出現(xiàn)請求超時導致臟連接,TTL網(wǎng)絡報文的生存時間往往都會超過TCP請求超時時間,如果兩次握手都可以創(chuàng)建連接,傳輸數(shù)據(jù)并釋放連接后,第一個超時的連接請求才到達B機器的話,B機器會以為是A創(chuàng)建的新連接的請求,然后確認同意創(chuàng)建連接。因為A機器的狀態(tài)不是SYN_SENT,所以直接丟棄了B的確認數(shù)據(jù),以致最后只是B機器單方面創(chuàng)建連接完畢。

如果是三次握手,則B機器收到連接請求后,同樣會向A機器確認連接,但因為A機器不是SYN_SENT狀態(tài),所以會直接丟棄,B機器由于長時間沒有收到確認消息,最終超時導致連接創(chuàng)建失敗,因而不會出現(xiàn)臟連接。
TCP 斷開連接
??TCP是全雙工通信,雙方都能作為數(shù)據(jù)的發(fā)送和接收方,但TCP連接也會有斷開的時候,所謂相愛容易分手難,建立連接只有三次,而揮手斷開需要四次。A機器想要關閉連接,則待本方數(shù)據(jù)發(fā)送完畢后,傳遞FIN信號給B機器。B機器應答ACK,告訴A機器可以斷開,但是需要等B機器處理完數(shù)據(jù),再主動給A機器發(fā)送FIN信號。這時,A機器處于半關閉狀態(tài)(FIN_WAIT_2),無法再發(fā)送新的數(shù)據(jù),B機器做好連接關閉前的準備工作后,發(fā)送FIN給A機器,此時B機器也進入半關閉狀態(tài)(CLOSE_WAIT)。A機器發(fā)送針對B機器FIN的ACK后,進入TIME_WAIT狀態(tài),經(jīng)過2MSL(Maximum Segment Lifetime)后,沒有收到B機器傳來的報文,則確定B機器已經(jīng)收到A機器最后發(fā)送的ACK指令,此時TCP連接正式釋放。

四次揮手斷開連接可以用通俗的說法
??男生 :我們分手吧。
??女生:好,我的東西收拾完,發(fā)信息給你。(此時男生不能抱女生了)
??(1小時后)
??女生:我收拾好了,分手吧。(此時女生不能抱男生了)
??男生:好的。(大家約定兩個月的過渡期,雙方才可以分別找新的對象)
- TIME_WAIT:主動要求關閉的機器表示收到對方的FIN報文,并發(fā)送方ACK報文,進入TIME_WAIT狀態(tài),等2MSL后即可進入CLOSED狀態(tài)。如果FIN_WAIT_1狀態(tài)下,同時收到帶FIN標志和ACK標志的報文時,可以直接進入TIME_WAIT狀態(tài),而無需進入FIN_WAIT_2狀態(tài)。
- CLOSE_WAIT:被動要求關閉的機器收到對方請求連接的FIN報文,在第一次ACK應答后,馬上進入CLOSE_WAIT狀態(tài),這種狀態(tài)其實表示在等待關閉,并且通知應用程序發(fā)送剩余的數(shù)據(jù),處理現(xiàn)場信息。關閉相關資源。
- 2MSL是報文在網(wǎng)絡中生存的最長時間,超過閥值便將報文丟棄。