終於可以把TCP講清楚了


在這裏插入圖片描述

知識回顧

OSI七層模型 TCP/IP協議棧

在這裏插入圖片描述

應用程(數據 data):通過人機交互提供各種各樣的服務

表示層(數據 data):爲上層用戶解決用戶信息語法問題 編碼 解碼 加密(即時數據) 解密

會話層(數據 data):發現 建立 維持 終止 會話進程 建立虛擬的端到端的鏈接

傳輸層(數據段 segment): 1.數據分段 2.使用端口號區分不同的服務 3.可靠傳輸

網絡層(數據包 packet): 1.使用IP地址進行邏輯尋址 2.建立兩個節點間的連接

數據鏈路層(數據幀 frame):

1.MAC 媒介訪問控制層

​ 通過MAC地址進行物理尋址

2.LLC 邏輯鏈路層

​ 爲上層提供FCS校驗

​ 數據分幀

物理層(比特流 bit):定義電氣、電壓、接口規範,光學特性

總結:

上三層爲應用程序對數據進行加工和處理——數據流層

下四層爲數據傳輸層面——傳輸流層


TCP詳解

TCP處於OSI的第四層,即傳輸層

四層是傳輸層,作用有以下三點

1.用於區分上層不同的服務,採用端口號來區分
	0-65535 1-1024(著名端口) 1024-65535(動態端口、高端口)
	
2.提供可靠的傳輸機制 確認 重傳 排序 流控
	三次握手
	四次斷開
	
3.數據分段
	MSS 最大段長度	 1480Byte
	MTU 最大傳輸端元	1500Byte
	一個是在傳輸過程中 一個是在分割數據過程中
常見端口號
FTP    文件傳輸協議	 TCP 21
Telnet  遠程登錄      TCP 23
HTTP   超文本傳輸協議 	TCP 80 
DNS    域名解析系統    UDP/TCP 53
HTTPS  安全HTTP       TCP 443

1.1 TCP數據包結構詳解

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

字段解釋

1.端口號:用來標識同一臺計算機的不同的應用進程

​ 源端口:源端口和IP地址的作用是標識報文的返回地址

​ 目的端口:指明接收方計算機上的應用程序接口

TCP報頭中的源端口號和目的端口號同IP數據報中的源IP與目的IP唯一確定一條TCP連接。

2.序號和確認號seq、ackseq

​ 序號是TCP可靠傳輸的關鍵部分。序號是本報文段發送的數據組的第一個字節的序號。在TCP傳送的流中,每一個字節一個序號。比如說,一個報文段的序號爲300,此報文段數據部分共有100字節,則下一個報文段的序號爲400。所以序號確保了TCP傳輸的有序性

​ 確認號是期望收到對方下一個報文的第一個數據字節的序號,表明該序號之前的所有數據已經正確無誤的收到。確認號只有當ACK標誌爲1時纔有效。

什麼是ACK標誌?
	TCP包頭的數據結構中的第4行 URG、ACK、PSH、RST、SYN、FIN這些都是標誌位,如當URG爲1是,緊急指針纔有效

3.數據偏移/首部長度

​ 由於首部可能含有可選項內容,因此TCP報頭的長度是不確定的,報頭不包含任何任選字段則長度爲20字節,4位首部長度字段所能表示的最大值爲1111,轉化爲10進製爲15,15*32/8 = 60,故報頭最大長度爲60字節。首部長度也叫數據偏移,是因爲首部長度實際上指示了數據區在報文段中的起始偏移值。

4.保留

​ 爲以後做打算,現在置爲0

5.控制位

