1. 程式人生 > >TCP/IP協議下三層協議(二)----傳輸層協議

TCP/IP協議下三層協議(二)----傳輸層協議

1.UDP使用者資料報協議 首先,說明UDP的幾個主要特點: ①UDP是無連線的; ②UDP盡最大努力交付,但不保證資料可靠性; ③UDP是面向報文的; ④UDP沒有擁塞控制(網路出現擁塞狀況並不會導致源主機的傳送速率降低); ⑤UDP支援一對一,一對多,多對一與多對多的互動通訊; ⑥首部開銷小;


UDP的資料段格式很簡單,它的報頭是定長(因此UDP協議報頭資訊中無需加入報頭長度的資訊),其報頭資訊包括源埠號和目的埠號,UDP整個報文長度以及UDP檢驗和 這裡解釋一下埠號的作用:對於任何一個網路程序,IP地址+埠號是他的唯一標識資訊,而一般的網路通訊當中,通訊雙方分為客戶端和伺服器,由我們的客戶端主動發出請求,而伺服器則是被動的等待,接收和應答,而正因為我們的客戶端需要向伺服器主動傳送請求,所以它必須要知道伺服器的IP地址和埠號,所以對於客戶端而言,它的埠號可以是任意的,由使用者端自由分配一個空閒的埠號,但對於伺服器而言,它的埠號則必須是固定的,而且是被所有人所知曉的(例如:HTTP服務對應埠號80,HTTPS則對應443,FTP對應21),在使用客戶端程式的時候,必須明確指定伺服器IP地址與埠號(在/etc/services檔案中列出了所有被眾所周知的服務埠號以及其對應的傳輸協議) 對於UDP協議而言,這個傳輸協議不面向連線,也不會保證傳輸的可靠性,傳送端只管將上層的資料報文進行封裝,傳給下層的IP協議,而對於接收端則只管對IP協議層傳送過來的資料進行報頭和有效載荷資訊分離即可,至於資料包有沒有丟失,接收資料的順序對不對,UDP協議並不會處理,而這自然就得輪到上層應用層進行處理這些問題了,正因為UDP協議的這種特性,所以一般使用UDP的網路服務都比較簡單,資料量少,對於資料的可靠性要求不高,與之相對的TCP協議就恰恰相反,對於可靠性有著相當的要求,正因如此也就更加複雜 2.TCP傳輸控制協議 首先介紹TCP的主要特點: ①TCP是面向連線的(即在應用TCP協議時作業系統會對連線進行描述,建立對應的結構體來進行維護管理連線); ②TCP是面向位元組流的; ③每條TCP連線只能是一對一的; ④TCP提供全雙工通訊; ⑤TCP提供可靠交付的服務;

