一掉冶、TCP報(bào)文格式
TCP/IP協(xié)議的詳細(xì)信息參看《TCP/IP協(xié)議詳解》三卷本真竖。下面是TCP報(bào)文格式圖:
TCP報(bào)文格式上圖中有幾個(gè)字段需要重點(diǎn)介紹下:
- (1)序號(hào):Seq序號(hào),占32位厌小,用來(lái)標(biāo)識(shí)從TCP源端向目的端發(fā)送的字節(jié)流恢共,發(fā)起方發(fā)送數(shù)據(jù)時(shí)對(duì)此進(jìn)行標(biāo)記。
- (2)確認(rèn)序號(hào):Ack序號(hào)召锈,占32位,只有ACK標(biāo)志位為1時(shí)拐袜,確認(rèn)序號(hào)字段才有效蹬铺,Ack=Seq+1秉撇。
- (3)標(biāo)志位:共6個(gè),即URG规阀、ACK瘦麸、PSH、RST厉碟、SYN箍鼓、FIN等呵曹,具體含義如下:
- (A)URG:緊急指針(urgent pointer)有效。
- (B)ACK:確認(rèn)序號(hào)有效之剧。
- (C)PSH:接收方應(yīng)該盡快將這個(gè)報(bào)文交給應(yīng)用層砍聊。
- (D)RST:重置連接。
- (E)SYN:發(fā)起一個(gè)新連接蟹肘。
- (F)FIN:釋放一個(gè)連接。
需要注意的是:
- (A)標(biāo)志位中的ACK贰盗、與確認(rèn)序號(hào)Ack是不同的阳欲;
- (B)確認(rèn)序號(hào)Ack=發(fā)起方Seq+1 兩端配對(duì);
三次握手(three times handshake)即建立TCP連接秽晚,就是指建立一個(gè)TCP連接時(shí)赴蝇,需要客戶(hù)端和服務(wù)端總共發(fā)送3個(gè)包用來(lái)客戶(hù)端與服務(wù)端TCP連接的建立巢掺;
二、三次握手過(guò)程
(1)第一次握手:Client將標(biāo)志位SYN置為1考余,隨機(jī)產(chǎn)生一個(gè)值seq=X楚堤,并將該數(shù)據(jù)包發(fā)送給Server浸剩,Client進(jìn)入SYN_SENT狀態(tài)鳄袍,等待Server確認(rèn)。
(2)第二次握手:Server收到數(shù)據(jù)包后由標(biāo)志位SYN=1知道Client請(qǐng)求建立連接重罪,Server將標(biāo)志位SYN和ACK都置為1哀九,ack numbern=X+1阅束,隨機(jī)產(chǎn)生一個(gè)值seq=Y,并將該數(shù)據(jù)包發(fā)送給Client以確認(rèn)連接請(qǐng)求蝇更,Server進(jìn)入SYN_RCVD狀態(tài)。
(3)第三次握手:Client收到確認(rèn)后年扩,檢查ack number是否為X+1,ACK是否為1相嵌,如果正確則將標(biāo)志位ACK置為1况脆,ack=Y+1漠另,并將該數(shù)據(jù)包發(fā)送給Server,Server檢查ack是否為Y+1性湿,ACK是否為1满败,如果正確則連接建立成功,Client和Server進(jìn)入ESTABLISHED狀態(tài)宵荒,完成三次握手净嘀,隨后Client與Server之間可以開(kāi)始傳輸數(shù)據(jù)了。
如圖主要是根據(jù) ACK 與Ack number暑刃;
三岩臣、TCP四次揮手
由于TCP連接時(shí)全雙工的宵膨,因此,每個(gè)方向都必須要單獨(dú)進(jìn)行關(guān)閉谷扣,這一原則是當(dāng)一方完成數(shù)據(jù)發(fā)送任務(wù)后捎琐,發(fā)送一個(gè)FIN來(lái)終止這一方向的連接涯曲,收到一個(gè)FIN只是意味著這一方向上沒(méi)有數(shù)據(jù)流動(dòng)了幻件,即不會(huì)再收到數(shù)據(jù)了绰沥,但是在這個(gè)TCP連接上仍然能夠發(fā)送數(shù)據(jù)贺待,直到這一方向也發(fā)送了FIN。
首先進(jìn)行關(guān)閉的一方將執(zhí)行主動(dòng)關(guān)閉秃臣,而另一方則執(zhí)行被動(dòng)關(guān)閉哪工;
(1)第一次揮手:Client發(fā)送一個(gè)FIN雁比,用來(lái)關(guān)閉Client到Server的數(shù)據(jù)傳送,Client進(jìn)入FIN_WAIT_1狀態(tài)蠢终,將標(biāo)志位FIN和ACK置為1茴她,序號(hào)為X,確認(rèn)序號(hào)為Z=1;
(2)第二次揮手:Server收到FIN后祭钉,發(fā)回一個(gè)ACK給Client朴皆,ACK(標(biāo)志位ACK=1),確認(rèn)序號(hào)為收到的序號(hào)加1泛粹,ack=X+1;
(3)第三次揮手:Server發(fā)送一個(gè)FIN肮疗,用來(lái)關(guān)閉Server到Client的數(shù)據(jù)傳送,Server進(jìn)入LAST_ACK狀態(tài),將標(biāo)志位FIN和ACK置為1们衙,序號(hào)為Y,,確認(rèn)序號(hào)為收到的序號(hào)加1宗侦,ack=X+1;
(4)第四次揮手:Client收到FIN后忆蚀,Client進(jìn)入TIME_WAIT狀態(tài),發(fā)回ACK確認(rèn)(標(biāo)志位ACK=1),確認(rèn)序號(hào)為收到的序號(hào)加1 ack=Y+1;
為什么連接的時(shí)候是三次握手男旗,關(guān)閉的時(shí)候卻是四次握手?
為什么需要三次握手
在謝希仁著《計(jì)算機(jī)網(wǎng)絡(luò)》第四版中講“三次握手”的目的是“為了防止已失效的連接請(qǐng)求報(bào)文段突然又傳送到了服務(wù)端欣鳖,因而產(chǎn)生錯(cuò)誤”。在另一部經(jīng)典的《計(jì)算機(jī)網(wǎng)絡(luò)》一書(shū)中講“三次握手”的目的是為了解決“網(wǎng)絡(luò)中存在延遲的重復(fù)分組”的問(wèn)題什荣。這兩種不用的表述其實(shí)闡明的是同一個(gè)問(wèn)題溃睹。
謝希仁版《計(jì)算機(jī)網(wǎng)絡(luò)》中的例子是這樣的胰坟,“已失效的連接請(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)有要求建立連接∑排牛”。主要目的防止server端一直等待腮猖,浪費(fèi)資源翼悴。
為什么需要四次揮手
因是因?yàn)閠cp是全雙工模式,接收到FIN時(shí)意味將沒(méi)有數(shù)據(jù)再發(fā)來(lái)谍椅,但是還是可以繼續(xù)發(fā)送數(shù)據(jù)古话。