主頁 >  其他 > 底層網路知識詳解-最重要的傳輸層2-TCP協議上

底層網路知識詳解-最重要的傳輸層2-TCP協議上

2020-10-15 16:34:12 其他

上一節,我們講的 UDP,基本上包括了傳輸層所必須的埠欄位,它就像我們小時候一樣簡單,相信“網之初,性本善,不丟包,不亂序”,

后來呢,我們都慢慢長大,了解了社會的殘酷,變得復雜而成熟,就像 TCP 協議一樣,它之所以這么復雜,那是因為它秉承的是“性惡論”,它天然認為網路環境是惡劣的,丟包、亂序、重傳,擁塞都是常有的事情,一言不合就可能送達不了,因而要從演算法層面來保證可靠性,

TCP 包頭格式

我們先來看 TCP 頭的格式,從這個圖上可以看出,它比 UDP 復雜得多,

 

首先,源埠號和目標埠號是不可少的,這一點和 UDP 是一樣的,如果沒有這兩個埠號,資料就不知道應該發給哪個應用,

接下來是包的序號,為什么要給包編號呢?當然是為了解決亂序的問題,不編好號怎么確認哪個應該先來,哪個應該后到呢,編號是為了解決亂序問題,既然是社會老司機,做事當然要穩重,一件件來,面臨再復雜的情況,也臨危不亂,

還應該有的就是確認序號,發出去的包應該有確認,要不然我怎么知道對方有沒有收到呢?如果沒有收到就應該重新發送,直到送達,這個可以解決不丟包的問題,作為老司機,做事當然要靠譜,答應了就要做到,暫時做不到也要有個回復,

TCP 是靠譜的協議,但是這不能說明它面臨的網路環境好,從 IP 層面來講,如果網路狀況的確那么差,是沒有任何可靠性保證的,而作為 IP 的上一層 TCP 也無能為力,唯一能做的就是更加努力,不斷重傳,通過各種演算法保證,也就是說,對于 TCP 來講,IP 層你丟不丟包,我管不著,但是我在我的層面上,會努力保證可靠性,

這有點像如果你在北京,和客戶約十點見面,那么你應該清楚堵車是常態,你干預不了,也控制不了,你唯一能做的就是早走,打車不行就改乘地鐵,盡力不失約,

接下來有一些狀態位,例如 SYN 是發起一個連接,ACK 是回復,RST 是重新連接,FIN 是結束連接等,TCP 是面向連接的,因而雙方要維護連接的狀態,這些帶狀態位的包的發送,會引起雙方的狀態變更,

不像小時候,隨便一個不認識的小朋友都能玩在一起,人大了,就變得禮貌,優雅而警覺,人與人遇到會互相熱情的寒暄,離開會不舍地道別,但是人與人之間的信任會經過多次互動才能建立,

還有一個重要的就是視窗大小,TCP 要做流量控制,通信雙方各宣告一個視窗,標識自己當前能夠的處理能力,別發送的太快,撐死我,也別發的太慢,餓死我,

作為老司機,做事情要有分寸,待人要把握尺度,既能適當提出自己的要求,又不強人所難,除了做流量控制以外,TCP 還會做擁塞控制,對于真正的通路堵車不堵車,它無能為力,唯一能做的就是控制自己,也即控制發送的速度,不能改變世界,就改變自己嘛,

作為老司機,要會自我控制,知進退,知道什么時候應該堅持,什么時候應該讓步,

通過對 TCP 頭的決議,我們知道要掌握 TCP 協議,重點應該關注以下幾個問題:

  • 順序問題 ,穩重不亂;
  • 丟包問題,承諾靠譜;
  • 連接維護,有始有終;
  • 流量控制,把握分寸;
  • 擁塞控制,知進知退,

TCP 的三次握手

所有的問題,首先都要先建立一個連接,所以我們先來看連接維護問題,

TCP 的連接建立,我們常常稱為三次握手,

A:您好,我是 A,

B:您好 A,我是 B,

A:您好 B,

我們也常稱為“請求 -> 應答 -> 應答之應答”的三個回合,這個看起來簡單,其實里面還是有很多的學問,很多的細節,

首先,為什么要三次,而不是兩次?按說兩個人打招呼,一來一回就可以了啊?為了可靠,為什么不是四次?

我們還是假設這個通路是非常不可靠的,A 要發起一個連接,當發了第一個請求杳無音信的時候,會有很多的可能性,比如第一個請求包丟了,再如沒有丟,但是繞了彎路,超時了,還有 B 沒有回應,不想和我連接,

