農林漁牧網

您現在的位置是:首頁 > 農業

計算機網路發展和體系結構

2023-01-22由 小白聊程式設計 發表于 農業

移位指令使用什麼計數

計算機網路是什麼?

隨著計算機技術發展,計算機的體積和價格都在下降,之前計算機多用於研究機構,現階段逐步進入一般的公司用於辦公。原來計算機之間傳輸資料需要透過軟盤等第三方儲存介質進行轉存,人們需要將資料直接透過通訊線路傳輸,來縮短傳輸時間,於是計算機網路開始誕生,並逐漸發展為現在巨大的 Internet。

定義和分類

計算機網路的標準定義是:利用通訊線路將地理上分散的、具有獨立功能的計算機系統和通訊裝置按不同的形式連線起來,以功能完善的網路軟體及協議實現資源共享和資訊傳遞的系統。

計算機網路從覆蓋範圍上劃分可以分為三類:區域網、都會網路、廣域網。區域網 LAN(作用範圍一般為幾米到幾十公里)、都會網路MAN(界於WAN與LAN之間)、廣域網WAN(作用範圍一般為幾十到幾千公里)。當然計算機網路劃分不止這一種分類方式,可以按拓撲結構分類(匯流排型、環型、星型、網狀)、還可以按按資訊的交換方式(電路交換、報文交換、報文分組交換)來分等等方式。

計算機網路發展簡史

1。 誕生階段,20 世紀 60 年代中期之前的第一代計算機網路是以單個計算機中心的遠端聯機系統。

2。 ARPANET,多個主機透過通訊線路互聯起來。60 年代初。當時,美國國防部為了保證美國本土防衛力量和海外防禦武裝在受到前蘇聯第一次核打擊以後仍然具有一定的生存和反擊能力,認為有必要設計出一種分散的指揮系統;它由一個個分散的指揮點組成,當部分指揮點被摧毀後,其它點仍能正常工作,並且在這些點之間能夠繞過那些已被摧毀的指揮點而繼續保持聯絡。這個設計出發點很重要,理解了它,就能夠理解為何後面要學習的TCP要這麼設計。為了對這一構思進行驗證,1969 年,美國國防部國防高階研究計劃署(DOD/DARPA)資助建立了一個名為 ARPANET(即“阿帕網”)的網路,將多個大學的計算機主機聯接起來,位於各個結點的大型計算機採用分組交換技術,透過專門的通訊交換機和專門的通訊線路相互連線。E-mail、FTP 和 Telnet 在 ARPANET 上已經誕生。

3。 開放性的標準化體系結構,OSI 誕生。ARPANET 興起後,計算機網路發展迅猛,各大計算機公司相繼推出自己的網路體系結構及實現這些結構的軟硬體產品。由於沒有統一的標準,不同廠商的產品之間互聯很困難,人們迫切需要一種開放性的標準化實用網路環境,這樣應運而生了兩種國際通用的最重要的體系結構, 為了實現網路裝置間的互相通訊,ISO 和 IEEE

(電氣和電子工程師協會,是世界上最大的非營利性專業技術學會)相繼提出了 OSI 參考模型及其 TCP/IP 模型。由於 TCP/IP 儘早地制定了可行性較強的協議,提出了應對技術快速革新的協議,並及時進行後期改良的方案,因此打敗了 OSI 模型,成為了事實上的標準。

4。 Internet 網際網路

20 世紀 90 年代至今的第四代計算機網路, 就是我們所熟知的Internet網際網路。既然網路是很多的計算裝置(電腦、手機等等)連線在一起的,這些計算裝置來自不同的公司,有不同的體系結構,相互之間如何通訊呢?這就好比我們的語言,中國地廣人多,地方性語言也非常豐富,而且方言之間差距巨大。A 地區的方言可能 B 地區的人根本無法聽懂,所以要為全國進行溝通建立一個語言標準,這就是我們的普通話的作用。計算機網路協議同我們的普通話一樣,幫助我們的計算機之間進行溝通。想要成為計算機網路領域高手,掌握計算機網路領域知識就是必備的,而學習計算機網路領域知識過程就是理解網路協議的構成、原理和工作方式的過程。