1)URG(urgent):緊急指針標誌,爲1時表示緊急指針有效,告訴系統此報文段中有緊急數據,爲0則忽略緊急指針。
2)ACK(acknowledge):確認序號標誌,爲1時表示確認號有效,爲0表示報文中不含確認信息,忽略確認號字段。TCP規定,在連接建立後所有報文的傳輸都必須把ACK置1
3)PSH(push):push標誌,爲1表示是帶有push標誌的數據,指示接收方在接收到該報文段以後,應儘快將這個報文段交給應用程序,而不是在緩衝區排隊。
4)RST(reset):重置連接標誌,用於重置由於主機崩潰或其他原因而出現錯誤的連接。或者用於拒絕非法的報文段和拒絕連接請求。
5)SYN (Synchronize Sequence Numbers):同步序號,用於建立連接過程,在連接請求中,SYN=1和ACK=0表示該數據段沒有使用捎帶的確認域,而連接應答捎帶一個確認,即SYN=1和ACK=1。說白了就是,當SYN=1,ACK=0,表明是連接請求報文,若同意連接,則響應報文中應該使SYN=1,ACK=1
6)FIN(finish):finish標誌,用於釋放連接,爲1時表示發送方已經沒有數據發送了,即關閉本方數據流。

6.窗口

​ 滑動窗口大小,用來告知發送端接受端的緩存大小,以此控制發送端發送數據的速率,從而達到流量控制窗口大小時一個16bit字段,因而窗口大小最大爲65535

7.校驗和

​ 奇偶校驗,此校驗和是對整個的 TCP 報文段,包括 TCP 頭部和 TCP 數據,以 16 位字進行計算所得。由發送端計算和存儲,並由接收端進行驗證。

注意:數據鏈路層,網絡層、還有傳輸層的這種校驗只是爲了確認數據包的損壞與否,並沒有牽扯到安全加密層面

8.緊急指針

​ 只有當控制位 URG 標誌置 1 時緊急指針纔有效。緊急指針是一個正的偏移量,和順序號字段中的值相加表示緊急數據最後一個字節的序號。 TCP 的緊急方式是發送端向另一端發送緊急數據的一種方式。

9.選項和填充

​ 最常見的可選字段是最長報文大小,又稱爲MSS(Maximum Segment Size),每個連接方通常都在通信的第一個報文段(爲建立連接而設置SYN標誌爲1的那個段)中指明這個選項,它表示本端所能接受的最大報文段的長度。選項長度不一定是32位的整數倍,所以要加填充位,即在這個字段中加入額外的零,以保證TCP頭是32的整數倍。

10、數據部分

​ TCP 報文段中的數據部分是可選的。在一個連接建立和一個連接終止時,雙方交換的報文段僅有 TCP 首部。如果一方沒有數據要發送,也使用沒有任何數據的首部來確認收到的數據。在處理超時的許多情況中,也會發送不帶任何數據的報文段。

1.2 TCP三次握手

在這裏插入圖片描述

第一次握手:

​ 建立連接時,客戶端首先向服務器發送一個SYN=1用於請求連接,seq=x的建立TCP連接的請求,並進入SYN-SENT狀態

第二次握手:

​ 服務器向客戶端迴應一個SYN=1用於請求連接,ACK=1用於確認收到了客戶端的SYN,且使ackseq有效,seq=y,ack=x+1用於期待下次收到的seq,並進入SYN-RCVD狀態

第三次握手:

​ 客戶端收到服務器的SYN+ACK包,並向服務器迴應一個ACK=1用於確認收到了服務器發送的SYN,並回應seq爲第二次握手時服務器發送的ack爲x+1,在發送一個ack=y+1,即期望服務器下次發送的seq;至服務器收到這些包後,TCP的連接就建立完成了

狀態詳解:

未連接隊列

​ 在三次握手協議中,服務器維護一個未連接隊列,該隊列爲每個客戶端的SYN包(syn=1)開設一個條目,該條目表明服務器已收到SYN包,並向客戶發出確認,正在等待客戶的確認包。這些條目所標識的連接在服務器處於SYN_RECV狀態(SYN-received),當服務器收到客戶的確認包時,刪除該條目,服務器進入ESTABLISHED狀態。

TIME_WAIT狀態

TIME_WAIT狀態存在有兩個原因。

<1>可靠終止TCP連接。如果最後一個ACK報文因爲網絡原因被丟棄,此時server因爲沒有收到ACK而超時重傳FIN報文,處於TIME_WAIT狀態的client可以繼續對FIN報文做回覆,向server發送ACK報文。

<2>保證讓遲來的TCP報文段有足夠的時間被識別和丟棄。連接結束了,網絡中的延遲報文也應該被丟棄掉,以免影響立刻建立的新連接。

