韓老師計算機網絡-5傳輸層

一 傳輸層概述

在這裏插入圖片描述在這裏插入圖片描述在這裏插入圖片描述

二 傳輸層和應用層之間的關係

端口複用。
在這裏插入圖片描述

網絡層用協議號NSAP去區分上一層,傳輸層用端口號區分上一層

2.1 端口

在這裏插入圖片描述

在這裏插入圖片描述

  • 登記端口:開發程序的人註冊端口,不讓其他人用

    端口號:0-65535
    http—TCP+80端口
    https–TCP+443端口
    ftp–TCP+21端口
    SMTP–TCP+25端口
    POP3–TCP+110端口
    RDP–TCP+3389端口
    SQL–TCP+1433端口
    DNS–UDP+53端口 OR TCP+53端口
    共享文件夾–TCP+445端口

應用層協議和服務之間的關係:對外服務運行之後在TCP或UDP的某個端口監聽客戶端的請求。用端口來區分服務,用ip地址來區分計算機。讓服務器只開提供服務的那些端口別的端口不開可以增強服務器的安全,其他主機就不能用其他端口來偷用他的服務器(TCP/IP篩選)

2.2 windows防火牆的作用

攔截外來的請求但是自己可以訪問外部的網絡,別人進不來我可以出去。但防火牆攔不了木馬程序

三 UDP

3.1 UDP與TCP

UDP:一個數據包就能完成數據通信,不建立會話,不可靠傳輸;用於多播

在這裏插入圖片描述在這裏插入圖片描述

QQ聊天:不建立會話,不需要雙方“喂”一下,不可靠傳輸(通知用戶發送失敗)–>UDP
QQ傳文件:TCP
訪問網站:不可能一個數據包傳過來–>TCP

3.2 UDP協議的報文格式

在這裏插入圖片描述
UDP報文對應用層報文既不合並和不拆分,直接用

首部放端口信息、長度信息和差錯檢測信息,8個字節。

僞首部(IP數據報首部的部分信息)在計算校驗和時會加上,傳輸時會去掉
在這裏插入圖片描述
在這裏插入圖片描述在這裏插入圖片描述
在這裏插入圖片描述

UDP的特點

在這裏插入圖片描述在這裏插入圖片描述

四 TCP

4.1 TCP概述

TCP:分段、編號、建立會話 netstat -n

從這三個角度學習:可靠傳輸、流量控制(接收方讓發送方慢一點)、擁塞控制
在這裏插入圖片描述
面向連接:在傳輸之前要建立連接

點到點:不多播不廣播

全雙工通信:A到BB到A,A說話B要給A反饋,證明B在收。平時打電話老師給你安排任務你會說“嗯嗯”

在這裏插入圖片描述
在這裏插入圖片描述

4.2 TCP報文格式

在這裏插入圖片描述

與UDP一樣需要端口信息和校驗和信息;除此之外還需要分組所需的序號、以及可靠傳輸使用的確認、窗口

  • 序號:是該分組的第一個字節在整個文件中是第幾個字節(TCP面向字節流)

  • 確認號:接受方通知發送方此次發送我已收到,下一次發送方應該給我發文件中以第幾個字節開始的分組(用發送方發的序號和分組長度可以計算出來)

  • 數據偏移:TCP報文段從第多少個數據開始就是數據了(因爲首部除了固定的20個字節外還有可選部分)

  • 可選部分(選項+填充)最多40個字節,這是因爲數據偏移可以表示60個字節

  • 標誌位URG:1在發送方優先發送

  • 標誌位ACK:0什麼也沒收到但是我要發信息(客戶端建立會話時)/1確認收到

  • 標誌位SYN:同步:1建立會話

  • 標誌位PSH:1在接收端先讀,直接給應用層

  • 標誌位RST:1斷開連接

  • 標誌位FIN:1釋放連接

  • 校驗和:與UDP一樣

  • 緊急指針:指明哪段數據是緊急處理的,在URG=1時纔有效

  • 窗口:該主機的接收窗口大小。因爲要根據接收窗口確定發送窗口,保證發送的數據小於接收窗口
    在這裏插入圖片描述在這裏插入圖片描述