A 不能確認結果,于是再發,再發,終于,有一個請求包到了 B,但是請求包到了 B 的這個事情,目前 A 還是不知道的,A 還有可能再發,

B 收到了請求包,就知道了 A 的存在,并且知道 A 要和它建立連接,如果 B 不樂意建立連接,則 A 會重試一陣后放棄,連接建立失敗,沒有問題;如果 B 是樂意建立連接的,則會發送應答包給 A,

當然對于 B 來說,這個應答包也是一入網路深似海,不知道能不能到達 A,這個時候 B 自然不能認為連接是建立好了,因為應答包仍然會丟,會繞彎路,或者 A 已經掛了都有可能,

而且這個時候 B 還能碰到一個詭異的現象就是,A 和 B 原來建立了連接,做了簡單通信后,結束了連接,還記得嗎?A 建立連接的時候,請求包重復發了幾次,有的請求包繞了一大圈又回來了,B 會認為這也是一個正常的的請求的話,因此建立了連接,可以想象,這個連接不會進行下去,也沒有個終結的時候,純屬單相思了,因而兩次握手肯定不行,

B 發送的應答可能會發送多次,但是只要一次到達 A,A 就認為連接已經建立了,因為對于 A 來講,他的訊息有去有回,A 會給 B 發送應答之應答,而 B 也在等這個訊息,才能確認連接的建立,只有等到了這個訊息,對于 B 來講,才算它的訊息有去有回,

當然 A 發給 B 的應答之應答也會丟,也會繞路,甚至 B 掛了,按理來說,還應該有個應答之應答之應答,這樣下去就沒底了,所以四次握手是可以的,四十次都可以,關鍵四百次也不能保證就真的可靠了,只要雙方的訊息都有去有回,就基本可以了,

好在大部分情況下,A 和 B 建立了連接之后,A 會馬上發送資料的,一旦 A 發送資料,則很多問題都得到了解決,例如 A 發給 B 的應答丟了,當 A 后續發送的資料到達的時候,B 可以認為這個連接已經建立,或者 B 壓根就掛了,A 發送的資料,會報錯,說 B 不可達,A 就知道 B 出事情了,

當然你可以說 A 比較壞,就是不發資料,建立連接后空著,我們在程式設計的時候,可以要求開啟 keepalive 機制,即使沒有真實的資料包,也有探活包,

另外,你作為服務端 B 的程式設計者,對于 A 這種長時間不發包的客戶端,可以主動關閉,從而空出資源來給其他客戶端使用,

三次握手除了雙方建立連接外,主要還是為了溝通一件事情,就是 TCP 包的序號的問題

A 要告訴 B,我這面發起的包的序號起始是從哪個號開始的,B 同樣也要告訴 A,B 發起的包的序號起始是從哪個號開始的,為什么序號不能都從 1 開始呢?因為這樣往往會出現沖突,

例如,A 連上 B 之后,發送了 1、2、3 三個包,但是發送 3 的時候,中間丟了,或者繞路了,于是重新發送,后來 A 掉線了,重新連上 B 后,序號又從 1 開始,然后發送 2,但是壓根沒想發送 3,但是上次繞路的那個 3 又回來了,發給了 B,B 自然認為,這就是下一個包,于是發生了錯誤,

因而,每個連接都要有不同的序號,這個序號的起始序號是隨著時間變化的,可以看成一個 32 位的計數器,每 4 微秒加一,如果計算一下,如果到重復,需要 4 個多小時,那個繞路的包早就死翹翹了,因為我們都知道 IP 包頭里面有個 TTL,也即生存時間,

好了,雙方終于建立了信任,建立了連接,前面也說過,為了維護這個連接,雙方都要維護一個狀態機,在連接建立的程序中,雙方的狀態變化時序圖就像這樣,

 

 一開始,客戶端和服務端都處于 CLOSED 狀態,先是服務端主動監聽某個埠,處于 LISTEN 狀態,然后客戶端主動發起連接 SYN,之后處于 SYN-SENT 狀態,服務端收到發起的連接,回傳 SYN,并且 ACK 客戶端的 SYN,之后處于 SYN-RCVD 狀態,客戶端收到服務端發送的 SYN 和 ACK 之后,發送 ACK 的 ACK,之后處于 ESTABLISHED 狀態,因為它一發一收成功了,服務端收到 ACK 的 ACK 之后,處于 ESTABLISHED 狀態,因為它也一發一收了,

TCP 四次揮手

好了,說完了連接,接下來說一說“拜拜”,好說好散,這常被稱為四次揮手,

A:B 啊,我不想玩了,

B:哦,你不想玩了啊,我知道了,