計算機網路體系結構

OSI 七層模型

開放系統互連參考模型 (Open System Interconnect 簡稱 OSI)是國際標準化組織(ISO)和國際電報電話諮詢委員會(CCITT)聯合制定的開放系統互連參考模型,為開放式互連資訊系統提供了一種功能結構的框架。其目的是為異種計算機互連提供一個共同的基礎和標準框架,併為保持相關標準的一致性和相容性提供共同的參考。這裡所說的開放系統,實質上指的是遵循OSI參考模型和相關協議能夠實現互連的具有各種應用目的的計算機系統。

OSI採用了分層的結構化技術,共分七層,

物理層、資料鏈路層、網路層、傳輸層、會話層、表示層、應用層

計算機網路發展和體系結構

TCP/IP 模型

OSI模型比較複雜且學術化,所以我們實際使用的TCP/IP模型,分5層,`物理層、資料鏈路層(也有 TCP/IP 模型將物理層、資料鏈路層合稱為網路介面層,與之對應的,協議就被稱為 TCP/IP 四層協議模型)、網路層、傳輸層、應用層`。兩個模型之間的對應關係如圖所示:

計算機網路發展和體系結構

無論什麼模型,每一個抽象層建立在低一層提供的服務上,並且為高一層提供服務。大致來說,可以這麼理解(只是幫助我們理解,實際上肯定會有點出入),對於我們的 PC 機來說,物理層可以看成網絡卡,資料鏈路層可以看成網絡卡驅動程式,網路層和傳輸層由操作負責處理,應用層則是常用的一些網路應用程式和我們自己所編寫的網路應用程式。

TCP/IP 協議族

Transmission Control Protocol/Internet Protocol 的簡寫,中譯名為傳輸控制協議/因特網互聯協議,是 Internet 最基本的協議、Internet 國際網際網路絡的基礎,由網路層的 IP 協議和傳輸層的 TCP 協議組成。協議採用了 5 層的層級結構。然而在很多情況下,它是利用 IP 進行通訊時所必須用到的協議群的統稱。也就是說,它其實是個協議家族,由很多個協議組成,並且是在不同的層, 是網際網路的基礎通訊架構。

計算機網路發展和體系結構

IP、TCP 和 UDP

在上述圖形中,網際協議 IP 是 TCP/IP 中非常重要的協議,往往用來確定網路中唯一的一臺計算裝置,它的作用就好比我們現實生活中的電話號碼或者或者通訊地址。所以這層負責對資料加上 IP 地址(有傳送它的主機的地址(源地址)和接收它的主機的地址(目的地址))和其他的資料以確定傳輸的目標。而 TCP 和 UDP 都是傳輸層的協議,傳輸層主要為兩臺主機上的應用程式提供端到端的通訊。

TCP 有點類似於我們日常生活中的打電話,電話接通後透過“喂”確認對方身份,聽不清會要求對方重說,對方說的太快了會要求對方說慢點,講完了各說一句“再見”結束通話。

TCP 提供了一種可靠的資料傳輸服務,TCP 是面向連線的,也就是說,利用 TCP 通訊的兩臺主機首先要經歷一個建立連線的過程,等到連線建立後才開始傳輸資料,而且傳輸過程中採用“帶重傳的肯定確認”技術來實現傳輸的可靠性。TCP 還採用一種稱為“滑動視窗”的方式進行流量控制,傳送完成後還會關閉連線。

UDP(User Datagram Protocol 的簡稱, 中文名是使用者資料報協議)有點類似於我們日常生活中透過不靠譜的物流系統寄東西。UDP 是把資料直接發出去,而不管對方是不是在接收,也不管對方是否能接收的了,也不需要接收方確認,屬於不可靠的傳輸,可能會出現丟包現象,實際應用中要求程式設計師程式設計驗證。

所以 TCP 要比 UDP 可靠的多。

注意:

我們一些常見的網路應用基本上都是基於 TCP 和 UDP 的,這兩個協議又會使用網路層的 IP 協議。但是我們完全可以繞過傳輸層的 TCP 和 UDP,直接使用 IP,比如 Linux 核心中的LVS 就可以直接基於 IP 層進行負載平衡排程;甚至還可以直接訪問鏈路層,比如tcpdump程式就是直接和鏈路層進行通訊的。

TCP/IP 網路傳輸中的資料

每個分層中,都會對所傳送的資料附加一個首部,在這個首部中包含了該層必要的資訊,如傳送的目標地址以及協議相關資訊。通常,為協議提供的資訊為包首部,所要傳送的內容為資料。在下一層的角度看,從上一層收到的包全部都被認為是本層的資料。網路中傳輸的資料包由兩部分組成:一部分是協議所要用到的首部,另一部分是上一層傳過來的資料。首部的結構由協議的具體規範詳細定義。在資料包的首部,明確標明瞭協議應該如何讀取資料。反過來說,看到首部,也就能夠了解該協議必要的資訊以及所要處理的資料。我們用使用者A傳送,使用者B接受來說明:

① 使用者A應用程式處理

首先應用程式會進行編碼處理產生報文/訊息(message)交給下面的 TCP 層。

② 使用者A TCP模組的處理

TCP根據應用的指示,負責建立連線、傳送資料以及斷開連線。TCP 提供將應用層發來的

資料順利傳送至對端的可靠傳輸。為了實現這一功能,需要將應用層資料封裝為報文段

(segment)並附加一個 TCP 首部然後交給下面的 IP 層。

③ 使用者 A IP 模組的處理

IP 將 TCP 傳過來的 TCP 首部和 TCP 資料合起來當做自己的資料,並在 TCP 首部的前端

加上自己的 IP 首部生成 IP 資料報(datagram)然後交給下面的資料鏈路層。

④ 使用者 A 資料鏈路層的處理

從 IP 傳過來的 IP 包對於資料鏈路層來說就是資料。給這些資料附加上鍊路層首部封裝為

鏈路層幀(frame),生成的鏈路層幀(frame)將透過物理層傳輸給接收端。

⑤ 使用者B資料鏈路層的處理

使用者B主機收到鏈路層幀(frame)後,首先從鏈路層幀(frame)首部找到 MAC地址判斷是否為傳送給自己的包,若不是則丟棄資料。

如果是傳送給自己的包,則從乙太網包首部中的型別確定資料型別,再傳給相應的模組,如IP、ARP等。這裡的例子則是 IP 。

⑥使用者B IP模組的處理

IP模組接收到 資料後也做類似的處理。從包首部中判斷此 IP 地址是否與自己的IP地址

匹配,如果匹配則根據首部的協議型別將資料傳送給對應的模組,如 TCP、UDP。這裡的例

子則是 TCP。

⑦ 使用者 B TCP 模組的處理

在 TCP 模組中,首先會計算一下校驗和,判斷資料是否被破壞。然後檢查是否在按照序號

接收資料。最後檢查埠號,確定具體的應用程式。資料被完整地接收以後,會傳給由埠

號識別的應用程式。

⑧ 使用者 B 應用程式的處理

接收端應用程式會直接接收發送端傳送的資料。透過解析資料,展示相應的內容。

計算機網路發展和體系結構

地址和埠號

MAC 地址

我們常聽說 MAC 地址和 IP 地址。

MAC地址全稱叫做媒體訪問控制地址,也稱為區域網地址(LAN Address),MAC位址,

乙太網地址(Ethernet Address)或物理地址(Physical Address),由網路裝置製造商生產時寫在硬體內部。MAC 地址與網路無關,也即無論將帶有這個地址的硬體(如網絡卡、集線器、路由器等)接入到網路的何處,都有相同的 MAC地址,它由廠商寫在網絡卡的BIOS 裡,從理論上講,除非盜來硬體(網絡卡),否則是沒有辦法冒名頂替的。MAC 地址共 48 位(6 個位元組)。前 24 位由 IEEE(電氣和電子工程師協會)決定如何分配,後 24 位由實際生產該網路裝置的廠商自行制定。例如:FF:FF:FF:FF:FF:FF或FF-FF-FF-FF-FF-FF

