UDT协议解析及C/C++代码实现
基于 UDP 的協議 (UDT) 是一種高性能數據傳輸協議。用于廣域高速網絡上的分布式數據密集型應用程序。 UDT 使用 UDP 傳輸具有自己的可靠性控制和擁塞控制機制的批量數據。 新協議可以以比 TCP 高得多的速度傳輸數據。 UDT 也是一個高度可配置的框架,可以適應各種擁塞控制算法。
為什么需要使用UDT?
UDT 的最初(和主要)目的是為廣域網上的分布式數據密集型應用程序提供高性能傳輸接口,因為效率和公平原因,TCP 很少能很好地工作。它也可以用于 TCP 不適合的其他情況(例如,多媒體流、防火墻穿孔、部分可靠性等)
沒有明確的標準來確定何時使用 UDT 或何時不使用。一般來說,如果對 TCP 的性能或功能不滿意,UDT 可能是你所需要的,尤其是在少量批量源共享豐富帶寬的高速網絡中。
UDT數據包
UDT有兩種包:數據包和控制包;數據包。 它們通過第 1 位(標志位)來區分包頭。
數據包頭從 0 開始。包序號使用標志位之后的 31 位。 UDT 使用基于數據包的排序,即每發送一次,序列號加1數據包按照包發送的順序。序號是將其增加到最大數量 (2^31 - 1) 后進行包裝。
數據包頭結構如下:
以上是發送數據包時的 32 位時間戳和目標套接字 ID。時間戳是一個相對值開始。
UDT控制包和類型信息
UDT中有8種類型的控制包和類型信息被放在標題的位域 1 - 15 中。 內容以下字段取決于數據包類型。 前 128 位必須存在于數據包頭中,而可能存在空控件信息字段,取決于數據包類型。
特別是,UDT 對 ACK 數據包使用子序列。 每個 ACK 包被分配一個唯一遞增的 16 位序列號,即與數據包序號無關。 ACK序列number 使用控制數據包中的第 32 - 63 位。 ACK 序列號范圍從 0 到 (2^31 - 1)。
協議連接握手
握手包有如下信息(假設UDT 套接字 A 將此握手發送給 B):
Version: 32 位,UDT 版本。
Type:32 位,套接字類型(STREAM 或 DGRAM)。
Initial Sequence Number:32位,初始包序號。
MTU:32 位,最大數據包大小(包括 UDP/IP 標頭)。
Flow Window:32位,最大流窗口大小。
Requested Type: 32 位,連接類型(常規或集合) 。
ID:32位,套接字ID。
SYN cookie:32 位,SYN cookie。
Peer IP Address:128位,對端UDP套接字的IP地址 。
當服務器第一次收到客戶端的連接請求時,它根據客戶端地址和一個密鑰并將其發送回客戶端。然后客戶端必須發送將相同的 cookie 返回到服務器。
服務器在收到握手包和正確的cookie時,將數據包大小和最大窗口大小與其自己的值進行比較并將其自己的值設置為較小的值。
來自客戶端的連接類型應設置為 1。
來自服務器的響應應設置為 -1
客戶端還應該檢查響應是否來自服務器原始請求已發送至。
保持活動狀態
確認(ACK)
在收到 ACK 數據包時:更新最大的確認序列號。 在這個ACK中發回一個ACK序列號相同的ACK2。更新 RTT 和 RTTVar。將 ACK 和 NAK 周期都更新為 4 * RTT + RTTVar + SYN。 更新流窗口大小、更新估計的鏈路容量、更新發送者的緩沖區、更新發件人的丟失列表。
Ack Squence Number:32 bits,所有數據包的序號以前的數據包已經收到。
RTT (microseconds):32 位,RTT(以微秒為單位)。
RTT Variance (microseconds):32位,RTT方差。
Buffer Available (packets):32位,可用緩沖區大小(以字節為單位)。
Rate (packets/second):32 位:數據包接收率(以數據包數量計/ 每秒)。
Link Capacity (packets/second):32 位,估計的鏈路容量(以數據包數計/每秒) 。
否定確認 (NAK)
在收到 NAK 數據包時:將 NAK 中攜帶的所有序列號添加到發送者的損失中列表。
Missing Sequence Number:32位壓縮丟失信息的整數數組。
關機
如果其中一個連接的 UDT 實體正在關閉,它將發送一個關閉消息給對端。對端,收到此信息后
消息,也將被關閉。
此關閉消息,使用 UDP,只發送一次,不保證能收到。
確認(ACK2)
在收到 ACK2 數據包時: 在 ACK History Window 中根據 此 ACK2 中的 ACK 序列號。更新已確認的最大 ACK 號。根據ACK2到達時間和ACK計算新的rtt出發時間。
UDT協議解析C/C++代碼實現
static void dissect_udt(u_char *udt_data, int offset, int Payload_len) {udt_conv = (udt_conversation *)malloc(sizeof(udt_conversation));if (udt_conv == NULL) {return ;}if (dissect_udt_heur(udt_data, offset, Payload_len))return ;if (is_control) {const char *typestr = val_to_str(type, udt_packet_types);switch (type) {case UDT_PACKET_TYPE_ACK:...break;case UDT_PACKET_TYPE_ACK2:...break;case UDT_PACKET_TYPE_NAK: {unsigned int max = Payload_len;if (max > UDT_MAX_NAK_LENGTH)max = UDT_MAX_NAK_LENGTH;for (i = UDT_CONTROL_OFFSET; i <= (max-4) ; i = i + 4) {uint32_t start, finish;int is_range;is_range = ntohl(*(uint32_t*)(udt_data + offset + i)) & 0x80000000;start = get_sqn(udt_conv, ntohl(*(uint32_t*)(udt_data + offset + i)) & 0x7fffffff);if (is_range) {if (i > (max-8)) {...break;}finish = get_sqn(udt_conv, ntohl(*(uint32_t*)(udt_data + offset + i + 4)) & 0x7fffffff);...i = i + 4;} else {...}}...break;}default:...break;}}else {...}運行結果:
總結
UDT是一種高性能數據傳輸協議。它專為通過高速廣域網 (WAN) 大量傳輸大型數據集而設計。基于 UDP 的協議是 TCP 協議的一種更有效的替代方案,并且可以以更高的速度傳輸數據。
歡迎關注微信公眾號【程序猿編碼】,需要UDT協議解析完整源碼的添加本人微信號(c17865354792)
參考:http://tools.ietf.org/search/draft-gg-udt-03
總結
以上是生活随笔為你收集整理的UDT协议解析及C/C++代码实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 真格投资汇总
- 下一篇: 绘声绘影导出视频过大