4.3 TCP如何實現可靠傳輸

可靠傳輸–發啥收啥,不丟包

4.3.1 停止等待機制

a) 過去的路上出了問題:
在這裏插入圖片描述

等B回我跟我確認了我才繼續發下一個包,長時間收不到確認就重傳,只要不確認我就一直重傳
在這裏插入圖片描述

b) 回去的路上出了問題:
在這裏插入圖片描述

核心是:

對於發送方只要你沒告訴我收到我就認爲你沒收到一直超時重傳,一旦收到了你的確認我就發下一個,之後再收到你相同的確認我就無視他;

對於接受方只要我收到了我就確認並收下,哪怕收到了相同的我也再次確認,但是我會丟棄相同的。

在這裏插入圖片描述
在這裏插入圖片描述在這裏插入圖片描述

4.3.2 滑動窗口

在這裏插入圖片描述在這裏插入圖片描述

發送條件:只要在窗口內的數據包就能發;

窗口滑動條件:從窗口左邊起連續N個數據報都收到了ACK,則窗口可以移動N個包的位移

(如果只收到窗口左邊第一個包的ACK,那窗口往右移一格;

如果收到窗口左起三個數據包,則窗口往右移三格;

如收到窗口左起第一個和第三個ACK,此時從窗口左起連續1個數據包收到ACK,第二個ACK沒收到,收到第三個ACK也沒用,窗口右移一格;

如收到窗口左起第二個第三個第四個ACK但是沒收到第一個ACK,那是從窗口左起連續0個數據報的ACK,第一個ACK收不到就是不能後面的收到了也沒用,還是不能右移)

1 累計確認

在這裏插入圖片描述

B說我收到了第三個證明第一二三個我都收到了。如果一二四都收到了但三丟了,此時B會回覆前兩個我都收到了。這種方法一次ACK說明了這個ACK之前的數據包我也收到了。

2 舉例

a 無丟失情況
  1. 接收窗口決定發送窗口大小
    在這裏插入圖片描述

  2. 只要在發送窗口內的都可以在未接到B確認前就發送

在這裏插入圖片描述

  1. B進行累計確認(從第一個到連續的第N個,不連續的不算)

在這裏插入圖片描述

  1. A的發送窗口右移,並將已收到確認的數據刪除

在這裏插入圖片描述

  1. 接收窗口右移,並將已累計確認的數據交付上層應用

在這裏插入圖片描述

b 有丟失的情況:

在這裏插入圖片描述在這裏插入圖片描述

4.3.3 超時重傳時間選擇

網絡堵塞情況是變化的,所以要加權平均

在這裏插入圖片描述

4.4 TCP如何實現流量控制

解決通訊兩端處理速度不一致的問題

在接收端處理接收數據時就將接收窗口的大小減小,由於接收窗口決定發送窗口,因此發送窗口也減小了,於是實現流量控制。

4.5 TCP如何實現擁塞控制

4.5.1 網絡擁塞的概念

擁塞是網絡太擁堵了,跟網絡的所有主機都有關。而流量控制只跟接收兩個主機有關。
在這裏插入圖片描述在這裏插入圖片描述

4.5.2 慢開始擁塞避免算法概述

只有發送端檢測網絡擁塞狀態
在這裏插入圖片描述
在這裏插入圖片描述

擁塞窗口大小變化:指數增長–>加法增大–>慢開始門限乘法減小+重新慢開始
在這裏插入圖片描述在這裏插入圖片描述在這裏插入圖片描述

在這裏插入圖片描述

剛開始不知道網絡堵不堵,所以剛開始窗口小一點,如果網絡情況好,就不斷指數增長

4.5.3 慢開始快重傳快恢復擁塞避免算法概述

接收方和發送方配合檢測擁塞狀態
在這裏插入圖片描述

在這裏插入圖片描述在這裏插入圖片描述

