TCP协议——三次握手与四次关闭
1. TCP協(xié)議基礎(chǔ)
網(wǎng)絡(luò)編程基礎(chǔ)見(jiàn),傳送門(mén)
TCP是面向連接的,無(wú)論哪一方向另一方發(fā)送數(shù)據(jù)之前,都必須先在雙方之間建立一條連接。
在TCP/IP協(xié)議中,TCP協(xié)議提供可靠的連接服務(wù),連接是通過(guò)三次握手進(jìn)行初始化的。
三次握手的目的是同步連接雙方的序列號(hào)和確認(rèn)號(hào)并交換 TCP窗口大小信息。
TCP網(wǎng)絡(luò)傳輸示意圖:
2. 三次握手(3-Way Handshake)
-
第一次握手:建立連接。
客戶(hù)端發(fā)送連接請(qǐng)求報(bào)文段,將SYN位置為1,Sequence Number為x;然后,客戶(hù)端進(jìn)入SYN_SENT狀態(tài),等待服務(wù)器的確認(rèn); -
第二次握手:服務(wù)器收到SYN報(bào)文段。
服務(wù)器收到客戶(hù)端的SYN報(bào)文段,需要對(duì)這個(gè)SYN報(bào)文段進(jìn)行確認(rèn),設(shè)置Acknowledgment Number為x+1(Sequence Number+1);同時(shí),自己自己還要發(fā)送SYN請(qǐng)求信息,將SYN位置為1,Sequence Number為y;
服務(wù)器端將上述所有信息放到一個(gè)報(bào)文段(即SYN+ACK報(bào)文段)中,一并發(fā)送給客戶(hù)端,此時(shí)服務(wù)器進(jìn)入SYN_RECV狀態(tài); -
第三次握手:客戶(hù)端收到服務(wù)器的SYN+ACK報(bào)文段。然后將Acknowledgment Number設(shè)置為y+1,向服務(wù)器發(fā)送ACK報(bào)文段,這個(gè)報(bào)文段發(fā)送完畢以后,客戶(hù)端和服務(wù)器端都進(jìn)入ESTABLISHED狀態(tài),完成TCP三次握手。
完成了三次握手,客戶(hù)端和服務(wù)器端就可以開(kāi)始傳送數(shù)據(jù)。
問(wèn)題
- 1.為什么要三次握手?
既然總結(jié)了TCP的三次握手,那為什么非要三次呢?怎么覺(jué)得兩次就可以完成了。那TCP為什么非要進(jìn)行三次連接呢?在謝希仁的《計(jì)算機(jī)網(wǎng)絡(luò)》中是這樣說(shuō)的:為了防止已失效的連接請(qǐng)求報(bào)文段突然又傳送到了服務(wù)端,因而產(chǎn)生錯(cuò)誤。
在書(shū)中同時(shí)舉了一個(gè)例子,如下:
“已失效的連接請(qǐng)求報(bào)文段”的產(chǎn)生在這樣一種情況下:
client發(fā)出的第一個(gè)連接請(qǐng)求報(bào)文段并沒(méi)有丟失,而是在某個(gè)網(wǎng)絡(luò)結(jié)點(diǎn)長(zhǎng)時(shí)間的滯留了,以致延誤到連接釋放以后的某個(gè)時(shí)間才到達(dá)server。本來(lái)這是一個(gè)早已失效的報(bào)文段。但server收到此失效的連接請(qǐng)求報(bào)文段后,就誤認(rèn)為是client再次發(fā)出的一個(gè)新的連接請(qǐng)求。于是就向client發(fā)出確認(rèn)報(bào)文段,同意建立連接。
假設(shè)不采用“三次握手”,那么只要server發(fā)出確認(rèn),新的連接就建立了。由于現(xiàn)在client并沒(méi)有發(fā)出建立連接的請(qǐng)求,因此不會(huì)理睬server的確認(rèn),也不會(huì)向server發(fā)送數(shù)據(jù)。但server卻以為新的運(yùn)輸連接已經(jīng)建立,并一直等待client發(fā)來(lái)數(shù)據(jù)。這樣,server的很多資源就白白浪費(fèi)掉了。
采用“三次握手”的辦法可以防止上述現(xiàn)象發(fā)生。例如剛才那種情況,client不會(huì)向server的確認(rèn)發(fā)出確認(rèn)。server由于收不到確認(rèn),就知道client并沒(méi)有要求建立連接。”
防止了服務(wù)器端的一直等待而浪費(fèi)資源。
為什么是3次握手,不是2次握手?
start of a TCP conversation between Alice and Bob: Alice —> Bob
SYNchronize with my Initial Sequence Number of X Alice <— Bob I
received your syn, I ACKnowledge that I am ready for [X+1] Alice <—
Bob SYNchronize with my Initial Sequence Number of Y Alice —> Bob I
received your syn, I ACKnowledge that I am ready for [Y+1]
如果是2次握手,只能單向通信(1個(gè)發(fā)syn,一個(gè)ack),而事實(shí)上TCP是全雙工,雙方都需要建立ISN(Initial Sequence
Number ),彼此都需要知道對(duì)方的ISN
3次握手,邏輯上是4次握手,是有序的2次互通信
TCP connection is bidirectional. What this means is that it actually is a pair of one-way connections.The initiator sends SYN, the responder sends ACK: one simplex connection begins. “Then” the responder sends SYN, the initiator sends ACK: another simplex connection begins. Two simplex connections form one duplex TCP session So logically there are four steps involved; but because SYN and ACK flags are different “fields” of TCP header, they can be set simultaneously - the second and the third steps (of the four) are combined, so technically there are three packet exchanges. Each simplex (half-)connection uses 2-way exchange, as you proposed.Each client will perform an active OPEN and then proceed through both the SYN-SENT and SYN-RECEIVED states until their SYNs are acknowledged. This means there isn’t a “three-way handshake” any more as shown. Instead, it is like two simultaneous “two-way handshakes”. Each client sends a SYN, receives the other’s SYN and ACKs it, and then waits for its own ACK.2. 四次結(jié)束(4-Way Handshake)
當(dāng)客戶(hù)端和服務(wù)器通過(guò)三次握手建立了TCP連接以后,當(dāng)數(shù)據(jù)傳送完畢,肯定是要斷開(kāi)TCP連接的啊。那對(duì)于TCP的斷開(kāi)連接,這里就有了神秘的“四次分手”。
-
第一次分手:主機(jī)1(可以使客戶(hù)端,也可以是服務(wù)器端),設(shè)置Sequence Number和Acknowledgment Number,向主機(jī)2發(fā)送一個(gè)FIN報(bào)文段;此時(shí),主機(jī)1進(jìn)入FIN_WAIT_1狀態(tài);這表示主機(jī)1沒(méi)有數(shù)據(jù)要發(fā)送給主機(jī)2了;
-
第二次分手:主機(jī)2收到了主機(jī)1發(fā)送的FIN報(bào)文段,向主機(jī)1回一個(gè)ACK報(bào)文段,Acknowledgment Number為Sequence Number加1;主機(jī)1進(jìn)入FIN_WAIT_2狀態(tài);主機(jī)2告訴主機(jī)1,我“同意”你的關(guān)閉請(qǐng)求;
-
第三次分手:主機(jī)2向主機(jī)1發(fā)送FIN報(bào)文段,請(qǐng)求關(guān)閉連接,同時(shí)主機(jī)2進(jìn)入LAST_ACK狀態(tài);
-
第四次分手:主機(jī)1收到主機(jī)2發(fā)送的FIN報(bào)文段,向主機(jī)2發(fā)送ACK報(bào)文段,然后主機(jī)1進(jìn)入TIME_WAIT狀態(tài);主機(jī)2收到主機(jī)1的ACK報(bào)文段以后,就關(guān)閉連接;此時(shí),主機(jī)1等待2MSL后依然沒(méi)有收到回復(fù),則證明Server端已正常關(guān)閉,那好,主機(jī)1也可以關(guān)閉連接了。
至此,TCP的四次分手就這么愉快的完成了。
為什么要四次分手?
TCP協(xié)議是一種面向連接的、可靠的、基于字節(jié)流的運(yùn)輸層通信協(xié)議。
TCP是全雙工模式,這就意味著,
當(dāng)主機(jī)1發(fā)出FIN報(bào)文段時(shí),只是表示主機(jī)1已經(jīng)沒(méi)有數(shù)據(jù)要發(fā)送了,主機(jī)1告訴主機(jī)2,它的數(shù)據(jù)已經(jīng)全部發(fā)送完畢了;但是,這個(gè)時(shí)候主機(jī)1還是可以接受來(lái)自主機(jī)2的數(shù)據(jù);
當(dāng)主機(jī)2返回ACK報(bào)文段時(shí),表示它已經(jīng)知道主機(jī)1沒(méi)有數(shù)據(jù)發(fā)送了,但是主機(jī)2還是可以發(fā)送數(shù)據(jù)到主機(jī)1的;
當(dāng)主機(jī)2也發(fā)送了FIN報(bào)文段時(shí),這個(gè)時(shí)候就表示主機(jī)2也沒(méi)有數(shù)據(jù)要發(fā)送了,就會(huì)告訴主機(jī)1,我也沒(méi)有數(shù)據(jù)要發(fā)送了,之后彼此就會(huì)愉快的中斷這次TCP連接。
如果要正確的理解四次分手的原理,就需要了解四次分手過(guò)程中的狀態(tài)變化。
-
FIN_WAIT_1: 這個(gè)狀態(tài)要好好解釋一下,其實(shí)FIN_WAIT_1和FIN_WAIT_2狀態(tài)的真正含義都是表示等待對(duì)方的FIN報(bào)文。而這兩種狀態(tài)的區(qū)別是:FIN_WAIT_1狀態(tài)實(shí)際上是當(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)。而當(dāng)對(duì)方回應(yīng)ACK報(bào)文后,則進(jìn)入到FIN_WAIT_2狀態(tài),當(dāng)然在實(shí)際的正常情況下,無(wú)論對(duì)方何種情況下,都應(yīng)該馬上回應(yīng)ACK報(bào)文,所以FIN_WAIT_1狀態(tài)一般是比較難見(jiàn)到的,而FIN_WAIT_2狀態(tài)還有時(shí)常常可以用netstat看到。(主動(dòng)方)
-
FIN_WAIT_2:上面已經(jīng)詳細(xì)解釋了這種狀態(tài),實(shí)際上FIN_WAIT_2狀態(tài)下的SOCKET,表示半連接,也即有一方要求close連接,但另外還告訴對(duì)方,我暫時(shí)還有點(diǎn)數(shù)據(jù)需要傳送給你(ACK信息),稍后再關(guān)閉連接。(主動(dòng)方)
-
CLOSE_WAIT:這種狀態(tài)的含義其實(shí)是表示在等待關(guān)閉。怎么理解呢?當(dāng)對(duì)方close一個(gè)SOCKET后發(fā)送FIN報(bào)文給自己,你系統(tǒng)毫無(wú)疑問(wèn)地會(huì)回應(yīng)一個(gè)ACK報(bào)文給對(duì)方,此時(shí)則進(jìn)入到CLOSE_WAIT狀態(tài)。接下來(lái)呢,實(shí)際上你真正需要考慮的事情是察看你是否還有數(shù)據(jù)發(fā)送給對(duì)方,如果沒(méi)有的話,那么你也就可以 close這個(gè)SOCKET,發(fā)送FIN報(bào)文給對(duì)方,也即關(guān)閉連接。所以你在CLOSE_WAIT狀態(tài)下,需要完成的事情是等待你去關(guān)閉連接。(被動(dòng)方)
-
LAST_ACK: 這個(gè)狀態(tài)還是比較容易好理解的,它是被動(dòng)關(guān)閉一方在發(fā)送FIN報(bào)文后,最后等待對(duì)方的ACK報(bào)文。當(dāng)收到ACK報(bào)文后,也即可以進(jìn)入到CLOSED可用狀態(tài)了。(被動(dòng)方)
-
TIME_WAIT: 表示收到了對(duì)方的FIN報(bào)文,并發(fā)送出了ACK報(bào)文,就等2MSL后即可回到CLOSED可用狀態(tài)了。如果FINWAIT1狀態(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)。(主動(dòng)方)
-
CLOSED: 表示連接中斷。
總結(jié)
以上是生活随笔為你收集整理的TCP协议——三次握手与四次关闭的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 网络编程——常用协议解析
- 下一篇: TCP协议——流量控制和拥塞控制