這個時候,還只是 A 不想玩了,也即 A 不會再發送資料,但是 B 能不能在 ACK 的時候,直接關閉呢?當然不可以了,很有可能 A 是發完了最后的資料就準備不玩了,但是 B 還沒做完自己的事情,還是可以發送資料的,所以稱為半關閉的狀態,

這個時候 A 可以選擇不再接收資料了,也可以選擇最后再接收一段資料,等待 B 也主動關閉,

B:A 啊,好吧,我也不玩了,拜拜,

A:好的,拜拜,

這樣整個連接就關閉了,但是這個程序有沒有例外情況呢?當然有,上面是和平分手的場面,

A 開始說“不玩了”,B 說“知道了”,這個回合,是沒什么問題的,因為在此之前,雙方還處于合作的狀態,如果 A 說“不玩了”,沒有收到回復,則 A 會重新發送“不玩了”,但是這個回合結束之后,就有可能出現例外情況了,因為已經有一方率先撕破臉,

一種情況是,A 說完“不玩了”之后,直接跑路,是會有問題的,因為 B 還沒有發起結束,而如果 A 跑路,B 就算發起結束,也得不到回答,B 就不知道該怎么辦了,另一種情況是,A 說完“不玩了”,B 直接跑路,也是有問題的,因為 A 不知道 B 是還有事情要處理,還是過一會兒會發送結束,

那怎么解決這些問題呢?TCP 協議專門設計了幾個狀態來處理這些問題,我們來看斷開連接的時候的狀態時序圖

 

 斷開的時候,我們可以看到,當 A 說“不玩了”,就進入 FIN_WAIT_1 的狀態,B 收到“A 不玩”的訊息后,發送知道了,就進入 CLOSE_WAIT 的狀態,

A 收到“B 說知道了”,就進入 FIN_WAIT_2 的狀態,如果這個時候 B 直接跑路,則 A 將永遠在這個狀態,TCP 協議里面并沒有對這個狀態的處理,但是 Linux 有,可以調整 tcp_fin_timeout 這個引數,設定一個超時時間,

如果 B 沒有跑路,發送了“B 也不玩了”的請求到達 A 時,A 發送“知道 B 也不玩了”的 ACK 后,從 FIN_WAIT_2 狀態結束,按說 A 可以跑路了,但是最后的這個 ACK 萬一 B 收不到呢?則 B 會重新發一個“B 不玩了”,這個時候 A 已經跑路了的話,B 就再也收不到 ACK 了,因而 TCP 協議要求 A 最后等待一段時間 TIME_WAIT,這個時間要足夠長,長到如果 B 沒收到 ACK 的話,“B 說不玩了”會重發的,A 會重新發一個 ACK 并且足夠時間到達 B,

A 直接跑路還有一個問題是,A 的埠就直接空出來了,但是 B 不知道,B 原來發過的很多包很可能還在路上,如果 A 的埠被一個新的應用占用了,這個新的應用會收到上個連接中 B 發過來的包,雖然序列號是重新生成的,但是這里要上一個雙保險,防止產生混亂,因而也需要等足夠長的時間,等到原來 B 發送的所有的包都死翹翹,再空出埠來,

等待的時間設為 2MSL,MSLMaximum Segment Lifetime,報文最大生存時間,它是任何報文在網路上存在的最長時間,超過這個時間報文將被丟棄,因為 TCP 報文基于是 IP 協議的,而 IP 頭中有一個 TTL 域,是 IP 資料報可以經過的最大路由數,每經過一個處理他的路由器此值就減 1,當此值為 0 則資料報將被丟棄,同時發送 ICMP 報文通知源主機,協議規定 MSL 為 2 分鐘,實際應用中常用的是 30 秒,1 分鐘和 2 分鐘等,

還有一個例外情況就是,B 超過了 2MSL 的時間,依然沒有收到它發的 FIN 的 ACK,怎么辦呢?按照 TCP 的原理,B 當然還會重發 FIN,這個時候 A 再收到這個包之后,A 就表示,我已經在這里等了這么長時間了,已經仁至義盡了,之后的我就都不認了,于是就直接發送 RST,B 就知道 A 早就跑了,

TCP 狀態機

將連接建立和連接斷開的兩個時序狀態圖綜合起來,就是這個著名的 TCP 的狀態機,學習的時候比較建議將這個狀態機和時序狀態機對照著看,不然容易暈,

 

 在這個圖中,加黑加粗的部分,是上面說到的主要流程,其中阿拉伯數字的序號,是連接程序中的順序,而大寫中文數字的序號,是連接斷開程序中的順序,加粗的實線是客戶端 A 的狀態變遷,加粗的虛線是服務端 B 的狀態變遷,

 

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/172560.html

