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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

计算机网络 | 传输层 :UDP与TCP协议详解

發(fā)布時間:2024/4/11 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 计算机网络 | 传输层 :UDP与TCP协议详解 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

傳輸層

  • UDP
    • UDP的協(xié)議格式
    • UDP的特點
    • 基于UDP的應用層知名協(xié)議
    • UDP如何實現(xiàn)可靠傳輸
  • TCP
    • TCP的協(xié)議格式
    • TCP的特點
    • 連接管理機制
      • 三次握手
      • 四次揮手
      • 保活機制
      • 問題補充
    • 可靠傳輸
      • 確認應答
      • 超時重傳
    • 避免丟包重傳
      • 滑動窗口
        • 停止等待協(xié)議
        • 回退N步協(xié)議
        • 選擇重傳協(xié)議
      • 流量控制
      • 擁塞控制
    • 挽救傳輸性能
      • 快速重傳
      • 延遲應答
      • 捎帶應答
    • 面向字節(jié)流
    • 基于TCP的應用層知名協(xié)議


傳輸層是整個網(wǎng)絡(luò)體系結(jié)構(gòu)中的關(guān)鍵層次之一,主要負責兩個主機中進程之間的數(shù)據(jù)傳輸。
在傳輸層中常見的協(xié)議就是TCP協(xié)議(傳輸控制協(xié)議),UDP協(xié)議(用戶數(shù)據(jù)報協(xié)議)

UDP

UDP協(xié)議,即用戶數(shù)據(jù)報協(xié)議


UDP的協(xié)議格式

  • 16位源端端口/目的端口:表示源端/對端的端口號,源端端口有時候可以不設(shè)置(不關(guān)心通信的端口),可以設(shè)置為0。
  • 16位數(shù)據(jù)報長度:標志UDP首部與發(fā)送數(shù)據(jù)的長度之和,大小為2^16,即64K,65535。
  • 16位校驗和:用于檢驗接收的數(shù)據(jù)與發(fā)送的數(shù)據(jù)是否一致,不一致則丟棄。校驗方法:二進制反碼求和,即對報文從頭開始的每個字節(jié)進行取反相加,高出16位則截斷高位,與低16位相加,得到校驗和。

UDP的特點

其主要特點為:無連接,不可靠,面向數(shù)據(jù)報。

  • 無連接
    即不需要建立連接也可以發(fā)送數(shù)據(jù)。只需要知道對端的端口號和ip地址就可以直接傳輸。就比如寄快遞,只需要知道人家的地址就可以送過去,不需要與別人提前建立聯(lián)系
  • 不可靠
    即不能保證數(shù)據(jù)安全有序的到達對端。因為UDP不存在重傳機制與確認機制,所以并不能保證數(shù)據(jù)能夠到達對端,可能會在途中出現(xiàn)丟包,即使丟包了也不會報錯和重傳。UDP的報頭中不存在序號,并且是無連接的,所以他沒法保證數(shù)據(jù)到達后的順序,需要我們自己在應用層進行包序管理。
  • 面向數(shù)據(jù)報
    即不能靈活的控制讀寫次數(shù)與數(shù)據(jù)的長度,是一種限制了傳輸數(shù)據(jù)大小的傳輸方式。并且UDP的數(shù)據(jù)傳輸是整條的,不會拆分和合并數(shù)據(jù)。

面向數(shù)據(jù)報:
數(shù)據(jù)報長度字段只有16位,報頭要占8個字節(jié),所以數(shù)據(jù)報的長度不能大于(64K- 8) 。
UDP給應用層傳下來的報文添加首部后就會直接轉(zhuǎn)交給網(wǎng)絡(luò)層,所以對于較大的數(shù)據(jù),需要我們自己在應用層進行分包和包序管理進行多次發(fā)送。

UDP在報頭中定義了數(shù)據(jù)長度,所以傳輸?shù)臅r候都是整條收發(fā)。
所以接收時緩沖區(qū)必須要足夠大,如果緩沖區(qū)大于或者小于一條數(shù)據(jù)的大小時都會接收失敗,因為UDP不會交付半條或者多條數(shù)據(jù)。


基于UDP的應用層知名協(xié)議

  • NFS: 網(wǎng)絡(luò)文件系統(tǒng)
  • TFTP: 簡單文件傳輸協(xié)議
  • DHCP: 動態(tài)主機配置協(xié)議
  • BOOTP: 啟動協(xié)議(用于無盤設(shè)備啟動)
  • DNS: 域名解析協(xié)議

UDP如何實現(xiàn)可靠傳輸

