TCP 的辦公室

新人拜訪

「您好,我是 TCP 服務的實習生,剛培訓完,請問您就是 TCP 老司機嗎?」 瀏覽器

正坐在辦公室清閒喝着咖啡的我,差點一口噴出來,「哦哦,行,你終於來啦,看來幾天前的資源申請經過了啊,老司機?」服務器

「瀏覽器老大這麼叫你的,說你厲害,靠譜的很。」網絡

「好吧,既然來了,趕忙準備準備!這你的工做臺。」 我放下手中的咖啡,走到了一個靠窗的工做臺,指了指。工具

「好嘞。」 說着,剛來的小夥子走了過來。code

工做臺

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

「這樣吧,從左到右,我一一給你說說。」打包

「首先,最左邊呢,是個通道,這裏會蹦出應用層須要咱們發送的數據。最多見的就是 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 大家沒完了是不?」

相關文章
相關標籤/搜索