前言
不同於 TCP(stream-oriented,每個 IP datagram 中的資料都有其關聯) 協定,UDP 屬於不可靠的協定,因此並無法保證封包一定可以到達目的地(這表示即使封包沒到達目的地,發送端也不會收到任何通知)。
以下為 UDP datagram 是如何封裝在 IP datagram 中:
由於 UDP 協定必須依靠 IP 協定將資料傳送出去,因此在 UDP datagram 外面還要另外加上 IP datagram。
UDP Header
雖然 UDP 是種不可靠的協定,但相對於 TCP 單純的多,以下是 UDP Header 的內容:
其中比較需要說明的為 UDP length 的部份,而此 length 指的是整個 UDP header 的長度,最少為 8,而從圖中就可以看出,當 length = 8,表示 data 的部份為 0 byte。
而 checksum 的欄位,可以作為驗證資料正確與否來用,但接收端驗證後,若即使有資料錯誤的情況發生,也只會直接丟棄封包而不會通知傳送端,因此有些網路設備並沒有實作或是開啟驗證 checksum 的功能。
IP Fragmentation
要瞭解 IP 是如何將封包拆開再結合之前,必須先看看 IP header 的內容:當資料量過大時,IP 會自動將資料拆開,分成多個 datagram 進行傳送。
其中將資料拆開成多個 datagram 的工作在傳送段電腦完成;而將多個 datagram 組合成原本的資料,則是接收段電腦的工作。
而在 IP header 中用來控制資料拆開與組合的資訊,即為 identification、flag、fragmentation offset 三個欄位。
此外,若是封包在傳遞的過程中遺失了應該要怎辦? 答案就是:「全部重送一次」。
但 IP 沒有可以判斷傳送是否發生錯誤的機制,因此必須仰賴上一層的 protocol(例如:TCP) 來處理,而 UDP 沒有此種驗證機制,因此若是有需求,就必須在 UDP application 中有提供才行。
那到底將資料拆成多個封包後會變得如何呢? 以下有圖可以說明:
UDP datagram 可以到多大?
理論上,每一個 UDP datagram 最大可以到 65535 bytes(20 bytes IP header + 8 bytes UDP header + 63307 bytes data),但實際上,由於 socket API 或是 OS kernel 的限制,有時候並無法使用這麼大的 UDP datagram 進行傳送。
而實際應用上,其實也沒用到如此大的 UDP datagram,舉例來說:
NFS:使用大小為 8192 bytes 的 UDP datagram
DNS、TFTP、BOOTP、SNMP:都使用小於 512 bytes 的 UDP datagram
與 UDP 協定相關的錯誤
ICMP Unreachable Error (Fragmentation Required)
當封包大小超過 MTU 時,就必須將封包拆開了,但此時如果 IP header 中的 DF(don't fragment) flag 若是被啟用,就會發生 ICMP Unreachable Error。
ICMP Source Quench Error
此種錯誤發生在接收端的 buffer 又已經滿了,且來不及處理快速傳入的 UDP datagram 時。
基本上,不一定每個接收端發生此種錯誤時,都會處理 ICMP Source Quench Error 訊息給傳送端,這必須要端看接收端的實作情況。(有些會因為協定是 UDP 而忽略,TCP 則會處理)
沒有留言:
張貼留言