如果光光依靠UDP本身是無法實現(xiàn)可靠傳輸?shù)?#xff0c;因為其無法保證數(shù)據(jù)有序且到達,所以可以參考TCP的可靠性機制,在應用層也為其引入類似邏輯
例如

  • 引入序列號,保證數(shù)據(jù)有序
  • 確認應答機制,保證對端能夠收到數(shù)據(jù)
  • 引入超時重傳機制,保證數(shù)據(jù)不會丟失

  • TCP

    TCP協(xié)議,即傳輸控制協(xié)議


    TCP的協(xié)議格式

    • 16位源端端口/目的端口:表示源端/對端的端口號,源端端口有時候可以不設(shè)置(不關(guān)心通信的端口),可以設(shè)置為0。
    • 32位序號:序號是指發(fā)送數(shù)據(jù)的位置。每發(fā)送一次數(shù)據(jù),就累加一次該數(shù)據(jù)字節(jié)數(shù)的大小。序號不會從0或1開始,而是在建立連接時由計算機生成的隨機數(shù)作為其初始值,通過SYN包傳給接收端主機。
    • 32位確認序號:確認序號是指下一次應該收到的數(shù)據(jù)的序列號。實際上,它是指已收到確認序號減一為止的數(shù)據(jù)。發(fā)送端接收到這個確認序號以后可以認為在這個序號以前的數(shù)據(jù)都已經(jīng)被正常接收。
      TCP通過序號和確認序號來實現(xiàn)包序管理,確保TCP數(shù)據(jù)是有序交付的。
    • 4位數(shù)據(jù)偏移(首部長度):表示TCP首部的長度,單位為4字節(jié)即32位,因為數(shù)據(jù)偏移具有4位,所能表示的最大數(shù)據(jù)為15即2^4 - 1,所以TCP首部的最大長度為15 * 4 = 60字節(jié),因為數(shù)據(jù)偏移最少為5(除選項),所以TCP首部的最小長度為20字節(jié)。
    • 6位保留位:保留為今后使用,一般設(shè)置為 0。
    • 6位標志位:有六種標志位,用來描述本報文的性質(zhì)

    URG(Urgent Flag):該為為1時,表示包中有需要緊急處理的數(shù)據(jù)。對于需要緊急處理的數(shù)據(jù),會在后面的緊急指針中再進行解釋。
    ACK(Acknowledge Flag):該位為1時,確認應答的字段變?yōu)橛行?/strong>。TCP規(guī)則除了最初建立時的SYN包之外該為必須設(shè)置為1。
    PSH(Push Flag):該位為1時,表示需要將受到的數(shù)據(jù)立即傳輸給上層的應用。PSH為0時,則不需要立即上層而是先進行緩存。
    RST(ResetFlag):該位為1時表示TCP連接中出現(xiàn)異常必須強制斷開連接。例如,一個沒有被使用的端口即使發(fā)來連接請求,也無法通行。此時就可以返回一個RST設(shè)置為1的包。此外,程序宕掉或切斷電源等原因?qū)е轮鳈C重啟的情況下,由于所有的連接信息將全部被初始化,所以原有的TCP通行也將不能繼續(xù)進行。這種情況下,如果通信對方發(fā)送一個設(shè)置為1的RST包,就會使用心強制斷開連接。
    SYN(Synchronize Flag): 用于建立連接。SYN為1表示希望建立連接,并在其序列號的字段進行序列號初始值的設(shè)定。
    FIN(Finish Flag):該位為1時,表示今后不會再有數(shù)據(jù)發(fā)送,希望斷開連接。當通信結(jié)束希望斷開連接時,通信雙方的主機之間就可以相互交換FIN位置為1的TCP段。每個主機又對對方的FIN包進行確認應答以后就可以斷開連接。不過,主機收到FIN設(shè)置為1的TCP端以后不必馬上回復一個FIN包,而是可以等到緩沖區(qū)中所有數(shù)據(jù)都已成功發(fā)送而被自動刪除之后再發(fā)。

    • 16位窗口大小:指定滑動窗口的大小,即從TCP首部的確認序號所指位置開始能夠接收的數(shù)據(jù)大小,TCP不允許發(fā)送超過此處所示大小的數(shù)據(jù)。用于實現(xiàn)滑動窗口機制,來進行流量控制
    • 16位校驗和:用于檢驗接收的數(shù)據(jù)與發(fā)送的數(shù)據(jù)是否一致,不一致則丟棄。校驗方法:二進制反碼求和,即對報文從頭開始的每個字節(jié)進行取反相加,高出16位則截斷高位,與低16位相加,得到校驗和。
    • 16位緊急指針: 標識哪部分數(shù)據(jù)是緊急數(shù)據(jù)(帶外數(shù)據(jù)),這段數(shù)據(jù)的優(yōu)先級更高,會提前傳送
    • 0-40字節(jié)選項:選項字段用于提高TCP的傳輸性能,主要協(xié)商和描述一些信息。因為TCP首部大小最高為60字節(jié),而前面必須的有20字節(jié),所以選項的大小可以為0-40字節(jié)。
    • 填充位:保證TCP首部大小為4字節(jié)的整數(shù)倍,不夠則填充

    TCP的特點

    其主要特點為:面向連接,可靠,面向字節(jié)流。

    • 面向連接:通信必須在建立連接之后,通過連接管理機制實現(xiàn)。
    • 可靠傳輸:保證數(shù)據(jù)安全有序的到達對端
    • 面向字節(jié)流:以字節(jié)流的方式傳輸

    連接管理機制

    TCP通過首部的標志位來實現(xiàn)連接的管理,完成通信。
    通常情況下,需要經(jīng)過三次握手來建立連接,四次揮手來斷開連接
    這里我簡單的畫了一個圖

    三次握手


    開始時,客戶端處于CLOSED狀態(tài),服務端處于CLOSED狀態(tài)。
    之后服務端進入LISTEN狀態(tài),開始監(jiān)聽(只有處于監(jiān)聽狀態(tài)才會處理連接)。

    第一次握手(客戶端向服務端揮手):客戶端向服務端發(fā)送一個SYN請求建立連接,客戶端轉(zhuǎn)為SYN_SENT狀態(tài)。
    第二次握手(服務端向客戶端揮手):服務端一旦監(jiān)聽到連接請求,就會轉(zhuǎn)為SYN_RECV狀態(tài),并且向客戶端發(fā)送一個SYNACK來告訴客戶端我已經(jīng)收到了你的SYN連接請求,并且也發(fā)起連接。
    第三次握手(客戶端向服務端揮手):客戶端收到后轉(zhuǎn)為ESTABLISHED狀態(tài)。并且向服務端發(fā)送一個ACK給服務端,告知服務端我也收到了你的SYN請求,服務端收到后也進入ESTABLISHED狀態(tài)。

    簡單點來說:
    第一次握手:客戶端:在嗎,我是XX,你聽到我說話了嗎?
    第二次握手:服務端:我聽到你說話了,你聽到我說話了嗎?
    第三次握手:客戶端:我也聽到你說話了,既然我們互相都能聽到,就開始通信吧。


    四次揮手


    第一次揮手(客戶端向服務端揮手):客戶端向服務端發(fā)送一個FIN請求斷開連接,客戶端處于FIN_WAIT_1狀態(tài)。發(fā)送FIN表示發(fā)送端不再發(fā)送數(shù)據(jù),但不代表不接收數(shù)據(jù)。
    第二次揮手(服務端向客戶端揮手):服務端向哭護短回復一個ACK確認收到了FIN。并且轉(zhuǎn)為CLOSE_WAIT狀態(tài)(此時服務端已經(jīng)不再接受數(shù)據(jù)(關(guān)閉讀操作),但是還會繼續(xù)發(fā)送,所以此時會等待上層程序處理)
    第三次揮手(服務端向客戶端揮手):此時服務端也完成了寫操作,所以向服務端發(fā)送一個FIN請求斷開連接,并且進入LASK_ACK狀態(tài)。
    第四次揮手(客戶端向服務端揮手):客戶端收到了服務端的FIN,并且向服務端回復一個ACK表示已經(jīng)收到。同時客戶端進入TIME_WAIT狀態(tài)。服務端收到ACK后斷開連接進入CLOSED狀態(tài),客戶端也進入CLOSED狀態(tài)。

    簡單來說
    第一次揮手:客戶端:我要說的話已經(jīng)說完了。
    第二次揮手:服務端:你要說的我都聽到了,但是我的話還沒說完。
    第三次揮手:服務端:我要說的話也說完了。
    第四次揮手:客戶端:既然我們都說完了,那就結(jié)束通話吧。


    ?;顧C制

    在TCP通信中,如果兩端長時間沒有數(shù)據(jù)往來(默認7200秒),則每隔一段時間(默認75秒),服務端就會向客戶端發(fā)送一個?;钐綔y數(shù)據(jù)報,讓客戶端進行回復,如果多次(默認9次)沒有收到響應,則代表連接已經(jīng)斷開。

    通過?;顧C制來確保如果有一端斷開,能夠及時處理。


    問題補充

    TCP握手為什么三次,能不能兩次或者四次
    兩次不安全,四次沒必要。SYN的目的是為了確認對方是否具有收發(fā)數(shù)據(jù)的能力,并且得到ACK回復后,則證明對方收到數(shù)據(jù)并且當前在線。如果要建立連接,就必須確保雙方都具有收發(fā)數(shù)據(jù)的能力并且當前處于在線狀態(tài)。

    為什么不能兩次?
    如果只有兩次就能建立連接,那就代表著客戶端發(fā)起SYN連接,服務端確認后回復ACK+SYN就直接建立連接。
    1.如果客戶端連續(xù)發(fā)送多次請求,服務端就會建立多次連接,嚴重的浪費資源。
    2.如果客戶端發(fā)起SYN請求后就斷開,或者是因為延遲很久才發(fā)到,等服務端收到時客戶端已經(jīng)斷開連接,這時這個連接是失敗的,但是服務端還是創(chuàng)建了一個毫無意義的套接字,嚴重浪費了資源。

    為什么不用四次?
    四次握手完全沒有必要,建立連接的SYN和確認回復的ACK報文是可以一起發(fā)送的,沒有必要分開來增加操作。


    TCP揮手為什么要四次,三次可以嗎?
    不行,發(fā)送FIN包只能代表著主動關(guān)閉方不再發(fā)送數(shù)據(jù),但不代表著不再接受數(shù)據(jù),所以被動關(guān)閉方在回復ACK后還是有可能繼續(xù)發(fā)送數(shù)據(jù),等到被動關(guān)閉方所有數(shù)據(jù)發(fā)送完后才會發(fā)送FIN,主動關(guān)閉方收到后回復ACK才會斷開連接。這也就是為什么建立連接時ACK可以和SYN一起發(fā)送,而斷開連接時FIN不能和ACK一起發(fā)送的原因。(如果被動關(guān)閉方不需要發(fā)送數(shù)據(jù),則此時可以三次揮手)


    TCP三次握手失敗時,服務端如何處理?
    1.如果服務端沒有收到SYN,則什么都不做(因為壓根沒有建立起來連接,出現(xiàn)情況可能是SYN丟失)
    2.服務端發(fā)送了SYN和ACK后,沒有收到客戶端的ACK,此時則說明客戶端可能不在線,此時發(fā)送一個RST重置連接,并且釋放已有資源。


    TIME_WAIT有什么用?
    在TIME_WAIT狀態(tài)時,主動關(guān)閉方?jīng)]有直接調(diào)用close釋放資源,而是等到確保被動關(guān)閉方收到ACK確認后調(diào)用close,主動關(guān)閉方才調(diào)用。

    如果沒有TIME_WAIT,主動關(guān)閉方直接再發(fā)送完ACK后斷開連接,就會有如下幾種情況。

    • 被動關(guān)閉方?jīng)]有close釋放資源,則新啟用的客戶端就有可能會出現(xiàn)和原來的客戶端具有一樣的地址信息。
    • 主動關(guān)閉方發(fā)送的ACK丟失,被動關(guān)閉方?jīng)]有收到這個ACK,就會卡在LACK_ACK狀態(tài),所以超時后被動關(guān)閉方會重傳一個FIN。

    這時就會有兩種情況
    1.剛啟用的新客戶端綁定地址信息成功,但是此時卻收到了被動關(guān)閉方重傳的FIN,對新連接產(chǎn)生影響。
    2.如果新啟用的客戶端向服務端發(fā)送SYN連接,但是此時服務端處于LACK_ACK狀態(tài),此時他需要的是ACK而不是SYN,所以他會發(fā)送一個RST來重置連接。

    所以為了避免上述幾種情況,就添加了TIME_WAIT,等待一段時間確保被動關(guān)閉方收到ACK,即使沒有收到,也留有了足夠的時間來給被動關(guān)閉方進行FIN的重傳。

    等待的時間:默認為兩個MSL時間(報文最大生存時間)


    一臺主機上出現(xiàn)大量的TIME_WAIT是什么原因?如何處理?
    TIME_WAIT狀態(tài)是出現(xiàn)在主動關(guān)閉方的,如果出現(xiàn)大量的TIME_WAIT,就說明有大量的連接被主動關(guān)閉,可能是惡意攻擊或者爬蟲等。處理方法,調(diào)整TIME_WAIT的等待時間或者開啟地址重用(運行新的套接字使用已綁定的地址端口,因為TIME_WAIT中的套接字無法綁定,啟用后就可以直接頂替掉原來的)。


    一臺主機上出現(xiàn)大量的CLOSE_WAIT是什么原因?如何處理?
    CLOSE_WAIT狀態(tài)是在被動關(guān)閉方收到主動關(guān)閉方的FIN后進入的,此時主動關(guān)閉方已經(jīng)不再發(fā)送數(shù)據(jù),所以此時被動關(guān)閉方的讀端已經(jīng)被關(guān)閉,但是被動關(guān)閉方還需要等到他所有的數(shù)據(jù)發(fā)送完才會結(jié)束,所以此時被動關(guān)閉方會等待上層應用進行處理,處理結(jié)束后才會發(fā)送FIN。而如果出現(xiàn)大量的CLOSE_WAIT,則說明被動關(guān)閉方的上層應用處理有問題,沒有正確的關(guān)閉SOCKET釋放資源,所以此時就不會發(fā)送FIN,導致一直卡在CLOSE_WAIT。


    可靠傳輸

    TCP與UDP不一樣,他能夠確保數(shù)據(jù)安全有序的到達對端。
    通過以下方式

  • 面向連接
  • 確認應答機制(確保對端是否收到數(shù)據(jù),并且根據(jù)序號使數(shù)據(jù)有序)
  • 超時重傳機制(確保數(shù)據(jù)丟失后能夠重傳)
  • TCP首部報文中的序號和確認序號(確保數(shù)據(jù)有序)
  • TCP首部報文中的校驗和(確保收發(fā)數(shù)據(jù)一致,不一致則要求重傳)

  • 確認應答

    TCP在首部中給每一個發(fā)送的數(shù)據(jù)都設(shè)置了序號和確認序號。
    通過序號和確認序號,發(fā)送方告訴了接收方我發(fā)送的數(shù)據(jù)的序號,以及數(shù)據(jù)的長度。而接收方則回復發(fā)送方,我已經(jīng)收到了哪些數(shù)據(jù),你下一次應該從哪一個位置開始發(fā)送。

    seq:本條數(shù)據(jù)的起始序號。為上一條數(shù)據(jù)的ack
    ack:對對方發(fā)送數(shù)據(jù)的確認序號,告訴對方這個位置之前的所有數(shù)據(jù)已收到。確認序號為本條數(shù)據(jù)的起始序號加上數(shù)據(jù)長度。也就是上一條的seq + len
    len:本條數(shù)據(jù)的長度。

    這里簡單的畫個圖


    如果在傳輸過程中,前面的某一個數(shù)據(jù)丟失,即使這里的1025-2048和2049-3072已經(jīng)到達,但是這些數(shù)據(jù)的依舊無法確認回復,因為確認回復必須要保證確認序號ack前的所有數(shù)據(jù)都要到達。這么做的目的是為了防止因為確認回復的丟失導致的重傳。

    即使是因為丟包或者延遲而導致前面的數(shù)據(jù)晚到或重傳,等到接收到重傳的數(shù)據(jù)后,再一個個對之前發(fā)送的數(shù)據(jù)進行確認應答,并通過序號在接受緩沖區(qū)中進行排序。


    超時重傳

    在通信時,某一主機在給另一個主機發(fā)送數(shù)據(jù)后,可能會因為延遲或者丟包等網(wǎng)絡(luò)原因,導致數(shù)據(jù)不能到達,為了確保數(shù)據(jù)能夠到達對端,TCP加入了超時重傳機制,當發(fā)送端在特定的時間內(nèi)沒有收到來自接收端的確認應答時,就會重新發(fā)送,

    同時,不僅發(fā)送的數(shù)據(jù)會丟失,確認應答也有可能丟失,這時也會重傳。

    這個時間間隔也需要合理設(shè)置

    最理想的情況下, 找到一個最小的時間, 保證 “確認應答一定能在這個時間內(nèi)返回”.
    但是這個時間的長短, 隨著網(wǎng)絡(luò)環(huán)境的不同, 是有差異的
    如果超時時間設(shè)的太長, 會影響整體的重傳效率;
    如果超時時間設(shè)的太短, 有可能會頻繁發(fā)送重復的包

    TCP為了保證無論在任何環(huán)境下都能比較高性能的通信, 因此會動態(tài)計算這個最大超時時間

    Linux中(BSD Unix和Windows也是如此), 超時以500ms為一個單位進行控制, 每次判定超時重發(fā)的超時
    時間都是500ms的整數(shù)倍.
    如果重發(fā)一次之后, 仍然得不到應答, 等待 2500ms 后再進行重傳
    如果仍然得不到應答, 等待4500ms 進行重傳. 依次類推, 以指數(shù)形式遞增
    累計到一定的重傳次數(shù), TCP認為網(wǎng)絡(luò)或者對端主機出現(xiàn)異常,強制關(guān)閉連接


    避免丟包重傳

    滑動窗口

    從前面的確認應答機制可以看到,如果對于每一個數(shù)據(jù),發(fā)送后等需要等到接受其回復確認,才發(fā)送下一個數(shù)據(jù),就會導致效率的低下,尤其是網(wǎng)絡(luò)較差時,數(shù)據(jù)的往返之間過長的情況。
    既然這樣一收一發(fā)的效率過慢,那么一次性發(fā)送多條,就可以解決這種問題,但是如果發(fā)送的數(shù)量過多,就可能會導致緩沖區(qū)滿而出現(xiàn)丟包,為了控制發(fā)送數(shù)據(jù)的規(guī)模,于是TCP就引入了滑動窗口機制。

    在TCP首部中我們看到有一個窗口大小的字段,那個就是滑動窗口的大小,其限制了發(fā)送方最多發(fā)送多少數(shù)據(jù)。同時還有MSS(最大數(shù)據(jù)段大小,選取兩邊最小的一個MSS作為最大數(shù)據(jù)段大小),在三次握手的時候雙方進行協(xié)商,規(guī)定好通信時的MSS和窗口大小。

    窗口大小不能大于接收方的接受緩沖區(qū)中剩余空間大小,否則多出來的數(shù)據(jù)會直接丟棄,導致丟包。

    發(fā)送端維護發(fā)送窗口:用于限制一次能夠發(fā)送的數(shù)據(jù)
    后沿:數(shù)據(jù)發(fā)送的起始位置,等待確認回復的數(shù)據(jù),如果得到了回復,則后沿移動。
    前沿:數(shù)據(jù)發(fā)送的結(jié)束位置,前沿減去后沿必須小于等于窗口大小,移動取決于窗口大小。

    例如這張圖,窗口大小為4000,當1001-2001的數(shù)據(jù)得到回復后,窗口前沿后沿都向后移動1000.

    接收端維護接受窗口:用于進行數(shù)據(jù)的排序。
    后沿:數(shù)據(jù)接受的起始位置,移動取決于是否收到后沿數(shù)據(jù)。
    前沿:接收緩沖區(qū)剩余空間大小加上后沿,移動取決于接收緩沖區(qū)剩余大小。

    滑動窗口機制允許發(fā)送端根據(jù)窗口大小和mss連續(xù)發(fā)送多條數(shù)據(jù),并且為丟包的情況,也做好了準備。
    其又引入了下面三個協(xié)議。

    停止等待協(xié)議

    停止等待協(xié)議就是得到一條回復,才發(fā)送下一條數(shù)據(jù)。
    如圖

    回退N步協(xié)議

    一條數(shù)據(jù)丟失了,則需要發(fā)送端將這條數(shù)據(jù)以后的數(shù)據(jù)全部重傳

    選擇重傳協(xié)議

    如果一條協(xié)議丟失了,就僅僅對丟失的數(shù)據(jù)進行重傳


    流量控制

    接收端處理數(shù)據(jù)的速度是有限的. 如果發(fā)送端發(fā)的太快, 導致接收端的緩沖區(qū)被打滿, 這個時候如果發(fā)送端繼續(xù)發(fā)送,
    就會造成丟包, 繼而引起丟包重傳等等一系列連鎖反應.
    因此TCP支持根據(jù)接收端的處理能力, 來決定發(fā)送端的發(fā)送速度。這個機制就叫做流量控制

    • 接收端將自己可以接收的緩沖區(qū)大小放入 TCP 首部中的 “窗口大小” 字段, 通過ACK端通知發(fā)送端;
    • 窗口大小字段越大,說明網(wǎng)絡(luò)的吞吐量越高;
    • 接收端一旦發(fā)現(xiàn)自己的緩沖區(qū)快滿了, 就會將窗口大小設(shè)置成一個更小的值通知給發(fā)送端;
    • 發(fā)送端接受到這個窗口之后, 就會減慢自己的發(fā)送速度
    • 如果接收端緩沖區(qū)滿了, 就會將窗口置為0; 這時發(fā)送方不再發(fā)送數(shù)據(jù), 但是需要定期發(fā)送一個窗口探測數(shù)據(jù)段,使接收端把窗口大小告訴發(fā)送端

    擁塞控制

    雖然滑動窗口能夠高效的發(fā)送大量的數(shù)據(jù),但是在開始階段就發(fā)送大量的數(shù)據(jù),也可能會出現(xiàn)問題。 假設(shè)此時網(wǎng)絡(luò)狀態(tài)不是很好,可能有很多主機在使用,導致網(wǎng)絡(luò)的擁擠,在不了解網(wǎng)絡(luò)狀態(tài)的情況下貿(mào)然發(fā)送大量的數(shù)據(jù),可能就會導致發(fā)送的數(shù)據(jù)越多,丟包也就越多。
    所以TCP又引入了一個擁塞控制的機制來解決這個問題。

    擁塞控制:以一種慢啟動,快增長的傳輸方式,進行根據(jù)網(wǎng)絡(luò)狀態(tài)調(diào)整發(fā)送速度的機制

    先發(fā)少量的數(shù)據(jù),搞清楚當前的網(wǎng)絡(luò)狀況,再根據(jù)網(wǎng)絡(luò)的狀態(tài)來調(diào)整速度,如果網(wǎng)絡(luò)狀態(tài)正常,則快速的增加發(fā)送的速度。


    此處引入一個概念程為擁塞窗口
    發(fā)送開始的時候, 定義擁塞窗口大小為1;
    每次收到一個ACK應答, 擁塞窗口加1;
    每次發(fā)送數(shù)據(jù)包的時候, 將擁塞窗口和接收端主機反饋的窗口大小做比較, 取較小的值作為實際發(fā)送的窗口

    少量的丟包, 我們僅僅是觸發(fā)超時重傳; 大量的丟包, 我們就認為網(wǎng)絡(luò)擁塞;
    當TCP通信開始后, 網(wǎng)絡(luò)吞吐量會逐漸上升; 隨著網(wǎng)絡(luò)發(fā)生擁堵, 吞吐量會立刻下降;

    慢開始:設(shè)置擁塞窗口大小為1,之后每次收到一個確認回復ACK,就將擁塞窗口的大小*2。當達到慢開始的門限值時,就會使用擁塞避免算法。慢開始的作用主要是不了解當前的網(wǎng)絡(luò)狀況,為了避免因為快速增長而導致的大量丟包情況。

    擁塞避免:當達到慢開始門限值的時候,就會啟用加法增大算法,即每次收到一個確認回復ACK,就讓窗口大小+1。當出現(xiàn)網(wǎng)絡(luò)擁塞的情況時(丟包、超時),令擁塞窗口的門限值等于當前擁塞窗口大小的一半(即乘法減小),接著將當前窗口大小設(shè)置為1,重新進入慢開始。

    快重傳:當連續(xù)收到三次重復確認應答時,他此時就會對確認序號ack位置的數(shù)據(jù)進行重傳,因為發(fā)送三次確認回復的時間比起等待超時要少了很多,所以這種機制也被稱為快速重傳機制。

    快恢復:當出現(xiàn)了快重傳的情況時,就說明當前網(wǎng)絡(luò)狀況存在問題,但是又由于我們能夠連續(xù)三次收到確認應答,就說明了當前的問題并不是很嚴重,沒有必要重新進行慢開始。所以當前會將擁塞窗口的門限值設(shè)置為當前窗口大小的一般,并直接將窗口大小設(shè)置為門限值,直接開始擁塞避免。由于跳過了慢開始階段直接進行擁塞避免,因此被稱為快恢復

    擁塞控制,歸根結(jié)底就是TCP想盡可能快的傳送數(shù)據(jù),但是又怕給網(wǎng)絡(luò)造成巨大的壓力,所以采取這種當網(wǎng)絡(luò)狀態(tài)好是吞吐量上升,網(wǎng)絡(luò)狀態(tài)不好時吞吐量下降的折中方法。


    挽救傳輸性能

    快速重傳

    如下圖,當某一個報文段丟失時,接收端會一直回復后沿數(shù)據(jù)的確認應答,提示發(fā)送端我想要的是從1001開始的數(shù)據(jù),即使中間發(fā)送了后面的數(shù)據(jù),接收端也不會進行確認,而是不斷的回復后沿數(shù)據(jù)的確認應答。而如果發(fā)送端連續(xù)三次收到了同一個確認應答,他就了解到了有數(shù)據(jù)的丟失,他此時就會對確認序號ack位置的數(shù)據(jù)進行重傳。

    這樣的方法比之前的超時重傳要快,因為發(fā)送三次確認回復的時間比起等待超時要少了很多,所以這種機制也被稱為快速重傳機制。

    為什么是三次?
    三次提供了一個緩沖的時間,可以適當避免因為網(wǎng)絡(luò)延遲而導致的數(shù)據(jù)延遲到達。三次其實也是相當于一個確認,如果在第一次或者第二次后收到了該數(shù)據(jù),則就不會再發(fā)送后面幾條,發(fā)送端也不需要重傳。


    延遲應答

    接收方接收到數(shù)據(jù)后并不會馬上進行確認回復,因為一旦回復就會因為接收緩沖區(qū)的剩余空間變小,導致發(fā)送方的滑動窗口變小,使傳輸?shù)耐掏铝孔冃 ?br /> 所以引入延遲應答機制, 延遲一段時間,等待上層進行數(shù)據(jù)處理一段時間再進行答復,可能在應答的時候上層就已經(jīng)將數(shù)據(jù)取出了,這樣就保證了窗口的大小不會變小,吞吐量不會變慢,并且等待的時候上層也在處理,所以不會出現(xiàn)緩沖區(qū)不足的情況。

    延遲應答保證網(wǎng)絡(luò)不擁塞的情況下盡量提高傳輸效率


    捎帶應答

    接收方接受到數(shù)據(jù)之后,需要進行確認回復。而確認回復其實就是在報頭中標記一個ACK確認序號,發(fā)送這樣的只有響應的空報文十分浪費,所以為了減少空報頭的響應占據(jù)帶寬,所以引入了捎帶應答機制,在即將要發(fā)送的數(shù)據(jù)頭部中加上上一條接收到的數(shù)據(jù)的確認回復。比如三次握手中第二次的ACK+SYN就是捎帶應答。


    面向字節(jié)流

    對于TCP來說,每當創(chuàng)建一個socket的時候,就會同時在內(nèi)核中創(chuàng)建一個接收緩沖區(qū)和發(fā)送緩沖區(qū)。

    接收:對于接收到的數(shù)據(jù),并非像UDP一樣一條一條往上交付,而是先將接收到的數(shù)據(jù)放入緩沖區(qū),再根據(jù)上層所需要的長度,從接收緩沖區(qū)中取出相應的數(shù)據(jù)交付。
    發(fā)送:對于發(fā)送的數(shù)據(jù)并不會直接發(fā)送,而是先存入發(fā)送緩沖區(qū)。如果數(shù)據(jù)過大,則會被拆分成多個TCP數(shù)據(jù)包發(fā)送。而如果數(shù)據(jù)過小,則會在發(fā)送緩沖區(qū)中等待,直到大小合適后再從發(fā)送緩沖區(qū)中取出數(shù)據(jù)發(fā)送(延遲發(fā)送可關(guān)閉)。

    優(yōu)點:這種傳輸方式比較靈活,對于多個小數(shù)據(jù),會合并為一條大的數(shù)據(jù)一次性發(fā)送過去,這樣就大大的減少了IO的次數(shù)。接收方也更加靈活,他可以任意取出想要的數(shù)據(jù),不會像UDP一樣必須交付一條完整的報文。
    缺點:因為數(shù)據(jù)會在緩沖區(qū)中進行合并或者拆分,這就導致了數(shù)據(jù)直接的邊界無法控制,所以TCP交付的這條數(shù)據(jù)可能并非一條完整的數(shù)據(jù),而是半條或者多條數(shù)據(jù),所以可能會導致上層會將多條數(shù)據(jù)按照一條來處理。這也就是TCP粘包問題。

    TCP粘包問題:即TCP可能將多條數(shù)據(jù)按照一條處理(UDP不會有這種問題,UDP在首部中定義了數(shù)據(jù)報長度,確保每次只交付一條完整的數(shù)據(jù))

    解決方案:需要我們自己進行邊界的管理。
    1.每條數(shù)據(jù)之間以特殊字符進行間隔(如果數(shù)據(jù)中有該字符可能要轉(zhuǎn)義處理)
    2.數(shù)據(jù)定長傳輸,不夠則補位(數(shù)據(jù)如果過短,則會傳遞大量無用的補位數(shù)據(jù))
    3.應用層協(xié)議頭部定義數(shù)據(jù)長度(這里可以參考http協(xié)議和udp協(xié)議的做法)

    http:頭部以\r\n\r\n表示結(jié)束,并且在頭部的Content-Length確定正文長度。
    udp:傳輸層就解決了,在頭部中就已經(jīng)定義數(shù)據(jù)報長度。


    基于TCP的應用層知名協(xié)議

    • HTTP
    • HTTPS
    • SSH
    • Telnet
    • FTP
    • SMTP

    總結(jié)

    以上是生活随笔為你收集整理的计算机网络 | 传输层 :UDP与TCP协议详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。