對於TCP協議的資料段格式中的報頭資訊: 16位源埠號和16位目的埠號表示源主機對應埠號與目的主機對應埠號; 32位序號表示對於傳送端而言,本報文段所傳送的第一個位元組的序號(對於TCP協議而言,它對傳送的資料的每個位元組都進行按順序編號),與之相對的就是32位確認序號(假設該欄位值為n),它表示對於接收端而言,期望下一個收到傳送端傳送的位元組序號,換言之,在確認序號之前的資訊已經確認收到【對於序號與確認序號這兩個欄位,它們一來保證資料的不丟失,二來保證了資料在傳送端是如何傳送的,在接收端就如何接收,順序不會混亂,這是保證了TCP協議的可靠性傳輸】; 4位首部長度也叫資料偏移,單位為字(4位元組),範圍是5~15,表示首部最小長度為20位元組,最大為60位元組(保證了首部與有效載荷部分能夠有效區分);6位保留欄位留待後用,目前置為0;16位視窗大小表示一個緩衝區的大小,而這個緩衝區則是自己作為接收端的時候,接收緩衝區的大小,這個欄位的目的在於讓對方知道我方現在的接收緩衝區的大小,協同傳送端和接收端雙方接收資料(由於通訊雙方會因為各種原因導致其發 送與接收資料的能力有所不同,倘若傳送端的傳送資料能力較強,而接收端的讀取資料能力較弱,則會導致緩衝區滿了而傳送端還在傳送資料,而已滿的緩衝區萬萬不能用新資料將還未被讀取的資料進行覆蓋,那麼必然導致新發送過來的資料不能被接收,而視窗大小這個欄位的作用則是在於讓傳送端知道接收端當前的接收緩衝區的大小(能接收資料的能力有多大),從而做出調整(當視窗大小為0時,傳送端不再發送資料,等待接收端讀資料,通過輪循的方式在一段時間後向接收端傳送對應訊號詢問緩衝區大小,而接收端在響應時告訴傳送端自己的接收緩衝區當前大小,以判斷是否能夠傳送資料)); 16位檢驗和用於檢驗資料是否傳送正確;16位緊急指標表示本報文段的緊急資料的位元組數; 除了上述的欄位,還有6位控制位: ①URG表示置1時後面的16位緊急指標欄位有效,說明此報文段中有緊急資料(類似於高優先順序資料),需要優先傳輸,傳送端會將緊急資料提到報文資料的最前面以保證其能夠優先傳輸(緊急指標表明了有多少位元組緊急資料,而這樣一來從資料起始處偏移對應位元組這個區域就是緊急資料),而當接收端檢測到所接收的資料報中該位被置1,則去檢測緊急指標欄位,分析有多少位元組是需要緊急處理的,對這些資料進行優先處理; ②ACK表示置1時確認序號欄位有效,在TCP連線建立後所有的ACK欄位均要置為1; ③PSH表示置1時表示傳送端想立即得到接收端的響應,所以立即建立一個報文段將資料傳送出去,而不會等到緩衝區滿才傳送,而對於接收端而言,當檢測到PSH=1時,則將得到的報文段資料立即交給上層應用進行處理,不在等待緩衝區滿才向上交付; ④RST表示當前TCP連線可能出現了嚴重差錯,必須得釋放連線,然後重新建立連線,此時將RST置1即可完成復位,除此之外,這個標誌位還可以用來拒絕一個非法的報文段或拒絕一個連線; ⑤SYN表示在建立連線時用來同步序號,與ACK一起,當SYN=1,ACK=0時,表明這是一個連線請求的報文,若對方同意連線,則會響應SYN=1,ACK=1,所以SYN置1表示這是一個請求連線或連線響應報文; ⑥FIN用於釋放一個連線,當FIN置1時,表示資料傳送完畢,請求終止連線; 以上就是TCP首部資訊的大致介紹,而對於TCP協議而言,由於它是面向連線的,TCP的連線建立與釋放就尤為關鍵:

(1)三次握手----建立連線 第一次握手:由客戶端主動發出連線請求,傳送請求建立連線的報文,將SYN設為1,佔用一個序號1000(TCP規定SYN報文段不攜帶資料,但要消耗一個序號),還有一點mss代表最大報文段長度,如果一個報文段太大,那麼當它封裝成幀後對於鏈路層而言則是超過了它的最大幀長度MTU,這樣一來就必須在IP層進行分片,這會大大降低效率,所以mss表示建議伺服器傳送的段長度不要超過這個值; 第二次握手:伺服器收到了客戶端發來的連線請求,若同意建立連線,則向客戶端傳送連線應答響應,將SYN設為1,ACK設為1,並且確認序號設為1001(表示已經收到客戶端發來的序號為1000的資料,希望客戶端下次傳送序號為1001的資料),同時該響應報文段佔用一個序號8000,並且將自己的最大報文段長度傳送給客戶端(理由同上); 第三次握手:客戶端在成功收到來自伺服器的請求響應之後,再次向伺服器傳送資訊,而此次傳送的是響應確認收到的資訊,將ACK設為1,並且將確認序號設為8001(表示已經收到伺服器發來的序號為8000的資料,希望伺服器下次傳送序號為8001的資料 ),當伺服器成功收到來自客戶端的確認資訊之後,那麼此時伺服器與客戶端之間的連線隨即建立; 事實上,在第二次握手成功後,客戶端就已經認為成功建立了連線,並且建立對應的資料結構去維護連線,但是這個時候伺服器卻認為連線還沒能建立,並沒有對應的資料結構建立來維護這個連線,而這也是為什麼在建立連線的時候只能是三次握手,而不能是兩次握手或者是四次握手的關鍵: 若沒有第三次握手,那麼第一次握手成功後,伺服器就認為已經建立了連線,並且會向客戶端傳送響應資訊,但是如果這個時候由伺服器傳送的響應資訊在傳送過程中出現了丟失,導致客戶端沒能收到伺服器的響應,第二次握手失敗,那麼客戶端就會認為連線並沒有建立,但此時伺服器卻認為連線建立了,並建立了對應的資料結構來維護這個連線,這樣一來這個連線顯然是無效的,而對於伺服器而言,若在伺服器中存在大量的無效連線,這必然會降低伺服器的效能,甚至影響伺服器的正常服務;而對於三次握手而言,在第二次握手成功後,伺服器並不認為連線建立了,而是客戶端認為連線成功建立,並在第三次握手的時候客戶端向伺服器傳送確認收到響應資訊,若此時確認資訊成功到達伺服器,則伺服器建立連線,否則伺服器就認為連線未能建立,並在一段時間後認為客戶端未能收到自己的響應資訊,並再次向客戶端傳送響應資訊,這樣一來伺服器當中就不會存在大量的無效連線從而影響伺服器的正常工作(可能有人會認為這樣一來,客戶端中不就會存在無效連線了嗎,但是對於客戶端而言,一來無效連線的數量肯定不會多,二來客戶端不會像伺服器一樣向他人提供服務,所以就算有影響也是微乎其微的);然而至於四次握手或更多,三次握手能解決的問題為什麼要進行多餘的握手呢,這也是一種變相的降低效率 綜上,三次握手建立連線期間完成的工作就是協調通訊雙方的相關資訊(彼此雙方的視窗大小,彼此雙方的最大資料段mss大小,以及建立各自的描述連線的資料結構等) 第一次揮手:對於通訊雙方而言,都可以在資料傳輸結束後首先釋放連線,這裡我們假定客戶端先釋放連線,將FIN置1,表示此時客戶端的資料已經發送完畢,請求釋放連線,傳送相應的請求報文段,並將ACK設為1,確認序號為8011,並且佔用一個序號1021,但此時不攜帶資料; 第二次揮手:伺服器在接收到客戶端的釋放連線請求時,向客戶端傳送資訊,將ACK設為1,並將確認序號設為1022,表示1022序號之前的資料已準確收到,期望下次能收到序號為1022的資料,而當客戶端收到伺服器發回的響應後,此時TCP連線將進入半關閉狀態,即客戶端不再向伺服器傳送資料,但如果伺服器向客戶端傳送資料,客戶端依舊得接收,也就是說此時客戶端雖不會再進行資料傳送,但它依舊會維護資料結構來保證連線; 第三次揮手:伺服器在自己的資料傳送完畢後,向客戶端傳送釋放連線的請求,將FIN置1,ACK置1,佔用一個序號8011,但此時不攜帶資料,並且將確認序號設為1022; 第四次揮手:在接收到伺服器的釋放連線請求後,處於半關閉狀態的客戶端向伺服器傳送確認收到請求的響應,併發送給伺服器,將ACK設為1,將確認序號設為8012,但此時客戶端作為主動請求釋放連線的一方,它的連線並未釋放,而是進入TIME_WAIT狀態,並在此狀態等上2msl時間後,客戶端連線才會釋放(這裡處於TIME_WAIT狀態進行等待不釋放連線的目的在於確保最後一次的ACK響應能夠成功被伺服器接收,在丟失的情況下進行重發);而對於伺服器而言,在它收到ACK應答的時候,伺服器的連線就已經釋放; 以上便是釋放連線時的四次揮手,對於TCP協議的通訊雙方而言,要斷開連線必須雙方均斷開連線 (3)前面說過TCP通訊雙方在建立連線之處,會對雙方的一些資訊進行協調,其中有一項就是彼此雙方的視窗大小,對於視窗大小表示接收資料緩衝區的大小,代表某一時刻各自接收資料的能力,這一項資訊在TCP通訊從三次握手開始到四次揮手接收,始終是需要讓對方知道的,而它也是TCP通訊用來作為進行流量控制的一項機制(通訊雙方的資料傳送速率存在快慢差異),由於底層採用類似迴圈佇列的資料結構,視窗的大小範圍類似從左向右滑動,所以這項機制也叫作“滑動視窗” 補充:TCP的常見定時器 1.連線建立定時器 在傳送SYN報文段建立一條新連線時啟動。如果沒有在75S內收到響應,連線建立將終止。 2.重傳定時器 為了控制丟失的報文段或丟棄的報文段,也就是對報文段確認的等待時間。當TCP傳送報文段時,就建立這個特定報文段的重傳計時器,可能發生兩種情況:若在計時器超時之前收到對報文段的確認,則撤銷計時器;若在收到對特定報文段的確認之前計時器超時,則重傳該報文,並把計時器復位。重傳定時器的值(即TCP等待對端確認的時間)是動態計算的,取決於TCP為該連線測量的往返時間和該報文段 已被重傳的次數。 3.延遲ACK定時器 在TCP收到必須被確認但無需馬上發出確認的資料設定。TCP等待200ms後傳送確認響應。如果,在這200ms內,有資料要在該連線上傳送,延遲的ACK響應就可隨著資料一起傳送回對端,稱為捎帶確認。 4.持續定時器 對於TCP通訊雙方互相傳送資料,當對方的視窗大小為0時,另一方將停止傳送資料,此時將啟動持續定時器進行等待對端從接收緩衝區中讀資料,當定時器超時後,向對端傳送一段詢問報文並且啟動重傳定時器,詢問此時對端的視窗大小,若對端響應傳送報文告訴視窗大小不為0,則隨即重新開始向對端傳送資料,若視窗大小仍為0,那麼將持續定時器的設定值加倍並重啟等待,如果在重傳定時器超時還未收到對端的響應,那麼根據重傳定時器的原理,進行詢問報文的重發; 5.保活定時器 為了應對兩個TCP連線間出現長時間的沒有資料傳輸的情況。如果客戶已與伺服器建立了TCP連線,但後來客戶端主機突然故障,則伺服器就不能再收到客戶端發來的資料了,而伺服器肯定不能這樣永久地等下去,保活定時器就是用來解決這個問題的。伺服器每收到一次客戶端的資料,就重新設定保活定時器,通常為2小時,如果2小時沒有收到客戶端的資料,服務端就傳送一個探測報文,以後每隔75秒傳送一次,如果連續傳送10次探測報文段後仍沒有收到客戶端的響應,伺服器就認為客戶端出現了故障,就可以終止這個連線。 6.FIN_WAIT_2定時器 當某個連線從FIN_WAIT_1狀態(第一次揮手成功後主動斷開連線的一端所處狀態)變遷到FIN_WAIT_2狀態(即第二次揮手成功之後主動斷開連線的一端所處狀態--半關閉狀態),並且能再接收任何新資料時,FIN_WAIT_2定時器啟動,設為10分鐘。定時器超時後,重新設為75S,第二次超時後連線被關閉。加入這個定時器的目的是為了避免如果對端一直不傳送FIN,某個連線會永遠滯留在FIN_WAIT_2狀態(半關閉狀態)。 7.TIME_WAIT定時器 一般也稱為2MSL定時器。MSL指最大報文段生存時間。主要發生在TCP釋放連線四次握手中,主動關閉連線的那一方最後進入的狀態,設定的時間為2MSL設定這個計時器的目的: 一是為了保證主動方傳送的最後一個ACK報文段能夠到達,2MSL(報文段最大生存時間)等待時間保證了重發的FIN會被主動關閉的一段收到且重新發送最後一個ACK。 二是防止已失效的連線請求報文段出現在新的連線中,TCP規定在TIME_WAIT狀態,不能建立新的連線,即主動斷開連線的一方連線在此狀態期間不會被釋放,資源依舊被佔用。既然TIME_WAIT狀態維持2MSL,這就保證了一箇舊連線上傳送的分組及其應該在 2MSL內都會消失,不會對於新的連線造成干擾。