UDP,全稱User Datagram Protocol,用戶數據報協議,是TCP/IP四層參考模型中傳輸層的一種面向報文的、無連接的、不能保證可靠的、無擁塞控制的協議。UDP協議因為傳輸效率高,常用於即時通信,比如視頻/語音聊天,直播等。
1. UDP數據報的格式
用戶數據報UDP有兩個字段:數據字段和首部字段。首部字段很簡單,只有8個字節,有四個字段組成,每個字段的長度都是兩字節。各段意義如下:
- 源端口:源端口號。在需要對方回信時選用。不需要時可用全0。
- 目的端口:目的端口號。這在終點交付報文時必須要使用到。
- 長度:UDP用戶數據報的長度,其最小值是8(僅首部)。
- 校驗和:檢測UDP用戶數據報在傳輸中是否有錯。有錯就丟棄。
2. UDP校驗和的計算
UDP的校驗和需要計算UDP首部加數據荷載部分,但也需要加上UDP偽首部。這個偽首部指,源地址、目的地址、UDP數據長度、協議類型(0x11),協議類型就一個字節,但需要補一個字節的0x0,構成12個字節。偽首部+UDP首部+數據一起計算校驗和。
UDP檢驗和的計算方法是:
- 按每16位求和並在高位補0得到得出一個32位的求和結果;
- 如果這個32位的求和結果,高16位不為0,則高16位加低16位並且高位補0再得到一個32位的結果;
- 重復第2步直到高16位為0,將低16位取反,得到校驗和。
3. UDP校驗和計算方法的Java實現
一個實際例子:
key | hex |
---|---|
源IP地址 | 0x0aaa, 0x3bbf |
目的IP地址 | 0xd20e, 0x960d |
協議類型 | 0x0011 |
UDP長度 | 0x001c |
源端口 | 0xd123 |
目的端口 | 0x2742 |
長度 | 0x001c |
校驗和 | 0x285c(用於驗證) |
UDP數據 | 0x0000, 0x6c41, 0x5661, 0x0000, 0x0e00, 0xf8b6, 0xd401, 0x9313, 0x0000, 0x0000, 0x0000 |
Java實現:
public class CheckSumDemo {
public static void main(String[] args) {
/**
* 源IP
* 目的IP
* 協議類型
* UDP數據長度
* 源端口
* 目的端口
* UDP數據
* UDP數據
*/
int[] udp = {
0x0aaa, 0x3bbf,
0xd20e, 0x960d,
0x0011,
0x001c,
0xd123,
0x2742,
0x001c,
0x0000,0x6c41,0x5661,0x0000,0x0e00,0xf8b6,0xd401,0x9313,0x0000,0x0000,0x0000
};
int checkSum = 0x285c;
String s = udpCheckSum(udp);
System.out.println(s);
System.out.println(Integer.toHexString(checkSum).equals(s));
}
public static String udpCheckSum(int[] nums) {
int res = 0;
for (int num : nums) {
res += num;
if (res >>> 16 != 0) {
res = (res >>> 16) + (res & 0xffff);
}
}
return Integer.toHexString(~res).substring(4);
}
}
結果輸出:
285c
true