計算機網路發展和體系結構

IP 地址

IP 地址(Internet Protocol Address)的全稱叫作網際網路協議地址,它的本義是為網際網路上的每一個網路和每一臺主機配置一個唯一的邏輯地址,用來與物理地址作區分。

所以 IP 地址用來識別 TCP/IP 網路中互連的主機和路由器。IP 地址基於邏輯,比較靈活,不受硬體限制,也容易記憶。

IP 地址分為:IPv4 和 IPv6。我們這裡著重講的是 IPv4 地址,IP 地址是由 32 位的二進位制陣列成,它們通常被分為 4 個“8 位二進位制數”,我們可以把它理解為 4 個位元組,格式表示為:(A。B。C。D)。其中,A,B,C,D 這四個英文字母表示為 0-255 的十進位制的整數。例:192。168。1。1

Tips:IP 地址和 MAC 地址之間的區別

1、對於網路中的一些裝置,路由器或者是PC及而言,IP 地址的設計是出於拓撲設計出來的,只要在不重複 IP 地址的情況下,它是可以隨意更改的;而 MAC 地址是根據生產廠商燒錄好的,它一般不能改動的,一般來說,當一臺 PC 機的網絡卡壞了之後,更換了網絡卡之後MAC地址就會變了。

2、在前面的介紹裡面,它們最明顯的區別就是長度不同,IP 地址的長度為 32 位,而MAC地址為48位。

3、它們的定址協議層不同。IP 地址應用於 OSI 模型的網路層,而 MAC 地址應用在OSI模型的資料鏈路層。資料鏈路層協議可以使資料從一個節點傳遞到相同鏈路的另一個節點上(透過 MAC 地址),而網路層協議使資料可以從一個網路傳遞到另一個網路上(ARP根據目的 IP 地址,找到中間節點的MAC地址,透過中間節點傳送,從而最終到達目的網路)。

4、分配依據不同。IP 地址的分配是基於我們自身定義的網路拓撲,MAC 地址的分配是基於製造商。

埠號

面試題:為什麼埠號有65535個?

因為在TCP、UDP協議報文的開頭,會分別有 16 位二進位制來儲存源埠號和目標埠號,所以埠個數是 2^16=65536 個,但是0號埠用來表示所有埠,所以實際可用的埠號是65535個。

在傳輸層也有這種類似於地址的概念,那就是埠號。埠號用來識別同一臺計算機中進行通訊的不同應用程式。因此,它也被稱為程式地址。

一臺計算機上同時可以執行多個程式。傳輸層協議正是利用這些埠號識別本機中正在進行通訊的應用程式,並準確地將資料傳輸。

計算機網路發展和體系結構

埠號的確定

標準既定的埠號:這種方法也叫靜態方法。它是指每個應用程式都有其指定的埠號。但並不是說可以隨意使用任何一個埠號。例如HTTP、FTP、TELNET等廣為使用的應用協議中所使用的埠號就是固定的。這些埠號被稱為知名埠號,分佈在0~1023之間,我們在編寫自己的網路應用服務時,儘量不要使用這些埠號。

時序分配法:伺服器有必要確定監聽埠號,以讓客戶端程式訪問伺服器上的服務。但是客戶端沒必要確定埠號。在這種方法下,客戶端應用程式完全可以不用自己設定埠號,而全權交給作業系統進行分配,客戶端使用的臨時埠號,作業系統分配的一般都是大於10000的。

觀察埠號

Windows下使用netstat -ano檢視所有埠號,netstat -ano|findstr “<埠號>”檢視

指定埠號

Linux 下可以用 root 使用者執行 lsof -i:埠號檢視指定端口占用。

![](media/16654935208841/16654991193393。jpg)

lsof -i -U:顯示所有開啟的 UNIX domain 和埠檔案

我們用的更多的是 netstat