追問:爲什麼需要三次?

TCP是可靠的傳輸控制協議,三次握手能保證數據可靠傳輸又能提高傳輸效率。

如果TCP的握手是兩次:

<1>如果client發給server的SYN報文因爲網絡原因,延遲發送。由於client沒有收到server對SYN的確認報文,會重發SYN報文,服務器和回覆ACK,連接建立。數據發送完畢,這條連接被正常關閉。這時,延遲的SYN報文發到了server,server誤以爲這是client重新發送的同步報文,又回覆了一個ACK,和client建立了連接。

<2>如果server給client發送的ACK報文因爲網絡原因,報文被丟棄,此時server認爲已經建立好連接,但是client沒有收到確認報文,認爲沒有建立好連接。client會重發SYN報文,此時server已經處於就緒狀態,認爲已經建立好連接。

如果TCP的握手是四次:

1.client給server發送SYN同步報文;

2.server收到SYN後,給client回覆ACK確認報文;

3.server給client發送SYN同步報文;

4.client給server發送ACK確認報文。

第2.3步之間,server和client沒有任何的數據交互,分開發送相當於多發了一次TCP報文段,SYN和ACK標識只是TCP報頭的一個標識位。很明顯,這兩步可以合併,從而提高連接的速度和效率。

1.3 TCP四次斷開

在這裏插入圖片描述
爲什麼是三次握手?爲什麼不能是2、4次?

兩次 導致信息不匹配

四次 把TCP會話重複發送,浪費帶寬資源,沒有意義

SYN,ACK種是不攜帶數據的,
SYN是用來同步序列號的
ACK是用來確認收到的SYN的,用於確認包的

爲了提高連接的速度和效率。

1.4 TCP定時器

  • 建立連接定時器(connection-establishment timer)
  • 重傳定時器(retransmission timer)
  • 延遲應答定時器(delayed ACK timer)
  • 堅持定時器(persist timer)
  • 保活定時器(keepalive timer)
  • FIN_WAIT_2定時器(FIN_WAIT_2 timer)
  • TIME_WAIT定時器 (TIME_WAIT timer, 也叫2MSL timer)

建立連接定時器(connection-establishment timer)

  顧名思義,這個定時器是在建立連接的時候使用的, 我們知道, TCP建立連接需要3次握手, 如下圖所示:
在這裏插入圖片描述
  建立連接的過程中,在發送SYN時, 會啓動一個定時器(默認應該是3秒),如果SYN包丟失了, 那麼3秒以後會重新發送SYN包的(當然還會啓動一個新的定時器, 設置成6秒超時),當然也不會一直沒完沒了的發SYN包, 在/proc/sys/net/ipv4/tcp_syn_retries 可以設置到底要重新發送幾次SYN包。
   
重傳定時器(retransmission timer)

  重傳定時器在TCP發送數據時設定,在計時器超時後沒有收到返回的確認ACK,發送端就會重新發送隊列中需要重傳的報文段。使用RTO重傳計時器一般有如下規則:

  1. 當TCP發送了位於發送隊列最前端的報文段後就啓動這個RTO計時器;
  2. 如果隊列爲空則停止計時器,否則重啓計時器;
  3. 當計時器超時後,TCP會重傳發送隊列最前端的報文段;
  4. 當一個或者多個報文段被累計確認後,這個或者這些報文段會被清除出隊列

  重傳計時器保證了接收端能夠接收到丟失的報文段,繼而保證了接收端交付給接收進程的數據始終的有序完整的。因爲接收端永遠不會把一個失序不完整的報文段交付給接收進程。

延遲應答定時器(delayed ACK timer)
  延遲應答也被稱爲捎帶ACK, 這個定時器是在延遲應答的時候使用的。

	爲什麼要延遲應答呢?
  延遲應答是爲了提高網絡傳輸的效率。

  舉例說明,比如服務端收到客戶端的數據後, 不是立刻回ACK給客戶端,而是等一段時間(一般最大200ms),這樣如果服務端要是有數據需要發給客戶端,那麼這個ACK就和服務端的數據一起發給客戶端了,這樣比立即回給客戶端一個ACK節省了一個數據包。

