為啥"三次握手"確認(rèn)序號要加1?
其實(shí)加1只是表象,加長度才是本質(zhì)。但是,為啥要加長度?
了解TCP三次握手的人都知道,其ACK確認(rèn)報文會有一個確認(rèn)序號ack_seq,這個序號的值則為SYN連接報文的序號加1。
圖片
即假如客戶端向服務(wù)器發(fā)送連接請求,它會先發(fā)一個SYN報文。假設(shè)這個報文序號為x的話,收到請求的服務(wù)器會用ACK報文應(yīng)答,并將ACK報文的確認(rèn)序號賦值為x+1。意思是“收到x號報文了”。
這里難免讓人疑惑,既然是表達(dá)“收到x號報文”,ACK的確認(rèn)序號不應(yīng)該是賦值為x嗎?為啥是x+1,加1的作用是什么?
正如開頭所說,加1只是表象,加長度才是本質(zhì)。這里1表達(dá)的是SYN連接報文的數(shù)據(jù)長度。這個長度的單位是字節(jié),加1就表示收到了數(shù)據(jù)長度為1字節(jié)的報文,加m則表示收到數(shù)據(jù)長度為m字節(jié)的報文。
也許有人會追問,SYN作為連接請求報文,哪有什么數(shù)據(jù),其數(shù)據(jù)長度不應(yīng)該是零嗎?為啥要加1?
圖片
這是因?yàn)?,雖然SYN報文的數(shù)據(jù)部分確實(shí)為空,但是它卻實(shí)實(shí)在在占據(jù)了一個報文序號x,而一個報文序號是要對應(yīng)一個字節(jié)的,這時即使它實(shí)際沒有占用任何一個字節(jié)放數(shù)據(jù),那一個字節(jié)也被消耗了。
所以,“ack_seq=x+1”更準(zhǔn)確的翻譯應(yīng)該是“收到了起始序號為x長度為1的報文數(shù)據(jù)”。這種ack_seq=seq+length的方式其優(yōu)勢在于,配合序號的連續(xù)性,當(dāng)需要確認(rèn)的數(shù)據(jù)不止一個字節(jié)時,仍舊可以只用一個ACK報文進(jìn)行應(yīng)答。
不知是否有人疑惑,前文所述的SYN連接報文的編號x,一會說它是報文序號,一會又說一個報文序號對應(yīng)了一個字節(jié),那到底序號x是報文編號還是字節(jié)編號呢?
答案是,它既是報文編號也是字節(jié)編號,也就是一個編號兩個身份。但這只是一個報文的數(shù)據(jù)起始字節(jié)編號才有的特權(quán)。這就像各種編程語言中的數(shù)組,其內(nèi)部第一個數(shù)組項(xiàng)的地址,既是當(dāng)前數(shù)組項(xiàng)的地址,也代表整個數(shù)組的地址。