netstat -tunlp 用於顯示 tcp,udp 的埠和程序等相關情況。

netstat 檢視端口占用語法格式:

netstat -tunlp | grep 埠號

-t (tcp) 僅顯示 tcp 相關選項

-u (udp)僅顯示 udp 相關選項

-n 拒絕顯示別名,能顯示數字的全部轉化為數字

-l 僅列出在 Listen(監聽)的服務狀態

-p 顯示建立相關連結的程式名

計算機網路發展和體系結構

綜述

計算機網路發展和體系結構

所以一般來說,不管計算機中有多少網絡卡,每個網絡卡都會有自己的 MAC 地址,這個MAC地址是不會變化的。而每個網絡卡在正常工作的情況下,都會有一個 IP 地址,這個IP地址完全是可以變化的。而這臺計算機中承載的各種應用程式可以擁有自己的埠號,然後透過伺服器的網絡卡,正確地進行網路通訊。一臺伺服器上的不同網路應用程式必須有不同的埠號,A程式啟動了使用了埠x,B程式啟動就不能使用埠x,否則會報錯“Address already in use”。

總的來說,作業系統是透過源IP地址、目標IP地址、協議號(協議型別)、源埠號以及目標埠號這五個元素唯一性的識別一個網路上的通訊。

計算機網路發展和體系結構

面試題:一臺主機上只能保持最多 65535 個 TCP 連線,對嗎?

這個說法不對,我們分伺服器和客戶端分開討論,以下的討論都基於伺服器和客戶端都只有1個IP地址。

服務端

我們已經知道網路通訊五元組是由過源IP地址、目標IP地址、協議號(協議型別)、源埠號以及目標埠號構成。現在考察的是TCP連線,自然五元組中的協議號已經定下來了,於是網路通訊五元組就變化為TCP四元組。

那就是說TCP連線四元組是由源IP地址、源埠、目的IP地址和目的埠構成。

很明顯當四元組中任意一個元素髮生了改變,那麼就代表的是一條完全不同的新連線。

拿我們常用的MySQL舉例,假設它的IP是X,埠3306。使用者A基於IP地址A1,埠PA連線MySQL ,於是構成了一個TCP連線四元組(A1,PA,X,3306)。使用者 B 基於IP地址B1,埠PB連線同一個MySQL,這個時候MySQL需要開啟一個新埠來和使用者B通訊嗎?從我們日常的開發就可以知道,MySQL 並不需要這麼做,所以使用者B就和MySQL構成了一個新的TCP連線四元組(B1,PB,X,3306)。

服務端理論上能達成的最高併發數量是多少?從我們上面的使用者A和使用者B構成的 TCP連線四元組:

(A1,PA,X,3306)

(B1,PB,X,3306)

可以看到目的IP地址和目的埠(X,3306)是不變的,這樣就只剩下源IP地址、源埠是可變的。IP 地址是一個 32 位的整數,所以源 IP 最大有 2 的 32 次方這麼多個。 埠是一個 16 位的整數,所以埠的數量就是 2 的 16 次方。2的32次方(ip 數)× 2的16次方(port數)大約等於兩百多萬億。所以理論上,我們每個server可以接收的連線上限就是兩百多萬億。

當然實際上做不到,目前工程實踐中可以達到的連線數在千萬級別。基於 Java 的應用程式大概能支援百萬級別,具體怎麼做會在本課程第五章中詳細說明。

客戶端

前面我們已經說過,“客戶端應用程式完全可以不用自己設定埠號,而全權交給作業系統進行分配”,可用的埠號只有6萬多,從這個角度考慮,客戶端最多隻能發起6萬多條TCP連線。但其實也不是。從TCP連線四元組來考慮:源 IP 地址、源埠、目的 IP 地址和目的埠,目的IP地址和目的埠指的是伺服器的IP和埠,源IP地址、源埠自然就是客戶端的。

只要伺服器的 IP 或者埠不一樣,即使客戶端的IP和埠是一樣的。這個四元組也是屬於一條完全不同的新連線。比如:

連線 1:客戶端 IP 10000 伺服器 IP 10000