標籤:其他

上一篇:軟體測驗掃盲【教科書級】

下一篇:底層網路知識詳解-最重要的傳輸層3-TCP協議下

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 2023年最新微信小程式抓包教程

    01 開門見山 隔一個月發一篇文章,不過分。 首先回顧一下《微信系結手機號資料庫被脫庫事件》,我也是第一時間得知了這個訊息,然后跟蹤了整件事情的經過。下面是這起事件的相關截圖以及近日流出的一萬條資料樣本: 個人認為這件事也沒什么,還不如關注一下之前45億快遞資料查詢渠道疑似在近日復活的訊息。 訊息是 ......

    uj5u.com 2023-04-20 08:48:24 more
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:47:46 more
  • vulnhub_Earth

    前言 靶機地址->>>vulnhub_Earth 攻擊機ip:192.168.20.121 靶機ip:192.168.20.122 參考文章 https://www.cnblogs.com/Jing-X/archive/2022/04/03/16097695.html https://www.cnb ......

    uj5u.com 2023-04-20 07:46:20 more
  • 從4k到42k,軟體測驗工程師的漲薪史,給我看哭了

    清明節一過,盲猜大家已經無心上班,在數著日子準備過五一,但一想到銀行卡里的余額……瞬間心情就不美麗了。最近,2023年高校畢業生就業調查顯示,本科畢業月平均起薪為5825元。調查一出,便有很多同學表示自己又被平均了。看著這一資料,不免讓人想到前不久中國青年報的一項調查:近六成大學生認為畢業10年內會 ......

    uj5u.com 2023-04-20 07:44:00 more
  • 最新版本 Stable Diffusion 開源 AI 繪畫工具之中文自動提詞篇

    🎈 標簽生成器 由于輸入正向提示詞 prompt 和反向提示詞 negative prompt 都是使用英文,所以對學習母語的我們非常不友好 使用網址:https://tinygeeker.github.io/p/ai-prompt-generator 這個網址是為了讓大家在使用 AI 繪畫的時候 ......

    uj5u.com 2023-04-20 07:43:36 more
  • 漫談前端自動化測驗演進之路及測驗工具分析

    隨著前端技術的不斷發展和應用程式的日益復雜,前端自動化測驗也在不斷演進。隨著 Web 應用程式變得越來越復雜,自動化測驗的需求也越來越高。如今,自動化測驗已經成為 Web 應用程式開發程序中不可或缺的一部分,它們可以幫助開發人員更快地發現和修復錯誤,提高應用程式的性能和可靠性。 ......

    uj5u.com 2023-04-20 07:43:16 more
  • CANN開發實踐:4個DVPP記憶體問題的典型案例解讀

    摘要:由于DVPP媒體資料處理功能對存放輸入、輸出資料的記憶體有更高的要求(例如,記憶體首地址128位元組對齊),因此需呼叫專用的記憶體申請介面,那么本期就分享幾個關于DVPP記憶體問題的典型案例,并給出原因分析及解決方法。 本文分享自華為云社區《FAQ_DVPP記憶體問題案例》,作者:昇騰CANN。 DVPP ......

    uj5u.com 2023-04-20 07:43:03 more
  • msf學習

    msf學習 以kali自帶的msf為例 一、msf核心模塊與功能 msf模塊都放在/usr/share/metasploit-framework/modules目錄下 1、auxiliary 輔助模塊,輔助滲透(埠掃描、登錄密碼爆破、漏洞驗證等) 2、encoders 編碼器模塊,主要包含各種編碼 ......

    uj5u.com 2023-04-20 07:42:59 more
  • Halcon軟體安裝與界面簡介

    1. 下載Halcon17版本到到本地 2. 雙擊安裝包后 3. 步驟如下 1.2 Halcon軟體安裝 界面分為四大塊 1. Halcon的五個助手 1) 影像采集助手:與相機連接,設定相機引數,采集影像 2) 標定助手:九點標定或是其它的標定,生成標定檔案及內參外參,可以將像素單位轉換為長度單位 ......

    uj5u.com 2023-04-20 07:42:17 more
  • 在MacOS下使用Unity3D開發游戲

    第一次發博客,先發一下我的游戲開發環境吧。 去年2月份買了一臺MacBookPro2021 M1pro(以下簡稱mbp),這一年來一直在用mbp開發游戲。我大致分享一下我的開發工具以及使用體驗。 1、Unity 官網鏈接: https://unity.cn/releases 我一般使用的Apple ......

    uj5u.com 2023-04-20 07:40:19 more