日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

TCP协议详解----Linux学习笔记

發布時間:2023/12/20 linux 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 TCP协议详解----Linux学习笔记 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

傳輸層概述

傳輸層協議主要有兩個:TCP協議和UDP協議

TCP服務特點:
TCP協議的特點是:面向連接、字節流和可靠傳輸。(相對UDP協議而言的)
面向連接:
1.使用TCP協議的雙方必須先建立連接,然后才能開始數據的讀寫。
2.雙方都必須為該連接分配必要的內核資源以管理連接的狀態和連接上數據的傳輸。
3.同時TCP協議是全雙工的。也就是說雙方的數據讀寫可以通過一個連接進行,完成數據交換之后通訊雙方都必須斷開連接以釋放系統資源。
4.TCP協議的連接時一對一的。所以基于廣播和多播的應用程序不能使用TCP服務。然而無連接協議UDP,就非常適合于廣播和多播。

字節流:
字節流服務和數據報服務的區別:
對應于實際編程中就是通訊雙方是否必須執行相同次數的讀寫操作。當發送端應用程序連續執行多次寫入操作時,TCP模塊必須先把這些數據放入TCP發送緩沖區中,當TCP模塊真正開始發送數據時,發送緩沖區中這些等待發送的數據才可能封裝成一個或多個TCP報文段發出。所以TCP模塊發送出來的TCP報文的個數和應用程序執行的寫操作次數之間沒有固定的數量關系。而且當接收端收到一個或多個TCP報文段后,TCP模塊必須把它們攜帶的應用數據按照TCP報文段的序號依次放入TCP接收緩沖區中,同時通知應用程序讀取數據,這樣一來,接收端應用程序可以一次性將TCP接收緩沖區中的數據全部讀出,也可以分多次讀出,這就取決于用戶指定的應用程序讀緩沖區的大小,因此應用程序執行的讀操作次數和TCP模塊接收到的TCP報文段個數之間也沒有固定的數量關系。
總而言之:發送端執行的寫操作次數和接收端執行的讀操作次數,這兩者之間沒有任何數量關系。應用程序對數據的發送和接收是沒有邊界限制的。然而UDP并不是這樣,對于UDP來說,發送端應用程序沒執行一次寫操作,UDP模塊就必須將其封裝成一個UDP數據報,并發送這個數據報,到了接收端它必須針對每一個UDP數據報執行讀操作,否則就會發生丟包,并且如果用戶沒有指定足夠的應用程序緩沖區來讀取UDP數據報,那么UDP數據包就會截斷。
可以從下圖來區分TCP的字節流服務和UDP的數據報服務的區別:

可靠:
支撐TCP服務的可靠機制有:
1.TCP協議采用發送應帶機制
也就是說發送端發送的每一個TCP報文段都必須得到接收方的應答,才認為這個TCP報文段傳輸成功
2.TCP協議采用超時重傳機制
也就是說發送端在發送出一個TCP報文段之后就啟動定時器,如果在定時時間內沒有收到應答,那么就會重新發送這個報文段,同時TCP報文段最終是以IP數據報發送的,而IP數據報到達接收方可能亂序、重復。TCP協議同時會對接受的TCP報文段重排整理在交付給應用程序。
然而UDP數據報的服務中提供的是不可靠的服務。它們都需要上層協議來處理數據的確認和超時重傳。

TCP頭部信息:
TCP頭部信息出現在每個TCP報文段中,它用于指定通信的原端端口、目標端端口、管理TCP連接等這些任務。下圖為TCP的頭部結構:

包括:20個字節的固定頭部結構和40個字節的頭部選項字段。
頭部信息結構中每個字段的作用說明:
16位原端端口號和16位目的端端口號:
主要作用是告知主機該報文段來自哪里(哪里指的就是原端端口)以及傳給哪個上層協議或者應用程序等(指的是目標端端口)。客戶端通常使用系統自動選擇的臨時端口號,而服務器使用的是知名的服務器端口號(在Linux下知名服務器的端口號都定義在/etc/services這個文件中,常用的知名端口:HTTP服務:80、DNS服務:53、FTP服務:21)。
32位序號:
在一次TCP通信中(這里的一次TCP通信是指從TCP建立連接到斷開著整個過程中)在某個傳輸方向上的字節流的每個字節編號就是由這個32位序號來進行確認的。
32位確認號:
對于對另一方發送來的TCP報文段的響應,它的值是收到的TCP報文段的序號值+1。比如:主機A和主機B進行TCP通信,那么A發送出的TCP報文段不僅攜帶自己的序號而且包含對B發送來的TCP報文段的確認號。反過來說,B發送來的TCP報文段也同時攜帶自己的序號和對A發送來的報文段的確認號。
4位頭部長度:
標識該TCP頭部有多少個4字節。其中四位最大值能表示15。所以TCP頭部最長也就是60個字節。
6位保留
6位標志:
URG:表示緊急指針是否有效
ACK:表示確認號是否有效,我們稱ACK標志的TCP報文段為確認報文段。
PSH:提示接收端應用程序應該立即從TCP接收緩沖區中讀走數據,為接收后續數據騰出空間,因為應用程序不把接收到的數據讀走,那么這些數據就會一直停留在TCP接收緩沖區中,TCP接收緩沖區是存儲在內核中的,這樣也就會占用很大的內核資源。
RST:表示要求對方重新建立連接。我們稱攜帶RST標志的TCP報文段為復位報文段。
SYN:表示請求建立一個連接。我們稱攜帶SYN標志的TCP報文段為同步報文段。
FIN:表示通知對方本端要關閉連接了。我們稱攜帶FIN標志的TCP報文段為結束報文段。
16為窗口大小:
是TCP流量控制的一個手段,這里說的窗口是接收通告窗口(ReceiverWindow),告訴對方本端的TCP接收緩沖區中還能容納多少字節數據,這樣對方就能夠控制發送數據的速度。
16位校驗和:
由發送端填充,接收端對TCP報文段執行CRC算法來檢驗TCP報文段在傳輸過程中是否損壞。這個校驗不僅包括TCP頭部,也包括數據部分。這也是TCP可靠傳輸的重要保障。
16位緊急指針:
表示最后一個緊急數據的下一字節的序號。
頭部選項:
具體如下圖所示:

Kind:說明選項的類型。有的TCP選項沒有后邊兩個字段,僅包含以字節的Kind字段。
length:指定該選項的總長度
info:是選項的具體信息

常見的TCP選項有七種:

kind=0:是選項表結束選項。
kind=1:空操作選項,沒有特殊含義
kind=2:表示最大報文段長度選項
TCP連接初始化時,通訊雙方使用該選項來協商最大報文段的長度,TCP模塊通常把最大報文段長度設置為mtu-40(字節),這40字節就是20字節的TCP頭部和20字節的IP頭部,這樣一來,攜帶TCP報文段IP數據報的長度就不會超過mtu,這么一說,對于以太網來說,最大報文段長度就是1460字節。
kind=3:窗口擴大因子選項
在TCP連接初始化時,通訊雙方使用該選項來協商接收通告窗口的擴大因子,在TCP的頭部中接收通告窗口的大小是用16位表示的,所以最大值就是2^16-1(也就是65535個字節)。但實際上TCP模塊允許接收最大窗口遠不止這個數目,比這個數目大是為了提高TCP通訊的吞吐量,這個窗口擴大因子就解決了這個問題。我們假設TCP頭部中的接受通告窗口大小為n,窗口擴大因子是m,那么TCP報文段的實際接收窗口大小是n*2^m,這個字段跟最大報文長度字段一樣,窗口擴大因子選項只能出現在同步報文段中,當連接建立好后,每個數據傳輸方向上的窗口擴大因子就固定不變。
kind=4:選擇性確認選項
在TCP通訊時,如果某個TCP報文段丟失,那么TCP模塊就會重傳最后被確認的TCP報文段后續的所有報文段,這樣原先已經正確傳輸的TCP報文段也可能重復發送,這樣就降低了TCP的性能,選擇性確認選項的技術正是為了改善這種情況產生的,它讓TCP模塊只重新發送丟失的TCP報文段,不用發送所有未被確認的TCP報文段。
kind=5:SACK實際工作的選項
這個選項的參數告訴發送方本端已經收到并緩存的不連續的數據塊,從而讓發送端可以根據此選項并且重新發送丟失的數據塊
kind=8:表示時間戳選項
這個選項提供了比較準確的計算通訊雙方之間回路時間的方法。

TCP連接狀態轉移過程

使用TCP連接需要建立連接、數據傳輸、關閉連接這幾個過程。
其實TCP連接的任意一段在任意時刻都處于某種狀態,而且當前狀態都可以通過netstat命令查看。
下面說明TCP連接從建立到關閉的整個過程中,通信兩端狀態的變化。