連線 2:客戶端 IP 10000 伺服器 IP 20000

雖然客戶端的 IP 和埠完全一樣,但由於伺服器側的埠不同,所以仍然是兩條不同的連線。問題來了,客戶端同一個埠可以連線不同的伺服器嗎?答案是可以的。客戶端只要啟動時不顯示繫結到某個埠上,核心是可以使用一個埠連不同的服務端,核心會自己進行選擇並恰當地複用的,而且完全不會產生資料混亂,因為“源 IP 地址、目標 IP 地址、源埠號以及目標埠號就能唯一性確定一個 TCP 連線”。那麼對客戶端來說,四元組裡有3個可變,自然客戶端能同時支援的連線數比伺服器還要大得多。

TCP 特性

在我們上面的講述中,存在著客戶端和服務端兩者角色,在網路通訊裡是怎麼區分的?這個就牽涉到了 TCP 的相關特性。

TCP(Transmission Control Protocol)是面向連線的通訊協議,透過三次握手建立連線,然後才能開始資料的讀寫,通訊完成時要拆除連線,由於 TCP 是面向連線的所以只能用於端到端的通訊。

TCP 提供的是一種可靠的資料流服務,資料有可能被拆分後傳送,那麼採用超時重傳機制是和應答確認機制是組成 TCP 可靠傳輸的關鍵設計。

而超時重傳機制中最最重要的就是重傳超時(RTO,Retransmission TimeOut)的時間選擇,很明顯,在工程上和現實中網路環境是十分複雜多變的,有時候可能突然的抽風,有時候可能突然的又很順暢。在資料傳送的過程中,如果用一個固定的值一直作為超時計時器的時長是非常不經濟也非常不準確的方法,這樣的話,超時的時長就需要根據網路情況動態調整,就需要取樣統計一個數據包從傳送端傳送出去到接收到這個包的回覆這段時長來動態設定重傳超時值,這個時長就是為RTT,學名 round-trip time,然後再根據這個 RTT 透過各種演算法和公式平滑RTT值後,最終確定重傳超時值。

而IP層進行資料傳輸時,是不能保證資料包按照發送的順序達到目的機器。當IP將把它們向‘上’傳送到 TCP 層後,TCP將包排序並進行錯誤檢查。TCP 資料包中包括序號和確認,所以未按照順序收到的包可以被排序,而損壞的包可以被重傳。

TCP還採用一種稱為“滑動視窗”的方式進行流量控制,所謂視窗實際表示接收能力,用以限制傳送方的傳送速度。

同時 TCP 還允許在一個 TCP 連線上,通訊的雙方可以同時傳輸資料,也就是所謂的全雙工。

面向連線的服務(例如 Telnet、FTP、rlogin、X Windows 和 SMTP)需要高度的可靠性,所以它們使用了 TCP。DNS 在某些情況下使用 TCP(傳送和接收域名資料庫),但使用 UDP傳送有關單個主機的資訊。

TCP 三次握手

TCP 提供面向有連線的通訊傳輸。面向有連線是指在資料通訊開始之前先做好兩端之間的準備工作。

所謂三次握手是指建立一個 TCP 連線時需要客戶端和伺服器端總共傳送三個包以確認

連線的建立。在 socket 程式設計中,這一過程由客戶端執行 connect 來觸發,所以網路通訊中,

發起連線的一方我們稱為客戶端,接收連線的一方我們稱之為服務端。

具體詳情:

計算機網路發展和體系結構

第一次握手:客戶端將請求報文標誌位 SYN 置為 1,請求報文的Sequence Number 欄位(簡稱 seq)中填入一個隨機值 J,並將該資料包傳送給伺服器端,客戶端進入SYN_SENT狀態,等待伺服器端確認。

第二次握手:伺服器端收到資料包後由請求報文標誌位 SYN=1 知道客戶端請求建立連線,伺服器端將應答報文標誌位 SYN 和 ACK 都置為 1,應答報文的 Acknowledgment Number欄位(簡稱 ack)中填入 ack=J+1,應答報文的 seq 中填入一個隨機值 K,並將該資料包傳送給客戶端以確認連線請求,伺服器端進入 SYN_RCVD 狀態。

