最后一天,繼續(xù)卷!
大家好,我是小林。

正文
為什么 TCP 三次握手期間,為什么客戶端和服務(wù)端的初始化序列號(hào)要求不一樣的呢?
TCP 四次揮手中的 TIME_WAIT 狀態(tài)不是會(huì)持續(xù) 2 MSL 時(shí)長,歷史報(bào)文不是早就在網(wǎng)絡(luò)中消失了嗎?

客戶端和服務(wù)端建立一個(gè) TCP 連接,在客戶端發(fā)送數(shù)據(jù)包被網(wǎng)絡(luò)阻塞了,而此時(shí)服務(wù)端的進(jìn)程重啟了,于是就會(huì)發(fā)送 RST 報(bào)文來斷開連接。
緊接著,客戶端又與服務(wù)端建立了與上一個(gè)連接相同四元組的連接;
在新連接建立完成后,上一個(gè)連接中被網(wǎng)絡(luò)阻塞的數(shù)據(jù)包正好抵達(dá)了服務(wù)端,剛好該數(shù)據(jù)包的序列號(hào)正好是在服務(wù)端的接收窗口內(nèi),所以該數(shù)據(jù)包會(huì)被服務(wù)端正常接收,就會(huì)造成數(shù)據(jù)錯(cuò)亂。
客戶端和服務(wù)端的初始化序列號(hào)不一樣不是也會(huì)發(fā)生這樣的事情嗎?

那客戶端和服務(wù)端的初始化序列號(hào)都是隨機(jī)的,那還是有可能隨機(jī)成一樣的呀?
M是一個(gè)計(jì)時(shí)器,這個(gè)計(jì)時(shí)器每隔4毫秒加1。
F 是一個(gè) Hash 算法,根據(jù)源IP、目的IP、源端口、目的端口生成一個(gè)隨機(jī)數(shù)值,要保證 hash 算法不能被外部輕易推算得出。
懂了,客戶端和服務(wù)端初始化序列號(hào)都是隨機(jī)生成的話,就能避免連接接收歷史報(bào)文了。
序列號(hào),是 TCP 一個(gè)頭部字段,標(biāo)識(shí)了 TCP 發(fā)送端到 TCP 接收端的數(shù)據(jù)流的一個(gè)字節(jié),因?yàn)?TCP 是面向字節(jié)流的可靠協(xié)議,為了保證消息的順序性和可靠性,TCP 為每個(gè)傳輸方向上的每個(gè)字節(jié)都賦予了一個(gè)編號(hào),以便于傳輸成功后確認(rèn)、丟失后重傳以及在接收端保證不會(huì)亂序。序列號(hào)是一個(gè) 32 位的無符號(hào)數(shù),因此在到達(dá) 4G 之后再循環(huán)回到 0。
初始序列號(hào),在 TCP 建立連接的時(shí)候,客戶端和服務(wù)端都會(huì)各自生成一個(gè)初始序列號(hào),它是基于時(shí)鐘生成的一個(gè)隨機(jī)數(shù),來保證每個(gè)連接都擁有不同的初始序列號(hào)。初始化序列號(hào)可被視為一個(gè) 32 位的計(jì)數(shù)器,該計(jì)數(shù)器的數(shù)值每 4 微秒加 1,循環(huán)一次需要 4.55 小時(shí)。


懂了,客戶端和服務(wù)端的初始化序列號(hào)都是隨機(jī)生成,能很大程度上避免歷史報(bào)文被下一個(gè)相同四元組的連接接收,然后又引入時(shí)間戳的機(jī)制,從而完全避免了歷史報(bào)文被接收的問題。
收到讀者的打賞,不管多少錢都是對(duì)小林的最好的認(rèn)可;
收到讀者的感謝,幫助他們面試中擊破了網(wǎng)絡(luò)和系統(tǒng)的八股文面試,我把讀者們的故事,都收錄到了這里:讀者牛逼