上圖描繪了所有的TCP狀態以及可能的狀態轉換。
上圖中的粗虛線表示典型的服務端狀態轉移,粗實線表示典型的客戶端連接的狀態轉移。
服務器的典型狀態轉移過程:(接下來所說的連接狀態都是指該連接的服務器的狀態)
首先,服務器通過listen程序調用,進入LISTEN狀態。進入LISTEN狀態后,表示被動打開,被動的等待客戶端進行連接,服務器一旦監聽到某個連接請求,這個連接請求就是收到的同步報文段,之后就將該連接放入內核等待隊列中,并向客戶端發送帶SYN標志的確認報文段,此時該連接處于SYN RCVD狀態。從LISTEN狀態到SYN REVD狀態,它首先是收到了SYN報文段,緊接著就是發送帶有SYN標志的確認報文段,如果服務器成功的接收到客戶端發送會的確認報文段(ACK),那么該連接轉移到ESTABLISHED狀態。這個狀態是連接雙方能夠進行雙向數據傳輸的狀態,也就是從這個狀態開始,雙方能夠以TCP的方式傳送數據。
服務器關閉時狀態轉移的過程:當客戶端主動關閉數據連接時,客戶端主動關閉連接調用的系統調用就是close或者shutdown。服務器收到客戶端發送的關閉連接報文段后,通過返回確認報文段,是連接進入close_wait狀態,這個狀態就是等待服務器應用程序關閉連接,通常服務器檢測到客戶端關閉連接后也會立即給客戶端發送一個結束報文段來關閉連接,給客戶端發送一個接收報文段,這樣就進入了LAST_ACK狀態,接下來就是等待客戶端對接受報文段的最后一次確認,也就是等待接收圖片右下角的ACK,一旦確認完成,連接就徹底關閉,這種關閉連接的方式也稱為被動關閉。
客戶端的狀態轉移過程(接下來說的連接狀態都是指客戶端的連接狀態):
首先,客戶端通過connect系統調用,主動與服務器建立連接。connect系統調用會先給服務器發送一個同步報文段,是連接進入SYN_SENT狀態,此后connect系統調用可能因為兩個原因失敗返回,如果connect失敗返回,那么該連接又回到最初的CLOSED狀態。如果客戶端成功接收到服務器發送的同步報文段和確認,那么connect調用成功返回,也就是客戶端收到了服務器的同步報文段和確認報文段,說明connect的調用成功返回,連接轉移到ESTABLISHED狀態。接下來看一下當客戶端執行主動關閉時,這個狀態轉移過程:當客戶端進行關閉時,首先發送一個關閉連接報文段,同時連接進入FIN_WAIT_1狀態,如果此時客戶端收到服務器專門用于確認目的的確認報文段(也就是收到了服務器額ACK回應),那么連接轉移到FIN_WAIT_2狀態。當客戶端處于FIN_WAIT_2狀態時,服務器處于CLOSE_WAIT狀態,這對狀態是可能發生半關閉的狀態,此時如果服務器也關閉連接,也就是服務器也發送了結束報文段,也就是客戶端在FIN_WAIT_2狀態收到了結束報文字段,那么客戶端就給予確認,也就是發送一個ACK確認,同時進入TIME_WAIT狀態。

TCP建立連接和關閉連接的過程:

三次握手建立連接:

TCP頭部中我們知道有6個標志位,其中SYN標志位,這個標志僅在三次握手建立連接時有效,表示一個同步報文段。ACK標志是對TCP請求的確認標志。FIN標志是用來結束一個TCP連接,標識此報文段是一個結束報文段。


三次握手建立連接的過程:
第一次握手:客戶端發送一個帶有SYN標志的TCP報文段給服務器。
圖中SYN=1,表示這個字段是一個同步報文段,seq=i(序列號值為i),發送完這個報文段之后,主機A進入SYN SEND狀態,等待服務器的確認。
第二次握手:服務器收到同步報文段之后必須確認客戶的同步報文段,同時自己也發送一個帶有SYN標志的報文段。
圖中第二個報文段,SYN=1標志這是一個同步報文段,ACK=1表示這同時也是一個確認報文段。ack=i+1,表示確認序號值為i+1。seq=j,表示序號值為j。
第三次握手:客戶端收到服務器的確認報文段之后,向服務器發送確認包。
圖中ACK=1,表示是一個確認報文段。ack=j+1,確認序號為j+1。