第三次握手:客戶端收到應答報文後,檢查 ack 是否為 J+1,ACK 是否為 1,如果正確則將第三個報文標誌位 ACK 置為 1,ack=K+1,並將該資料包傳送給伺服器端,伺服器端檢查 ack 是否為 K+1,ACK 是否為 1,如果正確則連線建立成功,客戶端和伺服器端進入ESTABLISHED 狀態,完成三次握手,隨後客戶端與伺服器端之間可以開始傳輸資料了。

計算機網路發展和體系結構

為什麼 TCP 握手需要三次?

TCP 是可靠的傳輸控制協議,而三次握手是保證資料可靠傳輸又能提高傳輸效率的最小次數。為什麼?RFC793,也就是 TCP 的協議 RFC 中就談到了原因,這是因為:

為了實現可靠資料傳輸, TCP 協議的通訊雙方,都必須維護一個序列號, 以標識傳送出去的資料包中,哪些是已經被對方收到的。

舉例說明:傳送方在傳送資料包(假設大小為 10 byte)時, 同時送上一個序號( 假設為 500),那麼接收方收到這個資料包以後, 就可以回覆一個確認號(510 = 500 + 10) 告訴傳送方 “我已經收到了你的資料包, 你可以傳送下一個資料包, 序號從 511 開始” 。

三次握手的過程即是通訊雙方相互告知序列號起始值,並確認對方已經收到了序列號起始值的必經步驟。

如果只是兩次握手, 至多隻有連線發起方的起始序列號能被確認, 另一方選擇的序列號則得不到確認。

至於為什麼不是四次,很明顯,三次握手後,通訊的雙方都已經知道了對方序列號起始值,也確認了對方知道自己序列號起始值,第四次握手已經毫無必要了。

TCP 的三次握手的漏洞-SYN 洪泛攻擊

但是在 TCP 三次握手中是有一個缺陷,被稱為 SYN 洪泛攻擊。三次握手中有一個第二次握手,服務端向客戶端應答請求,應答請求是需要客戶端 IP 的,而且因為握手過程沒有完成,作業系統使用佇列維持這個狀態(Linux 2。2 以後,這個佇列大小引數可以透過/proc/sys/net/ipv4/tcp_max_syn_backlog 設定)。於是攻擊者就偽造這個 IP,往伺服器端狂

傳送第一次握手的內容,當然第一次握手中的客戶端 IP 地址是偽造的,從而服務端忙於進行第二次握手,但是第二次握手是不會有應答的,所以導致伺服器佇列滿,而拒絕連線。

面對這種攻擊,有以下的解決方案,最好的方案是防火牆。

無效連線監視釋放

這種方法不停監視所有的連線,包括三次握手的,還有握手一次的,反正是所有的,當達到一定(與)閾值時拆除這些連線,從而釋放系統資源。這種方法對於所有的連線一視同仁,不管是正常的還是攻擊的,所以這種方式不推薦。

延緩 TCB 分配方法

一般的做完第一次握手之後,伺服器就需要為該請求分配一個 TCB(連線控制資源),通常這個資源需要 200 多個位元組。延遲 TCB 的分配,當正常連線建立起來後再分配 TCB 則可以有效地減輕伺服器資源的消耗。

使用防火牆

防火牆在確認了連線的有效性後,才向內部的伺服器(Listener)發起SYN 請求,

TCP 四次揮手(分手)

四次揮手即終止TCP連線,就是指斷開一個TCP連線時,需要客戶端和服務端總共傳送4個包以確認連線的斷開。在socket程式設計中,這一過程由客戶端或服務端任一方執行close來觸發。

由於TCP連線是全雙工的,因此,每個方向都必須要單獨進行關閉。首先進行關閉的一方將執行主動關閉,而另一方則執行被動關閉。

計算機網路發展和體系結構

由上圖可見,TCP 建立一個連線需 3 個分節,終止一個連線則需 4 個分節。

