TCP 的工作臺

斑碼發表於2019-11-05

新人拜訪

“您好,我是 TCP 服務的實習生,剛培訓完,請問您就是 TCP 老司機嗎?”

正坐在辦公室悠閒喝著咖啡的我,差點一口噴出來,“哦哦,行,你終於來啦,看來幾天前的資源申請通過了啊,老司機?”

“瀏覽器老大這麼叫你的,說你厲害,靠譜的很。”

“好吧,既然來了,趕緊準備準備!這你的工作臺。” 我放下手中的咖啡,走到了一個靠窗的工作臺,指了指。

“好嘞。” 說著,剛來的小夥子走了過來。

工作臺

“好多工具啊,這個通道是什麼,這兒還有個鍾?都怎麼用呀?” 小夥子滿臉好奇的問道。

“這樣吧,從左到右,我一一給你說說。”

“首先,最左邊呢,是個通道,這裡會蹦出應用層需要我們傳送的資料。最常見的就是 HTTP 那小子的報文了。”

“瞭解,我們的工作就是傳送應用層的資料。原來不需要我們自己去拿啊!”

“旁邊呢就是掃描機,你需要根據實際情況把資料進行掃描,掃描機會把資料分塊,按序號,放在旁邊這個盒子裡。”

“嗯嗯,這個我清楚,資料塊大小需要根據實時的網路情況確定。”

“不錯。這小夥子腦子還挺靈光。看來培訓的不錯” 我心中暗暗贊到。

“再往右,你看到這又是一個通道,這個通道就是我們和伺服器進行溝通的通道了。通道旁是兩個計數器,分別用來記錄我們的序號和伺服器序號,這個會自動加,你不用操作。就叫 1 號計數器和 2 號計數器吧,等下會用到。”

“好的,1 號計數器其實就是報文中的序號?”

“嗯嗯,不錯,用的時候看一眼就行,在計數器旁邊有幾個按鈕,我給你說說。這裡最好記一下。”

“嗯嗯” 說著小夥子拿出了筆記本開始記錄。

任務降臨

我指了指標著 SYN 的按鈕,說道:“這個是請求連線按鈕,也就是通知伺服器,我們想發資料給他。”

說著,最左側的通道突然一閃,蹦出了一個 HTTP 服務打包好的包裹,剛來的小兄弟顯的有點慌亂,嚥了一口氣。

“剛好,那我就那這給給你做一下演示吧。” 說著,我站到了工作臺正中。

“嗯。” 小兄弟緊張的說不出話來。

“首先呢,按一下 SYN 按鈕,請求傳送資料。” 1 號計數器跳了一下,由原本的 0 跳到了 1。“按下這個按鈕工作臺會傳送一個請求連線報文,相信報文的內容你應該清楚吧?” 我問道。

SYN1,序號為 0。” 看了一眼 1 號計數器,小夥子自信的答道。

“嗯,不錯!” 不一會計數器旁的通道蹦出了一段報文,2 號計數器直接由 0 跳到了 11

“讓我們來看看,都有什麼,你看這裡。” 我指了指報文中的 ACK,小夥子也靠了過來。

ACK 等於 1,說明伺服器接受了我們的連線請求,對吧?” 小夥子說道。

“是的,那我們建立連線?” 我露出了狡猾的笑容。

“還需要核對 確認序號 吧?” 小夥子有點困惑。

“為什麼?” 我反問道。

“確保連線的準確性。老師說過,網路是一個複雜的環境,會出現報文滯留的情況,因此 TCP 連線兩端規定,在得到請求連線時,需要將 確認序號 置為請求序號加 1。那麼現在我們應該還要核對 確認序號1 號計數器的值!” 小夥子轉眼看向 1 號計數器,“咦,怎麼一樣?應該是差 1 的啊?”

“你忘了,在你按下 SYN 按鈕時,1 號計數器已經跳了一下嗎?”

“哦 ~” 小夥子恍然大悟,“那是應該相等,這個也太好用了吧!得記一下!”

“唰唰唰” 一旁發出鉛筆摩擦紙面的聲響,“有我剛來的樣子” 我不經感嘆道。

“接著,你看 SYN 欄位為 1,說明伺服器請求連線,TCP 是一個穩定的連線,雙向資料的通道,需要雙方都確認連線狀態,這點我不需要特殊說明吧?”

“嗯嗯,在學校老師說過。”

“那好,為了確保連線的正確性,我們需要和伺服器做相同的操作,把序號加 1 後,放在確認序號內,伺服器返回的序號是 10 我們返回 11 就行。但這些不需要你進行實際的報文生成,在你確定可以建立連線的情況下,按一下標著 ACK 按鈕就行。” 說著我按下了 ACK 按鈕。“現在三次握手結束,連線通道成功生成。我們開始傳輸資料,剩下還有幾個按鈕用到的時候在說。”

“那個,我想問一下,我知道 TCP 是個雙向資料通道,但如果我們不確認建立連線,直接傳送資料應該也沒問題吧?我們和伺服器都已經傳送了一次請求,並且都收到了,為什麼還要確認一下呢?” 小夥子若有所思道。

“既然是雙向資料通道,那麼通道的兩端都應該清楚自己和對方的傳送和接收的能力,對吧?”

“當然!不然通道是不穩定的。”

“那你想想,在前兩次通訊過程中,雙方都知道了哪些情況?”