三次握手之后,客戶端與服務器開始傳輸數據。

四次握手關閉連接:

第一次握手:客戶端發送一個帶有FIN標志的結束報文段,用來關閉客戶端A和服務器端B的數據傳送。
圖中FIN=1表示一個結束報文段。seq=i表示序號值為i。
第二次握手:服務端B收到這個結束報文段之后發回一個確認報文段,確認序號就是收到序號的值+1。
圖中ACK=1,表示這是一個確認報文段。ack=i+1,標志確認號為i+1。
第三次握手:服務器B關閉與客戶端A的連接,發送了一個帶有FIN標志的結束報文段。
圖中FIN=1表示這是一個結束報文段,seq=j表示這是一個結束報文段。
第四次握手:客戶端A發回一個確認報文段,其中確認序號設置為收到的序號+1。
圖中ACK=1表示是一個確認報文段,ack=j+1表示確認序號是j+1。

為什么建立連接需要三次握手,而關閉連接需要四次握手?
是因為服務端的Listen狀態下的連接當收到同步報文段建立連接請求后,他可以把同步報文段和確認報文段合并成為一個報文段來進行發送,確認報文段起了應答作用,同步報文段起了同步作用,對應于三次握手中也就是第二次握手。但是在關閉連接時在收到客戶端的結束通知時,僅僅表示對方沒有數據發送給自己了,但未必自己所有的數據都發送給對方了,所以不能馬上關閉TCP連接。可能需要在發送一些數據給客戶端之后在發送結束報文段給對方,來表示你現在可以關閉連接了。所以這里的確認報文段和同步報文段必須要分開。

為什么建立連接需要三次握手呢?兩次握手為什么不行?
如果是兩次握手就有可能造成死鎖,例如:如果客戶端和服務端進行通信,客戶端給服務端發送一個同步報文段,服務端收到了這個同步報文段并發送了確認報文段。按照兩次握手的規定,服務端就認定這個連接已經建立了,可以開始發送數據了。但是如果第二次握手的確認報文段丟失,那么客戶端就不知道服務端是否已經準備好,也不知道服務端建立什么樣的序號值,這樣服務端就有可能繼續發送第二次握手的報文段,但是到了客戶端,他可能不識別這個報文段。這樣就形成了死鎖。

TIME_WAIT狀態:

TIME_WAIT狀態存在的原因:

  • 可靠的終止TCP連接
  • 保證遲來的TCP報文段有足有的時間被識別并丟棄
  • RST復位報文段:

    TCP頭部中有6位的標志字段,其中有一位是RST復位標志位。如果TCP報文段中RST=1,就說明這個報文段是RST復位報文段。
    在某些情況下,TCP連接的一端會向另一端發送攜帶RST標志的報文段,用來通知對方關閉連接或者重新建立連接。其實在TCP連接建立時、TCP中間發送數據時、TCP連接關閉時這三個時間段內都有可能發送RST復位報文段。

    當連接建立時出現RST回應的情況有:

  • 向不存在的端口發送數據
  • 端口未打開
  • 請求超時
  • 提前關閉
  • 在一個已關閉的socket上收到數據
  • 異常終止一個連接
  • 向處于listen的端口發送數據
  • TCP可靠傳輸機制

    TCP超時重傳
    如果網絡出現異常,就有可能出現超時或者丟包,這個時候TCP模塊必須重傳超時時間內未能收到確認的TCP報文段。為此TCP模塊為每個TCP報文段維護一個重傳定時器。該定時器在TCP報文段第一次被發送時啟動,如果超時時間內未能收到接收方的應答,TCP模塊將重傳TCP報文段,并重置定時器。
    TCP的超時重換為TCP的可靠傳輸奠定了一定的基礎。

    TCP擁塞控制的過程
    TCP模塊還有一個重要的任務就是:提高網絡利用率、降低丟包率、擁塞控制。
    其中擁塞控制和流量控制都是為TCP的可靠傳輸而設計的。
    擁塞控制的任務是:確保子網能夠承載所到達的流量,這是一個全局性問題,涉及到各方面的行為,包括所有的主機、所有的路由器、路由器內的存儲轉發過程。

    總結

    以上是生活随笔為你收集整理的TCP协议详解----Linux学习笔记的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。