??TCP(傳輸控制協(xié)議)是一種面向連接液兽,確保數(shù)據(jù)在端到端之間可靠傳輸?shù)膮f(xié)議,面向連接指的是在發(fā)送數(shù)據(jù)前,需要先建立一條虛擬的鏈路揪罕,然后讓數(shù)據(jù)在這條鏈路上傳輸梯码,為了確保數(shù)據(jù)的可靠傳輸,不僅需要對(duì)發(fā)出的每個(gè)字節(jié)進(jìn)行編號(hào)確認(rèn)好啰,檢驗(yàn)每一個(gè)數(shù)據(jù)包的有效性轩娶,在出現(xiàn)超時(shí)情況時(shí)進(jìn)行重傳,還需要通過實(shí)現(xiàn)滑動(dòng)窗口和擁塞控制機(jī)制框往,避免網(wǎng)絡(luò)情況惡化而最終影響數(shù)據(jù)傳輸?shù)臉O端情形鳄抒,每個(gè)TCP數(shù)據(jù)包都是封裝在IP包中。每一個(gè)IP頭的后面緊接著是TCP頭椰弊,TCP報(bào)文格式如下:
三次握手
??協(xié)議第一行的兩個(gè)端口號(hào)各占兩個(gè)字節(jié)许溅,分別表示了源機(jī)器的端口號(hào)和目標(biāo)機(jī)器的端口號(hào)。這個(gè)兩個(gè)端口號(hào)和IP報(bào)頭中的源IP地址和目標(biāo)IP地址所組成的四元組可唯一標(biāo)示一條TCP連接秉版,由于TCP是面向連接的贤重,因此有服務(wù)端和客戶端之分。需要服務(wù)端先在相應(yīng)的端口進(jìn)行監(jiān)聽清焕,準(zhǔn)備好接受客戶端發(fā)起的建立連接請(qǐng)求并蝗。當(dāng)客戶端發(fā)起第一個(gè)請(qǐng)求建立連接的TCP報(bào)時(shí),目標(biāo)機(jī)器端口就是服務(wù)端所監(jiān)聽的端口號(hào)秸妥,比如代表HTTP服務(wù)的80端口滚停,代表SSH服務(wù)的22端口,代表HTTPS服務(wù)的443端口粥惧。
??TCP的FLAG位由6個(gè)bit組成铐刘,分別代表ACK,SYN,FIN,URG,PSH,RST,都以置1表示有效,我們重點(diǎn)關(guān)注SYN,ACK和FIN影晓。SYN(Synchronize Sequence Numbers)用作建立連接時(shí)的同步信號(hào)镰吵,ACK(Acknowledgement)用于對(duì)收到的數(shù)據(jù)進(jìn)行確認(rèn),所確認(rèn)的數(shù)據(jù)由確認(rèn)序列號(hào)表示挂签,F(xiàn)IN(finish)表示后面沒有數(shù)據(jù)需要發(fā)送疤祭,通常意味著所建立的連接需要關(guān)閉了。
- A機(jī)器發(fā)出一個(gè)數(shù)據(jù)包并將SYN置1饵婆,表示希望建立連接勺馆,包序列號(hào)假設(shè)為x。
- B機(jī)器收到A機(jī)器發(fā)送過來的數(shù)據(jù)包后侨核,通過SYN得知這是一個(gè)建立連接的請(qǐng)求草穆,于是發(fā)送一個(gè)響應(yīng)包并將SYN和ACK標(biāo)記都置1,假設(shè)這個(gè)包的序列號(hào)是y,而確認(rèn)序列號(hào)必須是x+1搓译,表示收到了A收到了A發(fā)送過來的SYN悲柱。在TCP中,SYN被當(dāng)作數(shù)據(jù)部分的一個(gè)字節(jié)些己。
-A收到B的響應(yīng)包后需要進(jìn)行確認(rèn)豌鸡,確認(rèn)包中將ACK置1嘿般,并將確認(rèn)序列號(hào)設(shè)置為y+1,表示收到了來自B的SYN。
這里為什么需要三次握手涯冠?主要有兩個(gè)目的炉奴,信息對(duì)等和防止超時(shí)。先從信息對(duì)等角度來看蛇更,雙方需要互相確認(rèn)自己的發(fā)報(bào)能力瞻赶,自己的收?qǐng)?bào)能力,對(duì)方的發(fā)報(bào)能力派任,對(duì)方的收?qǐng)?bào)能力共耍。
連接三次握手也是防止出現(xiàn)請(qǐng)求超時(shí)導(dǎo)致臟連接,TTL網(wǎng)絡(luò)報(bào)文的生存時(shí)間往往都會(huì)超過TCP請(qǐng)求超時(shí)時(shí)間吨瞎,如果兩次握手都可以創(chuàng)建連接,傳輸數(shù)據(jù)并釋放連接后穆咐,第一個(gè)超時(shí)的連接請(qǐng)求才到達(dá)B機(jī)器的話颤诀,B機(jī)器會(huì)以為是A創(chuàng)建的新連接的請(qǐng)求,然后確認(rèn)同意創(chuàng)建連接对湃。因?yàn)锳機(jī)器的狀態(tài)不是SYN_SENT,所以直接丟棄了B的確認(rèn)數(shù)據(jù)崖叫,以致最后只是B機(jī)器單方面創(chuàng)建連接完畢。
如果是三次握手拍柒,則B機(jī)器收到連接請(qǐng)求后心傀,同樣會(huì)向A機(jī)器確認(rèn)連接,但因?yàn)锳機(jī)器不是SYN_SENT狀態(tài)拆讯,所以會(huì)直接丟棄脂男,B機(jī)器由于長時(shí)間沒有收到確認(rèn)消息,最終超時(shí)導(dǎo)致連接創(chuàng)建失敗种呐,因而不會(huì)出現(xiàn)臟連接宰翅。
TCP 斷開連接
??TCP是全雙工通信,雙方都能作為數(shù)據(jù)的發(fā)送和接收方爽室,但TCP連接也會(huì)有斷開的時(shí)候汁讼,所謂相愛容易分手難,建立連接只有三次阔墩,而揮手?jǐn)嚅_需要四次嘿架。A機(jī)器想要關(guān)閉連接,則待本方數(shù)據(jù)發(fā)送完畢后啸箫,傳遞FIN信號(hào)給B機(jī)器耸彪。B機(jī)器應(yīng)答ACK,告訴A機(jī)器可以斷開,但是需要等B機(jī)器處理完數(shù)據(jù)忘苛,再主動(dòng)給A機(jī)器發(fā)送FIN信號(hào)搜囱。這時(shí)丑瞧,A機(jī)器處于半關(guān)閉狀態(tài)(FIN_WAIT_2)液样,無法再發(fā)送新的數(shù)據(jù)倦春,B機(jī)器做好連接關(guān)閉前的準(zhǔn)備工作后线婚,發(fā)送FIN給A機(jī)器辕狰,此時(shí)B機(jī)器也進(jìn)入半關(guān)閉狀態(tài)(CLOSE_WAIT)勉抓。A機(jī)器發(fā)送針對(duì)B機(jī)器FIN的ACK后蚯妇,進(jìn)入TIME_WAIT狀態(tài)侣集,經(jīng)過2MSL(Maximum Segment Lifetime)后简僧,沒有收到B機(jī)器傳來的報(bào)文坛增,則確定B機(jī)器已經(jīng)收到A機(jī)器最后發(fā)送的ACK指令获雕,此時(shí)TCP連接正式釋放。
四次揮手?jǐn)嚅_連接可以用通俗的說法
??男生 :我們分手吧收捣。
??女生:好届案,我的東西收拾完,發(fā)信息給你罢艾。(此時(shí)男生不能抱女生了)
??(1小時(shí)后)
??女生:我收拾好了楣颠,分手吧。(此時(shí)女生不能抱男生了)
??男生:好的咐蚯。(大家約定兩個(gè)月的過渡期童漩,雙方才可以分別找新的對(duì)象)
- TIME_WAIT:主動(dòng)要求關(guān)閉的機(jī)器表示收到對(duì)方的FIN報(bào)文,并發(fā)送方ACK報(bào)文春锋,進(jìn)入TIME_WAIT狀態(tài)矫膨,等2MSL后即可進(jìn)入CLOSED狀態(tài)。如果FIN_WAIT_1狀態(tài)下期奔,同時(shí)收到帶FIN標(biāo)志和ACK標(biāo)志的報(bào)文時(shí)侧馅,可以直接進(jìn)入TIME_WAIT狀態(tài),而無需進(jìn)入FIN_WAIT_2狀態(tài)呐萌。
- CLOSE_WAIT:被動(dòng)要求關(guān)閉的機(jī)器收到對(duì)方請(qǐng)求連接的FIN報(bào)文施禾,在第一次ACK應(yīng)答后,馬上進(jìn)入CLOSE_WAIT狀態(tài)搁胆,這種狀態(tài)其實(shí)表示在等待關(guān)閉弥搞,并且通知應(yīng)用程序發(fā)送剩余的數(shù)據(jù),處理現(xiàn)場(chǎng)信息渠旁。關(guān)閉相關(guān)資源攀例。
- 2MSL是報(bào)文在網(wǎng)絡(luò)中生存的最長時(shí)間,超過閥值便將報(bào)文丟棄顾腊。