堅持定時器(persist timer)

  我們已經知道TCP通過讓接收方指明希望從發送方接收的數據字節數(即窗口大小)來進行流量控制。如果窗口大小爲 0會發生什麼情況呢?這將有效地阻止發送方傳送數據,直到窗口變爲非0爲止。接收端窗口變爲非0後,就會發送一個確認ACK指明需要的報文段序號以及窗口大小。

  如果這個確認ACK丟失了,則雙方就有可能因爲等待對方而使連接終止:接收方等待接收數據(因爲它已經向發送方通告了一個非0的窗口),而發送方在等待允許它繼續發送數據的窗口更新。爲防止這種死鎖情況的發生,發送方使用一個堅持定時器 (persist timer)來週期性地向接收方查詢,以便發現窗口是否已增大。這些從發送方發出的報文段稱爲窗口探查 (window probe)。

保活定時器(keepalive timer)

  在TCP連接建立的時候指定了SO_KEEPALIVE,保活定時器纔會生效。如果客戶端和服務端長時間沒有數據交互,那麼需要保活定時器來判斷是否對端還活着,但是這個其實很不實用,因爲默認是2小時沒有數據交互才探測,時間實在是太長了。如果你真的要確認對端是否活着, 那麼應該自己實現心跳包,而不是依賴於這個保活定時器。

FIN_WAIT_2定時器(FIN_WAIT_2 timer)

  主動關閉的一端調用完close以後(即發FIN給被動關閉的一端, 並且收到其對FIN的確認ACK)則進入FIN_WAIT_2狀態。如果這個時候因爲網絡突然斷掉、被動關閉的一段宕機等原因,導致主動關閉的一端不能收到被動關閉的一端發來的FIN,主動關閉的一段總不能一直傻等着,佔着資源不撒手吧?這個時候就需要FIN_WAIT_2定時器出馬了, 如果在該定時器超時的時候,還是沒收到被動關閉一端發來的FIN,那麼不好意思, 不等了, 直接釋放這個鏈接。FIN_WAIT_2定時器的時間可以從/proc/sys/net/ipv4/tcp_fin_timeout中查看和設置。
   
TIME_WAIT定時器 (TIME_WAIT timer, 也叫2MSL timer)

  TIME_WAIT是主動關閉連接的一端最後進入的狀態, 而不是直接變成CLOSED的狀態, 爲什麼呢?第一個原因是萬一被動關閉的一端在超時時間內沒有收到最後一個ACK, 則會重發最後的FIN,2MSL(報文段最大生存時間)等待時間保證了重發的FIN會被主動關閉的一段收到且重新發送最後一個ACK;另外一個原因是在2MSL等待時間時,任何遲到的報文段會被接收並丟棄,防止老的TCP連接的包在新的TCP連接裏面出現。不可避免的,在這個2MSL等待時間內,不會建立同樣(源IP, 源端口,目的IP,目的端口)的連接。

1.5 TCP與UDP的區別

共同點:
同處於TCP/IP協議棧的傳輸層

不同點:
協議層面:
TCP是面向連接的可靠傳輸協議 協議號爲6
UDP是非面向連接的不可靠傳輸 協議號爲17

傳輸層面:
TCP只能一對一傳輸且需要維護連接狀態 通過流模式傳輸數據
UDP支持一對一、一對多、多對一、多對多且不需要建立連接 通過數據報模式傳輸數據

說明:
  流模式是指存在緩存區,傳進來的數據先進入緩衝區;防止發送方發送的數據太大導致接收方接受不了,而數據報追求的是速度,即即時性的將發送方發送的數據發送至接收方

數據層面:
TCP保證數據正確性、不丟包、不重複、有順序
UDP只盡最大努力交付、不保證可靠性

適用場景:
TCP適合網絡負擔不大,可靠性要求高的場景
UDP適合網絡負擔大、響應高、客戶端較多、可靠性要求不高的場景

報文層面:
封裝的報文頭大小不同 TCP 20byte UDP 8byte
在這裏插入圖片描述在這裏插入圖片描述

1.6 協議棧的攻擊

有需要的同學可以看看這個專欄,這裏我做了一個導圖式的總結
協議棧攻擊在這裏插入圖片描述

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