五 TCP連接

5.1 三次握手

在這裏插入圖片描述
在這裏插入圖片描述

建立連接(前兩次握手):同步,SYN=1

第三次握手開始SYN=0

SYN–建立連接

ACK–確認收到

seq–我發的是文件中的第幾個字節

ack–我下次要收到第幾個字節

第三次握手的作用是讓B知道這個連接已經建立。如果沒有第三次握手可能A發了兩次連接,一個先到B,B建立了連接,一個後到B,B也建立了連接。都等待A發數據。但是A看到之後的確認後就無視了,因爲之前已經建立了一個連接了,這就造成第二個連接中B一直在等待A發數據但其實沒有數據,但B也不知道這個連接A不用。加上第三次握手B就有了一個確認機制,如果超時未收到A的確認那這個連接就釋放了。最常見的情況就是我用一個假地址訪問服務器,服務器向一個不存在的主機第二次握手,沒有第三次握手服務器就一直要等待。
在這裏插入圖片描述在這裏插入圖片描述在這裏插入圖片描述

5.2 四次揮手

FIN–我沒有要說的了,我都發完了,申請主動關閉連接(我還有話沒話)
在這裏插入圖片描述在這裏插入圖片描述在這裏插入圖片描述在這裏插入圖片描述

TIME-WAIT是防止最後一次揮手在網絡中丟失

1. 三次握手

三次握手(Three-way Handshake)其實就是指建立一個TCP連接時,需要客戶端和服務器總共發送3個包。進行三次握手的主要作用就是爲了確認雙方的接收能力和發送能力是否正常、指定自己的初始化序列號爲後面的可靠性傳送做準備。實質上其實就是連接服務器指定端口,建立TCP連接,並同步連接雙方的序列號和確認號,交換TCP窗口大小信息。

剛開始客戶端處於 Closed 的狀態,服務端處於 Listen 狀態。

進行三次握手:

第一次握手:客戶端給服務端發一個 SYN 報文,並指明客戶端的初始化序列號 ISN©。此時客戶端處於 SYN_SEND 狀態。

首部的同步位SYN=1,初始序號seq=x,SYN=1的報文段不能攜帶數據,但要消耗掉一個序號。

第二次握手:服務器收到客戶端的 SYN 報文之後,會以自己的 SYN 報文作爲應答,並且也是指定了自己的初始化序列號 ISN(s)。同時會把客戶端的 ISN + 1 作爲ACK 的值,表示自己已經收到了客戶端的 SYN,此時服務器處於 SYN_REVD 的狀態。

在確認報文段中SYN=1,ACK=1,確認號ack=x+1,初始序號seq=y。

第三次握手:客戶端收到 SYN 報文之後,會發送一個 ACK 報文,當然,也是一樣把服務器的 ISN + 1 作爲 ACK 的值,表示已經收到了服務端的 SYN 報文,此時客戶端處於 ESTABLISHED 狀態。服務器收到 ACK 報文之後,也處於 ESTABLISHED 狀態,此時,雙方已建立起了連接。

確認報文段ACK=1,確認號ack=y+1,序號seq=x+1(初始爲seq=x,第二個報文段所以要+1),ACK報文段可以攜帶數據,不攜帶數據則不消耗序號。

發送第一個SYN的一端將執行主動打開(active open),接收這個SYN併發回下一個SYN的另一端執行被動打開(passive open)。

在socket編程中,客戶端執行connect()時,將觸發三次握手。
在這裏插入圖片描述

1.1 爲什麼需要三次握手,兩次不行嗎?

弄清這個問題,我們需要先弄明白三次握手的目的是什麼,能不能只用兩次握手來達到同樣的目的。

第一次握手:客戶端發送網絡包,服務端收到了。

這樣服務端就能得出結論:客戶端的發送能力、服務端的接收能力是正常的。

第二次握手:服務端發包,客戶端收到了。

這樣客戶端就能得出結論:服務端的接收、發送能力,客戶端的接收、發送能力是正常的。不過此時服務器並不能確認客戶端的接收能力是否正常。

