tcp報(bào)文段首部
- 最前面兩個分別是源端口和目的端口汇恤,各占2個字節(jié)
-
Sequence Number是包的序號澄暮,用來解決網(wǎng)絡(luò)包亂序(reordering)問題(seq是初始化序號的簡稱)思灌。
- 比如:一段報(bào)文套腹,seq為301砾跃,攜帶100字節(jié)的數(shù)據(jù)矫户,表明第一個字節(jié)的序號是301,最后的字節(jié)序號是400磅叛,期望下一個報(bào)文段的數(shù)據(jù)序號從401開始屑咳,則服務(wù)器或客戶端發(fā)的下一個報(bào)文段的序號字段應(yīng)為401.
-
Acknowledgement Number就是ACK——用于確認(rèn)收到,用來解決不丟包的問題弊琴。(此為確認(rèn)號兆龙,并非tcp flag的ACK)
- 期望收到對方下一個報(bào)文段的第一個數(shù)據(jù)字節(jié)序號。如若ACKnum = N敲董,則表明到N-1為止的所有數(shù)據(jù)都已經(jīng)正確收到紫皇。
- TCP Flag ,也就是包的類型腋寨,主要是用于操控TCP的狀態(tài)機(jī)的聪铺。
- URG:當(dāng)TCP Flag中的URG為1時,則表明緊急指針字段有效萄窜,告訴操作系統(tǒng)铃剔,報(bào)文段中有緊急數(shù)據(jù)、
- ACK:僅當(dāng)ACK =1時查刻,確認(rèn)號才有效键兜。當(dāng)ACK = 0時,確認(rèn)號是無效的穗泵。TCP規(guī)定普气,在連接建立后所有傳送的報(bào)文段都必須把ACK設(shè)為1。(有效的確認(rèn)連接已經(jīng)建立)
- PUSH(推送):當(dāng)這個設(shè)置為1時佃延,接收方會盡快的將收到的報(bào)文段交付給接受應(yīng)用進(jìn)程现诀,而不等到緩存滿了再交付
- RST(復(fù)位):當(dāng)收到的報(bào)文段rst為1時夷磕,表明tcp連接中出現(xiàn)嚴(yán)重的差錯,必須釋放連接仔沿,然后再重新建立連接企锌,還用來拒絕一個非法報(bào)文段和拒絕打開一個連接。
- SYN(同步):在連接建立時用來同步序號于未。當(dāng)SYN =1而ACK =0時,表明這是一個請求連接報(bào)文段陡鹃。對方若同意建立連接烘浦,則應(yīng)當(dāng)在響應(yīng)報(bào)文段中使用SYN=1 和ACK =1。
- FIN(終止): 用來釋放一個連接萍鲸,當(dāng)FIN = 1 時闷叉,表明此報(bào)文段的發(fā)送方的數(shù)據(jù)已經(jīng)發(fā)送完畢,并要求釋放連接脊阴。
- Window又叫Advertised-Window握侧,也就是著名的滑動窗口(Sliding Window),用于解決流控的
- 窗口指的是發(fā)送本報(bào)文段的一方的接受窗口嘿期。窗口值告訴對方:本報(bào)文段首部的確認(rèn)好算起品擎,接收方目前允許對方發(fā)送的數(shù)據(jù)量。窗口值作為接收方讓發(fā)送方設(shè)置其發(fā)送窗口的依據(jù)
- 比如备徐,確認(rèn)號是701萄传,窗口字段是1000,這就表明蜜猾,從701?號算起秀菱,發(fā)送此報(bào)文段的一方還有接受1000個字節(jié)數(shù)據(jù)(字節(jié)序號是701~1700)的接受緩存空間。
tcp三次握手
- TCP是面向連接的協(xié)議蹭睡,為什么要三次握手呢衍菱?
- 要使每一方能夠確知對方的存在
- 避免了服務(wù)器資源的浪費(fèi),預(yù)防連接請求延遲到達(dá)時肩豁,服務(wù)器依舊打開連接等待客戶端脊串。
- 默認(rèn)情況下,client(客戶端)為主動打開連接清钥,server(服務(wù)端)為被動打開連接洪规。
- 1.一般服務(wù)器進(jìn)程會先創(chuàng)建傳輸控制塊TCB,準(zhǔn)備接受客戶端的連接請求循捺,然后服務(wù)器進(jìn)程就處于listen(監(jiān)聽)狀態(tài)斩例,等待連接請求。
- 2.client進(jìn)程在發(fā)起連接之前也會創(chuàng)建一個TCB从橘,然后向server發(fā)出連接請求報(bào)文段念赶,這時候首部的
同步位SYN =1
础钠,同時會選擇一個初始化序號seq = x
。tcp規(guī)定叉谜,SYN報(bào)文段不能攜帶數(shù)據(jù)旗吁,但要消耗一個序號,這時候發(fā)送完SYN報(bào)文后停局,client進(jìn)入SYN-SENT(同步已發(fā)送)
狀態(tài). - 3.server收到請求報(bào)文段后(SYN報(bào)文)很钓,如同意建立連接,則向client發(fā)送確認(rèn)報(bào)文段董栽,在確認(rèn)報(bào)文段首部把
SYN位和ACK位都設(shè)置為1.
码倦,然后AckNum確認(rèn)號 為x+1
,同時也為自己選擇一個初始化序號seq = y
锭碳。
在此報(bào)文段中依然不能攜帶數(shù)據(jù)袁稽,但同樣要消耗掉一個序號,此時server進(jìn)入SYN-RCVD(同步收到)
狀態(tài) - 4.此時client收到server的確認(rèn)后擒抛,還要給server發(fā)送確認(rèn)推汽,此時是第三次握手。發(fā)送的確認(rèn)報(bào)文段
ACK置1
歧沪,確認(rèn)號AckNum為 ack= y+1.
而自己的序號seq = x+1
,這時候歹撒,tcp規(guī)定可以攜帶數(shù)據(jù),但不攜帶數(shù)據(jù)則不消耗序號
诊胞。這說明栈妆,下一個數(shù)據(jù)報(bào)文段的seq仍是 x+1
.這時候。tcp連接已經(jīng)建立厢钧,client也進(jìn)入ESTABLISHED(已建立連接狀態(tài)
). - 5.當(dāng)server收到client的確認(rèn)后鳞尔,也進(jìn)入了
ESTABLISHED狀態(tài)
- 三次握手主要是為了防止已失效的連接請求報(bào)文突然又傳送到server,因而產(chǎn)生錯誤早直,從而浪費(fèi)server的資源寥假。有了第三次的話,client不發(fā)送第三次確認(rèn)server的確認(rèn)霞扬,server由于收不到第三次確認(rèn)糕韧,就是的client并沒有需要建立連接。
四次握手喻圃,釋放連接
1.同理三次握手萤彩,client先發(fā)送一個連接釋放報(bào)文段給server,
并停止發(fā)送數(shù)據(jù)
斧拍,主動關(guān)閉tcp連接,這個報(bào)文段的首部將tcp flag中的FIN為設(shè)置為1
雀扶,然后將seq = u
,等于把前面已傳送過去的數(shù)據(jù)最后一個字節(jié)+1.此時client由ESTABLISHED狀態(tài)進(jìn)入FIN-WAIT-1(終止等待1)狀態(tài)
。等待server的確認(rèn)愚墓,請注意予权,F(xiàn)IN報(bào)文段即使不攜帶數(shù)據(jù)
,也會消耗一個序號浪册。2.當(dāng)server收到FIN報(bào)文后扫腺,會立即發(fā)出
確認(rèn)ack=1,ACKnum =u +1村象,然后自己的序號為v
笆环,發(fā)出去后則進(jìn)入CLOSE-WAIT(關(guān)閉等待)狀態(tài)
.這個時候server會通知高層應(yīng)用進(jìn)程,這時TCP連接進(jìn)入半關(guān)閉(half-close)狀態(tài)厚者,就是client已經(jīng)沒有數(shù)據(jù)發(fā)給server躁劣,而server如果還有數(shù)據(jù)發(fā)給client,client仍要接收籍救,這個狀態(tài)還持續(xù)一段時間。3.當(dāng)client收到server的確認(rèn)后渠抹,就進(jìn)入了
FIN-WAIT-2(終止等待2)狀態(tài)
蝙昙,等待server發(fā)出關(guān)閉連接報(bào)文。4.當(dāng)server已經(jīng)沒有更多數(shù)據(jù)要向client發(fā)送的時候梧却,就會發(fā)出server的FIN報(bào)文段奇颠,然后必須重復(fù)發(fā)送上次的
確認(rèn)號AckNum為 ack= u+1
,在設(shè)置自己的序號seq=w
此時server就會進(jìn)入LAST-ACK(最后確認(rèn))狀態(tài)
,等待client的確認(rèn)放航。5.當(dāng)client受到server的連接釋放報(bào)文后烈拒,必須對此發(fā)出確認(rèn)。在確認(rèn)報(bào)文段把
ack置1
广鳍,確認(rèn)號AckNum為 ack= w+1
荆几。而自己的序號為 seq = u+1
。然后則進(jìn)入 TIME-WAIT赊时。此時TCP連接還沒釋放
吨铸,必須等待2MSL(2次最長報(bào)文段壽命:2*2分鐘)
.等待完后才進(jìn)入CLOSED狀態(tài),而server收到最后ACK的時候就會進(jìn)入CLOSED祖秒,比client早一點(diǎn)诞吱。-
為什么需要等待2MSL時間呢?
- 1.為了保證client發(fā)送的最后一個ACK報(bào)文段能夠到達(dá)server竭缝,假如房维,這個最后ACK報(bào)文段丟失了,則server就處在LAST-ACK狀態(tài)中抬纸,一直收不到自己剛剛發(fā)給client的FIN+ACK的報(bào)文段的確認(rèn)報(bào)文咙俩。server就會再次重傳一次FIN+ACK。而client就能在2MSL時間內(nèi)收到重傳的FIN+ACK報(bào)文湿故,從而client在最后TIME-WAIT的狀態(tài)中可以再次重傳一次對server的FIN+ACK報(bào)文的確認(rèn)報(bào)文暴浦。重啟2MSL計(jì)時器溅话。
- 這樣如果client不在TIME-WAIT等待一段時間,而是在發(fā)送第一次ACK報(bào)文后立即釋放連接歌焦,如果這個ACK報(bào)文丟失后飞几,就無法收到server重傳的FIN+ACK報(bào)文,因而不會再次發(fā)送ACK報(bào)文段独撇,server就無法正常進(jìn)入CLOSED狀態(tài)屑墨。
- 2.還有一個原因是為了防止已經(jīng)失效的報(bào)文段在新的連接中出現(xiàn)。因?yàn)閏lient發(fā)送完最后一個ACK報(bào)文段后纷铣,等待2MSL后卵史,會使本次連接內(nèi)所有產(chǎn)生的報(bào)文段在網(wǎng)絡(luò)中小時。
總結(jié)
- 無論三次握手與四次握手搜立,雙方的序號seq與acknum都要保持同步以躯,比如server發(fā)送seq =x,client則會發(fā)送acknum=x+1.
- 每次握手都需要確認(rèn)上一次握手啄踊,tcp flag中的標(biāo)志位是發(fā)起連接或者釋放連接的關(guān)鍵忧设。