更好閱讀體驗:《理解 TCP 和 UDP》— By Gitbookgit
TCP 在傳送數據以前必須先創建鏈接,數據傳送結束後要釋放鏈接。
TCP 不提供廣播或多播服務,因爲 TCP 要提供可靠的、面向鏈接的運輸服務,所以不可避免地增長了許多的開銷,如確認、流量控制、計時器以及鏈接管理等。 github
而 UDP 在傳送數據以前不須要先創建鏈接。接收方收到 UDP 報文以後,不須要給出任何確認。
雖然 UDP 不提供可靠交付,但在某些狀況下 UDP 倒是一種最有效的工做方式。 網絡
簡單來講就是:併發
UDP:單個數據報,不用創建鏈接,簡單,不可靠,會丟包,會亂序;tcp
TCP:流式,須要創建鏈接,複雜,可靠 ,有序。spa
UDP 全稱 User Datagram Protocol, 與 TCP 同是在網絡模型中的傳輸層的協議。計算機網絡
UDP 的主要特色是:3d
無鏈接的,即發送數據以前不須要創建鏈接,所以減小了開銷和發送數據以前的時延。code
不保證可靠交付,所以主機不須要爲此複雜的鏈接狀態表blog
面向報文的,意思是 UDP 對應用層交下來的報文,既不合並,也不拆分,而是保留這些報文的邊界,在添加首部後向下交給 IP 層。
沒有阻塞控制,所以網絡出現的擁塞不會使發送方的發送速率下降。
支持一對1、一對多、多對一和多對多的交互通訊,也便是提供廣播和多播的功能。
首部開銷小,首部只有 8 個字節,分爲四部分。
UDP 的經常使用場景:
名字轉換(DNS)
文件傳送(TFTP)
路由選擇協議(RIP)
IP 地址配置(BOOTP,DHTP)
網絡管理(SNMP)
遠程文件服務(NFS)
IP 電話
流式多媒體通訊
UDP 數據報分爲數據字段和首部字段。
首部字段只有 8 個字節,由四個字段組成,每一個字段的長度是 2 個字節。
首部各字段意義:
源端口:源端口號,在須要對方回信時選用,不須要時可全 0.
目的端口:目的端口號,在終點交付報文時必需要使用到。
長度:UDP 用戶數據報的長度,在只有首部的狀況,其最小值是 8 。
檢驗和:檢測 UDP 用戶數據報在傳輸中是否有錯,有錯就丟棄。
UDP 數據報首部中檢驗和的計算方法比較特殊。
在計算檢驗和時,要在數據報以前增長 12 個字節的僞首部,用來計算校驗和。
僞首部並非數據報真正的首部,是爲了計算校驗和而臨時添加在數據報前面的,在真正傳輸的時候並不會把僞首部一併發送。
僞首部個字段意義:
第一字段,源 IP 地址
第二字段,目的 IP 地址
第三字段,字段全 0
第四字段,IP 首部中的協議字段的值,對於 UDP,此字段值爲 17
第五字段,UDP 用戶數據報的長度
校驗和的計算中,頻繁用到了二進制的反碼求和運算,運算規則見下:
二進制反碼求和運算
0 + 0 = 0 1 + 0 = 0 + 1 = 1 1 + 1 = 10
其中 10 中的 1 加到了下一列去,若是是最高列的 1 + 1 ,那麼獲得的 10 留下 0 , 1 移到最低列,與最低位再作一次二進制加法便可。
檢驗和計算過程
把首部的檢驗和字段設置爲全 0
把僞首部以及數據段當作是許多 16 位的字串接起來。
若數據段不是偶數個字節,則填充一個全 0 字節,可是這個字節不發送。
經過二進制反碼運算,計算出 16 位字的和。
讓第一行和第二行作二進制反碼運算。
將第一行和第二行的結果與第三行作二進制反碼計算,以此類推。
最後運算結果取反,獲得校驗和。
把計算出來的校驗和值,填入首部校驗和字段。
接收方收到數據報以後,按照一樣的方法計算校驗和,若是有差錯,則丟棄這個數據報。
能夠看出校驗和,既檢查了 UDP 用戶數據報的源端口號和目的端口號以及數據報的數據部分,又檢查了 IP 數據報的源 IP 地址和目的地址。
一個校驗和例子
假設一個 UDP 數據報:
各字段以二進制表示:
1001 1001 0001 0011 //僞首部源IP地址前16位,值:153.19 0000 1000 0110 1000 //僞首部源IP地址後16位,值:8.104 1010 1011 0000 0011 //僞首部目的IP地址前16位,值:171.3 0000 1110 0000 1011 //僞首部目的IP地址後16位,值:14.11 0000 0000 0001 0001 //僞首部UDP協議字段表明號,值:17 0000 0000 0000 1111 //僞首部UDP長度字段,值:15 0000 0100 0011 1111 //UDP頭部源IP地址對應的進程端口號,值:1087 0000 0000 0000 1101 //UDP頭部目的IP地址對應的進程端口號,值:13 0000 0000 0000 1111 //UDP頭部UDP長度字段,值:15 0000 0000 0000 0000 //UDP頭部UDP檢驗和,值:0 0101 0100 0100 0101 //數據字段 0101 0011 0101 0100 //數據字段 0100 1001 0100 1110 //數據字段 0100 0111 0000 0000 //數據字段+填充0字段
按照二進制反碼運算求和,結果:10010110 11101101
結果求反碼得出校驗和:01101001 00010010