第三次握手:客戶端發包,服務端收到了。

這樣服務端就能得出結論:客戶端的接收、發送能力正常,服務器自己的發送、接收能力也正常。

因此,需要三次握手才能確認雙方的接收與發送能力是否正常。

試想如果是用兩次握手,則會出現下面這種情況:

如客戶端發出連接請求,但因連接請求報文丟失而未收到確認,於是客戶端再重傳一次連接請求。後來收到了確認,建立了連接。數據傳輸完畢後,就釋放了連接,客戶端共發出了兩個連接請求報文段,其中第一個丟失,第二個到達了服務端,但是第一個丟失的報文段只是在某些網絡結點長時間滯留了,延誤到連接釋放以後的某個時間纔到達服務端,此時服務端誤認爲客戶端又發出一次新的連接請求,於是就向客戶端發出確認報文段,同意建立連接,不採用三次握手,只要服務端發出確認,就建立新的連接了,此時客戶端忽略服務端發來的確認,也不發送數據,則服務端一致等待客戶端發送數據,浪費資源。

1.2 什麼是半連接隊列?

服務器第一次收到客戶端的 SYN 之後,就會處於 SYN_RCVD 狀態,此時雙方還沒有完全建立其連接,服務器會把此種狀態下請求連接放在一個隊列裏,我們把這種隊列稱之爲半連接隊列。

當然還有一個全連接隊列,就是已經完成三次握手,建立起連接的就會放在全連接隊列中。如果隊列滿了就有可能會出現丟包現象。

這裏在補充一點關於SYN-ACK 重傳次數的問題:

服務器發送完SYN-ACK包,如果未收到客戶確認包,服務器進行首次重傳,等待一段時間仍未收到客戶確認包,進行第二次重傳。如果重傳次數超過系統規定的最大重傳次數,系統將該連接信息從半連接隊列中刪除。

注意,每次重傳等待的時間不一定相同,一般會是指數增長,例如間隔時間爲 1s,2s,4s,8s…

1.3 ISN(Initial Sequence Number)是固定的嗎?

當一端爲建立連接而發送它的SYN時,它爲連接選擇一個初始序號。ISN隨時間而變化,因此每個連接都將具有不同的ISN。ISN可以看作是一個32比特的計數器,每4ms加1 。這樣選擇序號的目的在於防止在網絡中被延遲的分組在以後又被傳送,而導致某個連接的一方對它做錯誤的解釋。

三次握手的其中一個重要功能是客戶端和服務端交換 ISN(Initial Sequence Number),以便讓對方知道接下來接收數據的時候如何按序列號組裝數據。如果 ISN 是固定的,攻擊者很容易猜出後續的確認號,因此 ISN 是動態生成的。

1.4 三次握手過程中可以攜帶數據嗎?

其實第三次握手的時候,是可以攜帶數據的。但是,第一次、第二次握手不可以攜帶數據

爲什麼這樣呢?大家可以想一個問題,假如第一次握手可以攜帶數據的話,如果有人要惡意攻擊服務器,那他每次都在第一次握手中的 SYN 報文中放入大量的數據。因爲攻擊者根本就不理服務器的接收、發送能力是否正常,然後瘋狂着重複發 SYN 報文的話,這會讓服務器花費很多時間、內存空間來接收這些報文。

也就是說,第一次握手不可以放數據,其中一個簡單的原因就是會讓服務器更加容易受到攻擊了。而對於第三次的話,此時客戶端已經處於 ESTABLISHED 狀態。對於客戶端來說,他已經建立起連接了,並且也已經知道服務器的接收、發送能力是正常的了,所以能攜帶數據也沒啥毛病。

1.5 SYN攻擊是什麼?

