linux网络编程(二)TCP通讯状态
linux網(wǎng)絡(luò)編程(二)TCP通訊狀態(tài)
- TCP狀態(tài)轉(zhuǎn)換
- 為什么需要等待2MSL?
- 端口復(fù)用
TCP狀態(tài)轉(zhuǎn)換
tcp協(xié)議連接開(kāi)始會(huì)經(jīng)過(guò)三次握手,客戶(hù)端和服務(wù)器開(kāi)始都會(huì)處于CLOSED狀態(tài)
第一次握手:客戶(hù)端會(huì)先發(fā)送SYN請(qǐng)求給服務(wù)器,客戶(hù)端處于SYN_SET狀態(tài),
第二次握手:服務(wù)器接收到SYN后,發(fā)給客戶(hù)端ACK回答和SYN請(qǐng)求,服務(wù)器從LISTEN變成SYN_RCVD
第三次握手:客戶(hù)端接收到ACK和SYN請(qǐng)求后,發(fā)送給服務(wù)器ACK回應(yīng),客戶(hù)端從SYN_SET變成ESTABLISHED狀態(tài),服務(wù)器接收到ACK回應(yīng)后,也變?yōu)镋STABLISHED狀態(tài)
tcp協(xié)議關(guān)閉會(huì)經(jīng)過(guò)四次握手,假設(shè)客戶(hù)端為主動(dòng)關(guān)閉,服務(wù)器為被動(dòng)關(guān)閉
第一次握手:客戶(hù)端發(fā)送FIN請(qǐng)求,狀態(tài)變?yōu)镕IN_WAIT_1
第二次握手:服務(wù)器接收到FIN請(qǐng)求,同時(shí)發(fā)送ACK應(yīng)答,狀態(tài)為CLOSE_WAIT,客戶(hù)端收到ACK應(yīng)答后,變?yōu)镕IN_WAIT_2狀態(tài),此時(shí)處于半關(guān)閉的狀態(tài)
第三次握手:服務(wù)器發(fā)送FIN請(qǐng)求,狀態(tài)為L(zhǎng)ACK_ACK
第四次握手:客戶(hù)端接收到FIN請(qǐng)求后,發(fā)送ACK應(yīng)答,狀態(tài)變?yōu)門(mén)IME_WAIT,等待2MSL之后關(guān)閉
- CLOSED:表示初始狀態(tài)。
- LISTEN:該狀態(tài)表示服務(wù)器端的某個(gè)SOCKET處于監(jiān)聽(tīng)狀態(tài),可以接受連接。
- SYN_SENT:這個(gè)狀態(tài)與SYN_RCVD遙相呼應(yīng),當(dāng)客戶(hù)端SOCKET執(zhí)行CONNECT連接時(shí),它首先發(fā)送SYN報(bào)文,隨即進(jìn)入到了SYN_SENT狀態(tài),并等待服務(wù)端的發(fā)送三次握手中的第2個(gè)報(bào)文。SYN_SENT狀態(tài)表示客戶(hù)端已發(fā)送SYN報(bào)文。
- SYN_RCVD: 該狀態(tài)表示接收到SYN報(bào)文,在正常情況下,這個(gè)狀態(tài)是服務(wù)器端的SOCKET在建立TCP連接時(shí)的三次握手會(huì)話(huà)過(guò)程中的一個(gè)中間狀態(tài),很短暫。此種狀態(tài)時(shí),當(dāng)收到客戶(hù)端的ACK報(bào)文后,會(huì)進(jìn)入到ESTABLISHED狀態(tài)。
- ESTABLISHED:表示連接已經(jīng)建立。
- FIN_WAIT_1: FIN_WAIT_1和FIN_WAIT_2狀態(tài)的真正含義都是表示等待對(duì)方的FIN報(bào)文。區(qū)別是:FIN_WAIT_1狀態(tài)是當(dāng)socket在ESTABLISHED狀態(tài)時(shí),想主動(dòng)關(guān)閉連接,向?qū)Ψ桨l(fā)送了FIN報(bào)文,此時(shí)該socket進(jìn)入到FIN_WAIT_1狀態(tài)。
FIN_WAIT_2狀態(tài)是當(dāng)對(duì)方回應(yīng)ACK后,該socket進(jìn)入到FIN_WAIT_2狀態(tài),正常情況下,對(duì)方應(yīng)馬上回應(yīng)ACK報(bào)文,所以FIN_WAIT_1狀態(tài)一般較難見(jiàn)到,而FIN_WAIT_2狀態(tài)可用netstat看到。 - FIN_WAIT_2:主動(dòng)關(guān)閉鏈接的一方,發(fā)出FIN收到ACK以后進(jìn)入該狀態(tài)。稱(chēng)之為半連接或半關(guān)閉狀態(tài)。該狀態(tài)下的socket只能接收數(shù)據(jù),不能發(fā)。
- TIME_WAIT: 表示收到了對(duì)方的FIN報(bào)文,并發(fā)送出了ACK報(bào)文,等2MSL后即可回到CLOSED可用狀態(tài)。如果FIN_WAIT_1狀態(tài)下,收到對(duì)方同時(shí)帶
FIN標(biāo)志和ACK標(biāo)志的報(bào)文時(shí),可以直接進(jìn)入到TIME_WAIT狀態(tài),而無(wú)須經(jīng)過(guò)FIN_WAIT_2狀態(tài)。 - CLOSING: 這種狀態(tài)較特殊,屬于一種較罕見(jiàn)的狀態(tài)。正常情況下,當(dāng)你發(fā)送FIN報(bào)文后,按理來(lái)說(shuō)是應(yīng)該先收到(或同時(shí)收到)對(duì)方的 ACK報(bào)文,再收到對(duì)方的FIN報(bào)文。但是CLOSING狀態(tài)表示你發(fā)送FIN報(bào)文后,并沒(méi)有收到對(duì)方的ACK報(bào)文,反而卻也收到了對(duì)方的FIN報(bào)文。什么情況下會(huì)出現(xiàn)此種情況呢?如果雙方幾乎在同時(shí)close一個(gè)SOCKET的話(huà),那么就出現(xiàn)了雙方同時(shí)發(fā)送FIN報(bào)文的情況,也即會(huì)出現(xiàn)CLOSING狀態(tài),表示雙方都正在關(guān)閉SOCKET連接。
- CLOSE_WAIT: 此種狀態(tài)表示在等待關(guān)閉。當(dāng)對(duì)方關(guān)閉一個(gè)SOCKET后發(fā)送FIN報(bào)文給自己,系統(tǒng)會(huì)回應(yīng)一個(gè)ACK報(bào)文給對(duì)方,此時(shí)則進(jìn)入到CLOSE_WAIT狀態(tài)。接下來(lái)呢,察看是否還有數(shù)據(jù)發(fā)送給對(duì)方,如果沒(méi)有可以close這個(gè)SOCKET,發(fā)送FIN報(bào)文給對(duì)方,即關(guān)閉連接。所以在CLOSE_WAIT狀態(tài)下,需要關(guān)閉連接。
- LAST_ACK: 該狀態(tài)是被動(dòng)關(guān)閉一方在發(fā)送FIN報(bào)文后,最后等待對(duì)方的ACK報(bào)文。當(dāng)收到ACK報(bào)文后,即可以進(jìn)入到CLOSED可用狀態(tài)。
為什么需要等待2MSL?
當(dāng)客戶(hù)端也就是主動(dòng)關(guān)閉的一端,接收到服務(wù)器也就是被動(dòng)關(guān)閉的一端的FIN請(qǐng)求時(shí),需要回應(yīng)ACK回應(yīng),但是客戶(hù)端并不能保證ACK回應(yīng)服務(wù)器一定能收到,就添加了一個(gè)保護(hù)機(jī)制,在2MSL時(shí)間內(nèi),如果服務(wù)器沒(méi)有收到ACK回應(yīng),服務(wù)器會(huì)再一次發(fā)送FIN請(qǐng)求,知道能收到客戶(hù)端收到ACK回應(yīng)。服務(wù)器在2MSL之內(nèi)一直沒(méi)有收到的話(huà),客戶(hù)端將做超時(shí)處理,關(guān)閉失敗。
作用:
- 讓4次握手關(guān)閉流程更加可靠,4次握手的最后一個(gè)ACK是是由主動(dòng)關(guān)閉方發(fā)送出去的,若這個(gè)ACK丟失,被動(dòng)關(guān)閉方會(huì)再次發(fā)一個(gè)FIN過(guò)來(lái)。若主動(dòng)關(guān)閉方能夠保持一個(gè)2MSL的TIME_WAIT狀態(tài),則有更大的機(jī)會(huì)讓丟失的ACK被再次發(fā)送出去。
- 防止lost duplicate對(duì)后續(xù)新建正常鏈接的傳輸造成破壞。lost uplicate在實(shí)際的網(wǎng)絡(luò)中非常常見(jiàn),經(jīng)常是由于路由器產(chǎn)生故障,路徑無(wú)法收斂,導(dǎo)致一個(gè)packet在路由器A,B,C之間做類(lèi)似死循環(huán)的跳轉(zhuǎn)。IP頭部有個(gè)TTL,限制了一個(gè)包在網(wǎng)絡(luò)中的最大跳數(shù),因此這個(gè)包有兩種命運(yùn),要么最后TTL變?yōu)?,在網(wǎng)絡(luò)中消失;要么TTL在變?yōu)?之前路由器路徑收斂,它憑借剩余的TTL跳數(shù)終于到達(dá)目的地。但非常可惜的是TCP通過(guò)超時(shí)重傳機(jī)制在早些時(shí)候發(fā)送了一個(gè)跟它一模一樣的包,并先于它達(dá)到了目的地,因此它的命運(yùn)也就注定被TCP協(xié)議棧拋棄。
端口復(fù)用
在server的TCP連接沒(méi)有完全斷開(kāi)之前不允許重新監(jiān)聽(tīng)是不合理的
在server代碼的socket()和bind()調(diào)用之間插入如下代碼:
總結(jié)
以上是生活随笔為你收集整理的linux网络编程(二)TCP通讯状态的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 草根王剧情介绍
- 下一篇: linux网络编程(三)select、p