“第一次我們發報文,第二次伺服器返回報文我們接收到,那我們就知道了我們有能力傳送和接收,伺服器也有能力接收和傳送。”

“那伺服器呢?”

“伺服器的話,應該知道了他自己有能力接收,知道我們有能力傳送,他自己卻不清楚他能不能傳送,也不知道我們是否能接收!因為我們還沒回復他。”

“因此呢,三次通訊(握手)讓雙方都知道了雙方都有傳送與接收的能力,這對於一個雙向資料通道來說至關重要。” 我解釋道。

“嗯嗯,我記一下。” 又是一陣 “唰唰唰” 的聲音。

傳送報文

“已經建立了通道,那接下來就簡單了。” 我拿起 HTTP 扔過來的資料,說道:“我們看看我們一次能傳送的資料包大小,在這兒。” 我指了指工作臺最右側的螢幕,螢幕上顯示著一連串的資訊,“這些就是系統引數,這個就是我們網路所能承受的最大傳送量。”

“嗯,一次可以傳送 1100 位元組。” 小夥子邊看邊說道。

“嗯,不錯。那我們就將資料按 1000 來切割吧,剩一定空間個報文頭部使用。” 說著我啟動一遍的掃描機,設定為 1000,丟進 HTTP 的資料,一旁的盒子出現排好序的資料塊。

“好神奇啊,學校裡都我們自己切的。” 小夥子雙眼中冒著金光。

“接下來發生報文就好了。”

“好的,我來拼接資料,源埠:5800,目標埠:80,序號:1,資料偏移:20,標誌位:無特殊情況,視窗大小:3,校驗和:...” 小夥子突然嘰裡咕嚕一堆,嚇了我一跳。

“不需要這麼麻煩,源埠,目標埠,在工作臺接收到應用層資料後,就能生成,至於序號和偏移量,你也不用關心啦,我來演示一遍,看好。”

我瞧了一眼伺服器先前返回的報文,得知視窗為 3,拿起盒子裡的資料就往按鈕旁的通道里丟,一連丟了 3 個。1 號計數器也連續跳了 3 下,由 1 跳到了 1001,在由 1001 跳到了 2001,最終定格在 3001

“好了,接下來就等伺服器響應了。”

“這就好了?” 小夥子明顯有點不敢相信。

“對啊,好了!等伺服器確認就行。” 我有點得意。“工作臺會幫我們把資料打包生成報文,這個工作臺可是我的專利!”

“哇塞,老司機就是厲害!比學校裡高階多了。” 小夥子雙眼中再次亮起金光。

單向關閉

沒過多久,2 號計數器連跳 3 次,噠噠噠,通道里蹦出 3 個伺服器返回的報文,內容都為:請求完成,需要下一份資料。

我拿起盒子裡的下 3 塊,往通道里扔。1 號計數器噠噠噠,又連著跳了 3 次。如此迴圈往復了十幾次,資料終於發完。

“今天的網不錯誒,沒有重發的情況出現。現在我們發完了,只需要等待伺服器傳送資料就行了。”

大概過了 10ms,通道內陸陸續續開始蹦出報文,我剛想上手,一旁小夥子一把把報文攬走,“這個我熟,我來吧!”

獲取報文資料,按照序號排好,一頓操作還挺溜。

噠噠噠,2 號計數器不斷的跳動,定格在 50001 上。

“好現在資料也接收完畢了,需要進行單向關閉。如何進行關閉?” 我想考考小夥子的能力。

“傳送報文,將 FIN 置為 1,序號為 43001。” 小夥子瞧了一眼 1 號計數器說道:“然後等伺服器返回確認就好了,哦,對為了應付網路滯留情況出現,需要核對 確認序號。”

“不錯,但在這...” 我話還沒說完,小夥子興奮的說道:“是不是按那個 FIN 按鈕就好了?”

“嗯,對!我們只需要核對 確認序號 就好了。你來操作吧 ~” 看著一臉興奮的小夥子,我停止了手中的操作。

“好的。” 說著,小夥子按下了 FIN 按鈕。1 號計數器跳了一下,定格在 43002。不一會通道里蹦出了報文,確認序號與 1 好計數器一致,都為 43002

“現在單向關閉成功,等待伺服器請求關閉。” 小夥子一副訓練有素的樣子。

“嗯,不錯,接下來就等待伺服器最終確定關閉了。” 我拿起一旁的咖啡,慢悠悠的說道:“那你知道為什麼這是單向關閉?”

“因為只有我們這邊確認把資料都已經傳送完畢啦 ~ 沒準伺服器還有資料給我們呢 ~ ”

“嗯,不錯。” 我拿起咖啡喝了一口,不經感慨道:“後繼有人了啊!”

“老大,伺服器發出關閉請求了,你看。” 小夥子拿起一個報文,對我說道。

“我想你應該知道怎麼做了吧?”

“嗯嗯,按 ACK 按鈕就好了,這個和開啟連線確認是同一個操作,按您的智慧,應該是這樣。” 說著按下了 ACK 按鈕。

“嗯,這個彩虹屁真香,哦不,你真聰明!”

“哈哈” 我們同時發出笑聲,“我和你說,那個 HTTP 服務部可不咋的,經常砸我,這不資料都好了,砸 TM 的。”

duang ~” 通道一頭髮出一陣巨響,“TCP 你們沒完了是不?”

相關文章