服務器端的資源分配是在二次握手時分配的,而客戶端的資源是在完成三次握手時分配的,所以服務器容易受到SYN洪泛攻擊。SYN攻擊就是Client在短時間內僞造大量不存在的IP地址,並向Server不斷地發送SYN包,Server則回覆確認包,並等待Client確認,由於源地址不存在,因此Server需要不斷重發直至超時,這些僞造的SYN包將長時間佔用未連接隊列,導致正常的SYN請求因爲隊列滿而被丟棄,從而引起網絡擁塞甚至系統癱瘓。SYN 攻擊是一種典型的 DoS/DDoS 攻擊。

檢測 SYN 攻擊非常的方便,當你在服務器上看到大量的半連接狀態時,特別是源IP地址是隨機的,基本上可以斷定這是一次SYN攻擊。在 Linux/Unix 上可以使用系統自帶的 netstats 命令來檢測 SYN 攻擊。

netstat -n -p TCP | grep SYN_RECV

常見的防禦 SYN 攻擊的方法有如下幾種:

  • 縮短超時(SYN Timeout)時間
  • 增加最大半連接數
  • 過濾網關防護
  • SYN cookies技術

2. 四次揮手

建立一個連接需要三次握手,而終止一個連接要經過四次揮手(也有將四次揮手叫做四次握手的)。這由TCP的半關閉(half-close)造成的。所謂的半關閉,其實就是TCP提供了連接的一端在結束它的發送後還能接收來自另一端數據的能力。

TCP 的連接的拆除需要發送四個包,因此稱爲四次揮手(Four-way handshake),客戶端或服務器均可主動發起揮手動作。

剛開始雙方都處於 ESTABLISHED 狀態,假如是客戶端先發起關閉請求。四次揮手的過程如下:

第一次揮手:客戶端發送一個 FIN 報文,報文中會指定一個序列號。此時客戶端處於 FIN_WAIT1 狀態。

即發出連接釋放報文段(FIN=1,序號seq=u),並停止再發送數據,主動關閉TCP連接,進入FIN_WAIT1(終止等待1)狀態,等待服務端的確認。

第二次揮手:服務端收到 FIN 之後,會發送 ACK 報文,且把客戶端的序列號值 +1 作爲 ACK 報文的序列號值,表明已經收到客戶端的報文了,此時服務端處於 CLOSE_WAIT 狀態。

即服務端收到連接釋放報文段後即發出確認報文段(ACK=1,確認號ack=u+1,序號seq=v),服務端進入CLOSE_WAIT(關閉等待)狀態,此時的TCP處於半關閉狀態,客戶端到服務端的連接釋放。客戶端收到服務端的確認後,進入FIN_WAIT2(終止等待2)狀態,等待服務端發出的連接釋放報文段。

第三次揮手:如果服務端也想斷開連接了,和客戶端的第一次揮手一樣,發給 FIN 報文,且指定一個序列號。此時服務端處於 LAST_ACK 的狀態。

即服務端沒有要向客戶端發出的數據,服務端發出連接釋放報文段(FIN=1,ACK=1,序號seq=w,確認號ack=u+1),服務端進入LAST_ACK(最後確認)狀態,等待客戶端的確認。

第四次揮手:客戶端收到 FIN 之後,一樣發送一個 ACK 報文作爲應答,且把服務端的序列號值 +1 作爲自己 ACK 報文的序列號值,此時客戶端處於 TIME_WAIT 狀態。需要過一陣子以確保服務端收到自己的 ACK 報文之後纔會進入 CLOSED 狀態,服務端收到 ACK 報文之後,就處於關閉連接了,處於 CLOSED 狀態。

即客戶端收到服務端的連接釋放報文段後,對此發出確認報文段(ACK=1,seq=u+1,ack=w+1),客戶端進入TIME_WAIT(時間等待)狀態。此時TCP未釋放掉,需要經過時間等待計時器設置的時間2MSL後,客戶端才進入CLOSED狀態。

收到一個FIN只意味着在這一方向上沒有數據流動。客戶端執行主動關閉並進入TIME_WAIT是正常的,服務端通常執行被動關閉,不會進入TIME_WAIT狀態。

在socket編程中,任何一方執行close()操作即可產生揮手操作。

在這裏插入圖片描述

