TCP/IP是一類用于網(wǎng)絡(luò)通信的協(xié)議系統(tǒng)萍鲸,傳統(tǒng)上被分為四層,如圖所示
接下來庇勃,具體說一下TCP/IP三次握手檬嘀,四次揮手
首先,需要了解一下它的報(bào)文格式责嚷,以及內(nèi)容表示鸳兽;
(1)seq:隨機(jī)序號(hào),占32位罕拂,用來標(biāo)識(shí)從TCP源端向目的端發(fā)送的字節(jié)流揍异,發(fā)送方發(fā)送數(shù)據(jù)時(shí)對此進(jìn)行標(biāo)記;
(2)ack:確認(rèn)序號(hào),占32位爆班,只有ACK標(biāo)志位為1時(shí)衷掷,確認(rèn)序號(hào)字段才有效,ack=seq+1;
(3)標(biāo)志位:共六個(gè)柿菩,URG戚嗅,ACK,PSH枢舶,RST懦胞,SYN,F(xiàn)IN
URG:緊急指針(Urgent Pointer)有效祟辟;
ACK:確認(rèn)序號(hào)有效医瘫;
PSH:接收方應(yīng)盡快將這個(gè)報(bào)文交給應(yīng)用層;
RST:重置連接旧困;
SYN:發(fā)起一個(gè)新連接醇份;
FIN:釋放一個(gè)連接稼锅;
TCP三次握手
1.TCP服務(wù)器進(jìn)程先創(chuàng)建傳輸控制塊TCB,時(shí)刻準(zhǔn)備接受客戶進(jìn)程的連接請求僚纷,此時(shí)服務(wù)器就進(jìn)入了LISTEN(監(jiān)聽)狀態(tài)矩距;
2.TCP客戶進(jìn)程也是先創(chuàng)建傳輸控制塊TCB,然后向服務(wù)器發(fā)出連接請求報(bào)文怖竭,這是報(bào)文首部中的同部位SYN=1锥债,同時(shí)選擇一個(gè)初始序列號(hào) seq=x ,此時(shí)痊臭,TCP客戶端進(jìn)程進(jìn)入了 SYN-SENT(同步已發(fā)送狀態(tài))狀態(tài)哮肚。TCP規(guī)定,SYN報(bào)文段(SYN=1的報(bào)文段)不能攜帶數(shù)據(jù)广匙,但需要消耗掉一個(gè)序號(hào)允趟。
3.TCP服務(wù)器收到請求報(bào)文后,如果同意連接鸦致,則發(fā)出確認(rèn)報(bào)文潮剪。確認(rèn)報(bào)文中應(yīng)該 ACK=1,SYN=1分唾,因?yàn)榉?wù)器端已經(jīng)收到了序號(hào)為x的數(shù)據(jù)包抗碰,接下來需要接受下一個(gè)數(shù)據(jù)包,所以確認(rèn)號(hào)是ack=x+1绽乔,同時(shí)也要為自己初始化一個(gè)序列號(hào) seq=y弧蝇,此時(shí),TCP服務(wù)器進(jìn)程進(jìn)入了SYN-RCVD(同步收到)狀態(tài)迄汛。這個(gè)報(bào)文也不能攜帶數(shù)據(jù)捍壤,但是同樣要消耗一個(gè)序號(hào)。
4.TCP客戶進(jìn)程收到確認(rèn)后鞍爱,還要向服務(wù)器給出確認(rèn)。確認(rèn)報(bào)文的ACK=1专酗,ack=y+1睹逃,自己的序列號(hào)seq=x+1,此時(shí)祷肯,TCP連接建立沉填,客戶端進(jìn)入ESTABLISHED(已建立連接)狀態(tài)。TCP規(guī)定佑笋,ACK報(bào)文段可以攜帶數(shù)據(jù)翼闹,但是如果不攜帶數(shù)據(jù)則不消耗序號(hào)。
5.當(dāng)服務(wù)器收到客戶端的確認(rèn)后也進(jìn)入ESTABLISHED狀態(tài)蒋纬,此后雙方就可以開始通信了猎荠。
當(dāng)然很多人就會(huì)想為什么要建立三次握手坚弱,也就是說為什么客戶端最后還要建立一次連接,兩次握手可不可以关摇,答案當(dāng)然是否定的荒叶!
首先,三次握手的目的:消除舊有連接請求的SYN消息對新連接的干擾输虱,同步連接雙方的序列號(hào)和確認(rèn)號(hào)并交換TCP窗口的大小信息些楣。
一句話,主要防止已經(jīng)失效的連接請求報(bào)文突然又傳送到了服務(wù)器宪睹,從而產(chǎn)生錯(cuò)誤愁茁。
如果使用的是兩次握手建立連接,假設(shè)有這樣一種場景亭病,客戶端發(fā)送了第一個(gè)請求連接并且沒有丟失鹅很,只是因?yàn)樵诰W(wǎng)絡(luò)結(jié)點(diǎn)中滯留的時(shí)間太長了,由于TCP的客戶端遲遲沒有收到確認(rèn)報(bào)文命贴,以為服務(wù)器沒有收到道宅,此時(shí)重新向服務(wù)器發(fā)送這條報(bào)文,此后客戶端和服務(wù)器經(jīng)過兩次握手完成連接胸蛛,傳輸數(shù)據(jù)污茵,然后關(guān)閉連接。此時(shí)此前滯留的那一次請求連接葬项,網(wǎng)絡(luò)通暢了到達(dá)了服務(wù)器泞当,這個(gè)報(bào)文本該是失效的,但是民珍,兩次握手的機(jī)制將會(huì)讓客戶端和服務(wù)器再次建立連接襟士,這將導(dǎo)致不必要的錯(cuò)誤和資源的浪費(fèi)。
如果采用的是三次握手嚷量,就算是那一次失效的報(bào)文傳送過來了陋桂,服務(wù)端接受到了那條失效報(bào)文并且回復(fù)了確認(rèn)報(bào)文,但是客戶端不會(huì)再次發(fā)出確認(rèn)蝶溶。由于服務(wù)器收不到確認(rèn)嗜历,就知道客戶端并沒有請求連接。
TCP四次揮手
1.客戶端進(jìn)程發(fā)出連接釋放報(bào)文抖所,并且停止發(fā)送數(shù)據(jù)梨州。釋放數(shù)據(jù)報(bào)文首部,F(xiàn)IN=1田轧,其序列號(hào)為seq=u(等于前面已經(jīng)傳送過來的數(shù)據(jù)的最后一個(gè)字節(jié)的序號(hào)加1)暴匠,此時(shí),客戶端進(jìn)入FIN-WAIT-1(終止等待1)狀態(tài)傻粘。 TCP規(guī)定每窖,F(xiàn)IN報(bào)文段即使不攜帶數(shù)據(jù)帮掉,也要消耗一個(gè)序號(hào)。
2.服務(wù)器收到連接釋放報(bào)文岛请,發(fā)出確認(rèn)報(bào)文旭寿,ACK=1,ack=u+1崇败,并且?guī)献约旱男蛄刑?hào)seq=v盅称,此時(shí),服務(wù)端就進(jìn)入了CLOSE-WAIT(關(guān)閉等待)狀態(tài)后室。TCP服務(wù)器通知高層的應(yīng)用進(jìn)程缩膝,客戶端向服務(wù)器的方向就釋放了,這時(shí)候處于半關(guān)閉狀態(tài)岸霹,即客戶端已經(jīng)沒有數(shù)據(jù)要發(fā)送了疾层,但是服務(wù)器若發(fā)送數(shù)據(jù),客戶端依然要接受贡避。這個(gè)狀態(tài)還要持續(xù)一段時(shí)間痛黎,也就是整個(gè)CLOSE-WAIT狀態(tài)持續(xù)的時(shí)間。
3.客戶端收到服務(wù)器的確認(rèn)請求后刮吧,此時(shí)湖饱,客戶端就進(jìn)入FIN-WAIT-2(終止等待2)狀態(tài),等待服務(wù)器發(fā)送連接釋放報(bào)文(在這之前還需要接受服務(wù)器發(fā)送的最后的數(shù)據(jù))杀捻。
4.服務(wù)器將最后的數(shù)據(jù)發(fā)送完畢后井厌,就向客戶端發(fā)送連接釋放報(bào)文,F(xiàn)IN=1致讥,ack=u+1仅仆,由于在半關(guān)閉狀態(tài),服務(wù)器很可能又發(fā)送了一些數(shù)據(jù)垢袱,假定此時(shí)的序列號(hào)為seq=w墓拜,此時(shí),服務(wù)器就進(jìn)入了LAST-ACK(最后確認(rèn))狀態(tài)请契,等待客戶端的確認(rèn)撮弧。
5.客戶端收到服務(wù)器的連接釋放報(bào)文后,必須發(fā)出確認(rèn)姚糊,ACK=1,ack=w+1授舟,而自己的序列號(hào)是seq=u+1救恨,此時(shí),客戶端就進(jìn)入了TIME-WAIT(時(shí)間等待)狀態(tài)释树。注意此時(shí)TCP連接還沒有釋放肠槽,必須經(jīng)過2?MSL(最長報(bào)文段壽命)的時(shí)間后擎淤,當(dāng)客戶端撤銷相應(yīng)的TCB后,才進(jìn)入CLOSED狀態(tài)秸仙。
6.服務(wù)器只要收到了客戶端發(fā)出的確認(rèn)嘴拢,立即進(jìn)入CLOSED狀態(tài)。同樣寂纪,撤銷TCB后席吴,就結(jié)束了這次的TCP連接±痰埃可以看到孝冒,服務(wù)器結(jié)束TCP連接的時(shí)間要比客戶端早一些。
為什么建立連接是三次握手拟杉,關(guān)閉連接確是四次揮手呢庄涡?
建立連接的時(shí)候, 服務(wù)器在LISTEN狀態(tài)下搬设,收到建立連接請求的SYN報(bào)文后穴店,把ACK和SYN放在一個(gè)報(bào)文里發(fā)送給客戶端。
而關(guān)閉連接時(shí)拿穴,服務(wù)器收到對方的FIN報(bào)文時(shí)泣洞,僅僅表示對方不再發(fā)送數(shù)據(jù)了但是還能接收數(shù)據(jù),而自己也未必全部數(shù)據(jù)都發(fā)送給對方了贞言,所以己方可以立即關(guān)閉斜棚,也可以發(fā)送一些數(shù)據(jù)給對方后,再發(fā)送FIN報(bào)文給對方來表示同意現(xiàn)在關(guān)閉連接该窗,因此弟蚀,己方ACK和FIN一般都會(huì)分開發(fā)送,從而導(dǎo)致多了一次酗失。
為什么客戶端最后還要等待2MSL义钉?
MSL(Maximum Segment Lifetime),TCP允許不同的實(shí)現(xiàn)可以設(shè)置不同的MSL值规肴。
第一捶闸,保證客戶端發(fā)送的最后一個(gè)ACK報(bào)文能夠到達(dá)服務(wù)器,因?yàn)檫@個(gè)ACK報(bào)文可能丟失拖刃,站在服務(wù)器的角度看來删壮,我已經(jīng)發(fā)送了FIN+ACK報(bào)文請求斷開了,客戶端還沒有給我回應(yīng)兑牡,應(yīng)該是我發(fā)送的請求斷開報(bào)文它沒有收到央碟,于是服務(wù)器又會(huì)重新發(fā)送一次,而客戶端就能在這個(gè)2MSL時(shí)間段內(nèi)收到這個(gè)重傳的報(bào)文均函,接著給出回應(yīng)報(bào)文亿虽,并且會(huì)重啟2MSL計(jì)時(shí)器菱涤。
第二贴届,防止類似與“三次握手”中提到了的“已經(jīng)失效的連接請求報(bào)文段”出現(xiàn)在本連接中渣叛。客戶端發(fā)送完最后一個(gè)確認(rèn)報(bào)文后下隧,在這個(gè)2MSL時(shí)間中收毫,就可以使本連接持續(xù)的時(shí)間內(nèi)所產(chǎn)生的所有報(bào)文段都從網(wǎng)絡(luò)中消失攻走。這樣新的連接中不會(huì)出現(xiàn)舊連接的請求報(bào)文。
如果已經(jīng)建立了連接牛哺,但是客戶端突然出現(xiàn)故障了怎么辦陋气?
TCP還設(shè)有一個(gè)保活計(jì)時(shí)器引润,顯然巩趁,客戶端如果出現(xiàn)故障,服務(wù)器不能一直等下去淳附,白白浪費(fèi)資源议慰。服務(wù)器每收到一次客戶端的請求后都會(huì)重新復(fù)位這個(gè)計(jì)時(shí)器,時(shí)間通常是設(shè)置為2小時(shí)奴曙,若兩小時(shí)還沒有收到客戶端的任何數(shù)據(jù)别凹,服務(wù)器就會(huì)發(fā)送一個(gè)探測報(bào)文段,以后每隔75分鐘發(fā)送一次洽糟。若一連發(fā)送10個(gè)探測報(bào)文仍然沒反應(yīng)炉菲,服務(wù)器就認(rèn)為客戶端出了故障,接著就關(guān)閉連接坤溃。