(1)某個應用程序首先呼叫 close,我們稱該端執行主動關閉(active close)。該端的TCP於是傳送一個FIN分節,表示資料傳送完畢,應用程序進入 FIN-WAIT-1(終止等待 1)狀態。

(2)接收到這個 FIN 的對端執行被動關閉(passive close),發出確認報文。因為 FIN 的接收意味著接收端應用程序在相應連線上再無額外資料可接收,接收端進入了CLOSE-WAIT(關閉等待)狀態,這時候處於半關閉狀態,即主動關閉端已經沒有資料要傳送了,但是被動關閉端若傳送資料,主動關閉端依然要接受。這個狀態還要持續一段時間,也就是整個CLOSE-WAIT狀態持續的時間。主動關閉端收到確認報文後進入FIN-WAIT-2(終止等待 2)狀態。

(3)一段時間後,被動關閉的應用程序將呼叫close關閉它的套接字。這導致它的TCP也傳送一個FIN,表示它也沒資料需要傳送了。

(4)接收這個最終FIN的原發送端TCP(即執行主動關閉的那一端)確認這個FIN發出一個確認ACK報文,並進入了TIME-WAIT(時間等待)狀態。注意此時TCP連線還沒有釋放,必須經過 2MSL(最長報文段壽命/最長分節生命期max segement lifetime,MSL是任何IP資料報能夠在因特網中存活的最長時間,任何TCP實現都必須為MSL選擇一個值。RFC1122[Braden 1989]的建議值是 2 分鐘,不過源自Berkelcy的實現傳統上改用30秒這個值。

這意味著 TIME_WAIT 狀態的持續時間在1分鐘到4分鐘之間)的時間後,當主動關閉端撤銷相應的TCB後,才進入CLOSED狀態。

(5) 被動關閉端只要收到了客戶端發出的確認,立即進入CLOSED狀態。同樣,撤銷TCB後,就結束了這次的TCP連線。可以看到,被動關閉端結束TCP連線的時間要比主動關閉端早一些。

既然每個方向都需要一個FIN和一個ACK,因此通常需要4個分節。我們使用限定詞“通常”是因為:某些情形下步驟1的FIN隨資料一起傳送;另外,步驟2和步驟3傳送的分節都出自執行被動關閉那-一端,有可能被合併成一個分節。

為什麼 TCP 的揮手需要四次?

TCP是全雙工的連線,必須兩端同時關閉連線,連線才算真正關閉。

如果一方已經準備關閉寫,但是它還可以讀另一方傳送的資料。傳送給 FIN 結束報文給對方,對方收到後,回覆ACK報文。當這方也已經寫完了準備關閉,傳送 FIN 報文,對方回覆ACK。兩端都關閉,TCP連線正常關閉。

為什麼需要 TIME-WAIT 狀態?

TIME_WAIT 狀態存在的原因有兩點

1、可靠的終止 TCP 連線。

2、保證讓遲來的 TCP 報文有足夠的時間被識別並丟棄。

根據前面的四次握手的描述,我們知道,客戶端收到伺服器的連線釋放的FIN報文後,必須發出確認。如最後這個ACK確認報文丟失,那麼伺服器沒有收到這個 ACK 確認報文,就要重發FIN連線釋放報文,客戶端要在某個狀態等待這個FIN 連線釋放報文段然後回覆確認報文段,這樣才能可靠的終止TCP連線。

在Linux系統上,一個TCP埠不能被同時開啟多次,當一個TCP連線處於TIME_WAIT狀態時,我們無法使用該連結的埠來建立一個新連線。反過來思考,如果不存在TIME_WAIT狀態,則應用程式能過立即建立一個和剛關閉的連線相似的連線(這裡的相似,是指他們具有相同的IP地址和埠號)。這個新的、和原來相似的連線被稱為原來連線的化身。新的化身可能受到屬於原來連線攜帶應用程式資料的TCP報文段(遲到的報文段),這顯然是不該發生的。這是 TIME_WAIT狀態存在的第二個原因。