2.1 揮手爲什麼需要四次?

因爲當服務端收到客戶端的SYN連接請求報文後,可以直接發送SYN+ACK報文。其中ACK報文是用來應答的,SYN報文是用來同步的。但是關閉連接時,當服務端收到FIN報文時,很可能並不會立即關閉SOCKET,所以只能先回復一個ACK報文,告訴客戶端,“你發的FIN報文我收到了”。只有等到我服務端所有的報文都發送完了,我才能發送FIN報文,因此不能一起發送。故需要四次揮手。

2.2 2MSL等待狀態

TIME_WAIT狀態也成爲2MSL等待狀態。每個具體TCP實現必須選擇一個報文段最大生存時間MSL(Maximum Segment Lifetime),它是任何報文段被丟棄前在網絡內的最長時間。這個時間是有限的,因爲TCP報文段以IP數據報在網絡內傳輸,而IP數據報則有限制其生存時間的TTL字段。

對一個具體實現所給定的MSL值,處理的原則是:當TCP執行一個主動關閉,併發回最後一個ACK,該連接必須在TIME_WAIT狀態停留的時間爲2倍的MSL。這樣可讓TCP再次發送最後的ACK以防這個ACK丟失(另一端超時並重發最後的FIN)。

這種2MSL等待的另一個結果是這個TCP連接在2MSL等待期間,定義這個連接的插口(客戶的IP地址和端口號,服務器的IP地址和端口號)不能再被使用。這個連接只能在2MSL結束後才能再被使用。

2.3 四次揮手釋放連接時,等待2MSL的意義?

MSL是Maximum Segment Lifetime的英文縮寫,可譯爲“最長報文段壽命”,它是任何報文在網絡上存在的最長時間,超過這個時間報文將被丟棄。

爲了保證客戶端發送的最後一個ACK報文段能夠到達服務器。因爲這個ACK有可能丟失,從而導致處在LAST-ACK狀態的服務器收不到對FIN-ACK的確認報文。服務器會超時重傳這個FIN-ACK,接着客戶端再重傳一次確認,重新啓動時間等待計時器。最後客戶端和服務器都能正常的關閉。假設客戶端不等待2MSL,而是在發送完ACK之後直接釋放關閉,一但這個ACK丟失的話,服務器就無法正常的進入關閉連接狀態。

兩個理由:

  • 保證客戶端發送的最後一個ACK報文段能夠到達服務端。

這個ACK報文段有可能丟失,使得處於LAST-ACK狀態的B收不到對已發送的FIN+ACK報文段的確認,服務端超時重傳FIN+ACK報文段,而客戶端能在2MSL時間內收到這個重傳的FIN+ACK報文段,接着客戶端重傳一次確認,重新啓動2MSL計時器,最後客戶端和服務端都進入到CLOSED狀態,若客戶端在TIME-WAIT狀態不等待一段時間,而是發送完ACK報文段後立即釋放連接,則無法收到服務端重傳的FIN+ACK報文段,所以不會再發送一次確認報文段,則服務端無法正常進入到CLOSED狀態。

  • 防止“已失效的連接請求報文段”出現在本連接中。

客戶端在發送完最後一個ACK報文段後,再經過2MSL,就可以使本連接持續的時間內所產生的所有報文段都從網絡中消失,使下一個新的連接中不會出現這種舊的連接請求報文段。

2.4 爲什麼TIME_WAIT狀態需要經過2MSL才能返回到CLOSE狀態?

理論上,四個報文都發送完畢,就可以直接進入CLOSE狀態了,但是可能網絡是不可靠的,有可能最後一個ACK丟失。所以TIME_WAIT狀態就是用來重發可能丟失的ACK報文。

3. 總結

《TCP/IP詳解 卷1:協議》有一張TCP狀態變遷圖,很具有代表性,有助於大家理解三次握手和四次揮手的狀態變化。如下圖所示,粗的實線箭頭表示正常的客戶端狀態變遷,粗的虛線箭頭表示正常的服務器狀態變遷。

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章