龍恒
摘? 要: 用戶數(shù)據(jù)報協(xié)議(UDP)是一種無連接傳輸層協(xié)議,提供的是一種不可靠的數(shù)據(jù)傳輸服務(wù),不能保證將數(shù)據(jù)按順序、完整地傳送到目的地。本文引入了一些TCP的機制并進(jìn)行了部分調(diào)整,在應(yīng)用層上基于UDP實現(xiàn)了一個具有擁塞控制、重傳等機制的新的數(shù)據(jù)傳輸協(xié)議。測試結(jié)果表明使用該協(xié)議傳輸?shù)乃袛?shù)據(jù)都能正確地到達(dá)目的地,成功解決了可靠性問題,同時其他方面都能滿足設(shè)計要求。
關(guān)鍵詞: UDP; 可靠性; 重傳; 擁塞控制; 流量控制
中圖分類號:TP311? ? ? ? ? 文獻(xiàn)標(biāo)識碼:A? ? ?文章編號:1006-8228(2020)04-33-05
A reliable transmission protocol based on UDP
Long Heng
(Maoming Polytechnic, Maoming, Guangdong 525000, China)
Abstract: User Datagram Protocol (UDP) is a connectionless transport layer protocol, it provides an unreliable data transmission service, and doesn't guarantee that the data transferred to the destination is in order and is integrated. This article introduces some TCP mechanisms and makes some improvement, to realize a UDP based new protocol with the mechanisms of congestion control and retransmission at the application layer. Test results show that all the data transmitted with the protocol can reach the destination correctly. It solved the reliability issues successfully and all aspects can meet the requirements.
Key words: UDP; reliability; retransmission; congestion control; flow control
0 引言
UDP是一種應(yīng)用廣泛的傳輸層協(xié)議,但是傳輸過程中容易出現(xiàn)數(shù)據(jù)包的丟失或失序等問題。而TCP協(xié)議則供了一套完善的保證可靠性的機制,可以保證將數(shù)據(jù)按順序完整地發(fā)送到目的地。本文在UDP的基礎(chǔ)上,引入了一些TCP的概念,在應(yīng)用層上實現(xiàn)了一個可靠的數(shù)據(jù)傳輸協(xié)議,稱為RUTP(Reliable Udp Transmission Protocol)。RUTP實現(xiàn)了接收方流量控制、擁塞控制、重傳和往返時間測量這些保證傳輸可靠性的基本機制[1],并且實現(xiàn)了SACK、Timestamp和Window Scale這三個對提高性能有幫助的功能。
1 協(xié)議首部
RUTP使用一個20字節(jié)的首部,結(jié)構(gòu)如圖1所示,各個字段的含義如表1所示。
其中確認(rèn)序號(acknowledgment)是一個32位的無符號整數(shù)。與RFC793中定義的acknowledgment number作用相同,是對接收到的字節(jié)數(shù)的確認(rèn),取值為被確認(rèn)的數(shù)據(jù)包的序號(sequence)加上該數(shù)據(jù)包所攜帶的數(shù)據(jù)字節(jié)數(shù),也就是下一個期望接收的字節(jié)的序號[2]。
另外還有一些只在特定數(shù)據(jù)包中才會出現(xiàn)的字段,稱為選項字段,其緊跟在RUTP固定首部字段之后。其中與保證可靠性有關(guān)的有兩個:SACK和PZW。SACK是選擇性確認(rèn)字段,其功能與RFC2018中描述的相同[3],但是組織方式有所不同;PZW選項實現(xiàn)的是RFC1122的Probing Zero Windows[4]功能。在一個數(shù)據(jù)包中,RUTP首部出現(xiàn)在UDP首部之后。
2 系統(tǒng)變量
RUTP定義了一系列的系統(tǒng)變量,為了更好地講明問題,把本文中用到的變量做一個簡單的說明:
RMSS:接收方能接收的最大報文段。
SMSS:發(fā)送方能發(fā)送的最大報文段。
MAX_RECV_SEQ:接收到的數(shù)據(jù)包的最大序號。
MAX_RECV_ACK:接收到的數(shù)據(jù)包的最大確認(rèn)序號。
LAST_SEND_SEQ:最后發(fā)送出去的序號,為最近一次發(fā)送出去的攜帶數(shù)據(jù)的數(shù)據(jù)包的序號加上其數(shù)據(jù)字節(jié)數(shù)。
LAST_SEND_ACK:最后發(fā)送出去的確認(rèn)序號,為最近一次接收到的數(shù)據(jù)包的序號加上所包含的數(shù)據(jù)字節(jié)數(shù)。
TS_RECENT:記錄接收到的帶有數(shù)據(jù)的有效數(shù)據(jù)包的時間,當(dāng)該數(shù)據(jù)包的序號小于等于LAST_
SEND_ACK的時候更新TS_RECENT的值。
FLIGHT_SIZE:當(dāng)前發(fā)送出去但是還沒有被接收方確認(rèn)的數(shù)據(jù)的字節(jié)數(shù)。
3 數(shù)據(jù)的接收
RUTP是一種全雙工協(xié)議,通訊的雙方可以同時接收和發(fā)送數(shù)據(jù)。其中接收流程如圖2所示。
3.1 滑動窗口
接收方使用一個稱為“滑動窗口”的機制進(jìn)行流量控制,這是對接收方的接收緩沖區(qū)使用狀況的一個形象的描述,也是判斷數(shù)據(jù)包是否合法的重要依據(jù)之一,圖3顯示了一個滑動窗口在某個時間點的狀態(tài)。
用于描述滑動窗口的重要變量有:窗口大小的最大值(swMax),窗口左邊緣(swLeft)、當(dāng)前窗口大小(swSize)、窗口的右邊緣(swRight),需要注意的是swLeft與swSize相加并不總是等于swRight,因為如果出現(xiàn)丟失/失序的情況,滑動窗口的左邊緣將會停留在接收到的序號連續(xù)的數(shù)據(jù)的最右的位置,在這種情況下接收到的序號更大的合法數(shù)據(jù)包,將會被保存起來等待丟失/失序的數(shù)據(jù)包到達(dá)后再提交給應(yīng)用程序,數(shù)據(jù)保存后,swSize的值將減小。
3.2 數(shù)據(jù)包分類
依據(jù)接收到的數(shù)據(jù)包的序號、TSval值、MAX_RECV_SEQ系統(tǒng)變量、MAX_RECV_ACK系統(tǒng)變量和滑動窗口的狀態(tài)將它們進(jìn)行分類。
3.2.1 非法數(shù)據(jù)包
假設(shè)數(shù)據(jù)包的序號為SEQ,攜帶的數(shù)據(jù)的字節(jié)數(shù)為L,符合以下條件之一的數(shù)據(jù)包被認(rèn)為是非法數(shù)據(jù)包:
⑴ 首部ack標(biāo)志為1,并且符合下列條件之一。
① 攜帶有數(shù)據(jù);
② 確認(rèn)序號小于MAX_RECV_ACK;
③ 序號不處于swLeft-swMax與swLeft+swMax之間。
⑵ 首部的TSval值小于TS_RECENT。這是RFC1323中的PAWS(Protect Against Wrapped Sequence Numbers)[5]要求。
⑶ 序號處于滑動窗口之外,也就是SEQ
3.2.2 失序數(shù)據(jù)包
指的是攜帶有數(shù)據(jù),但是不按順序到達(dá)接收方的數(shù)據(jù)包。這可能是由于延遲、丟失后被重傳等原因造成的。其特點是序號不等于swLeft。
3.2.3 重復(fù)數(shù)據(jù)包
指的是合法的攜帶有數(shù)據(jù),但是前面已經(jīng)成功接收過的數(shù)據(jù)包,其特點是序號大于等于swLeft-swMax并且序號加上L小于swLeft。重復(fù)數(shù)據(jù)包的作用是為了在接收到后立刻發(fā)送一個確認(rèn),這與重傳的算法有關(guān)。
3.2.4 PZW數(shù)據(jù)包
這種數(shù)據(jù)包與在RFC1122中定義的Probing Zero Windows數(shù)據(jù)包類似,但是實現(xiàn)有所不同,在RUTP中PZW數(shù)據(jù)包指的是首部的ack和opt標(biāo)志都為1,且在首部指定了PZW選項的數(shù)據(jù)包。
3.2.5 數(shù)據(jù)段
指的是除了上面各種類型之外、攜帶有數(shù)據(jù)并且按順序到達(dá)的合法數(shù)據(jù)包。
3.3 數(shù)據(jù)的保存
RUTP協(xié)議使用一個接收隊列和一個失序鏈表來保存接收到的數(shù)據(jù)。接收隊列用于保存接收到的數(shù)據(jù)包,每個接收到的數(shù)據(jù)包的序號通過了合法性檢驗后就會被放入接收隊列中,這些數(shù)據(jù)包按序號的從小到大從隊列的首部開始向后排列。
失序鏈表與接收隊列一起工作,它的表項指向接收隊列的失序位置的下一項,與swLeft一起可以標(biāo)識出所有的失序情況。
圖4顯示了swLeft、接收隊列和失序表在某一時刻的狀態(tài)。
為了支持發(fā)送重復(fù)確認(rèn),失序鏈表的每個表項還會保存其創(chuàng)建時滑動窗口的大小。在發(fā)送確認(rèn)時,如果出現(xiàn)失序的情況就使用第一個表項的滑動窗口的值作為其首部的rwnd字段的值,這樣對于發(fā)送方就能符合重復(fù)確認(rèn)的rwnd值相同的要求。
上述設(shè)計方式對生成選擇性確認(rèn)(SACK)信息也有幫助,RUTP的SACK功能與RFC2018中定義的功能相同,但是實現(xiàn)方式有所不同,RUTP中SACK塊是按順序從小到大在首部選項中排序的,而且RUTP的選項沒有TCP的最長40字節(jié)的限制。在生成SACK選項的時候只需遍歷一次失序鏈表即可。
3.4 確認(rèn)的發(fā)送
確認(rèn)指的是接收方發(fā)送的、對本方已經(jīng)接收到的數(shù)據(jù)的情況起告知作用的數(shù)據(jù)包,RUTP的確認(rèn)數(shù)據(jù)包將首部的ack標(biāo)志設(shè)置為1。RUTP協(xié)議在如下幾種情況下會發(fā)送確認(rèn):
⑴ 接收到失序數(shù)據(jù)包、重復(fù)數(shù)據(jù)包或PZW數(shù)據(jù)包都會立刻發(fā)送一個確認(rèn);
⑵ 連續(xù)接收到的未確認(rèn)字節(jié)數(shù)大于等于2×RMSS并且滿足式⑴的要求:
swSize>=min(0.5×swMax,RMSS) ⑴
式⑴是為了防止出現(xiàn)RFC1122中定義的糊涂窗口綜合癥(SWS)。
⑶ 確認(rèn)定時器超時,確認(rèn)定時器實現(xiàn)的是RFC1122中定義的delayed ACK功能,RFC6298要求延遲的時間必須少于500毫秒[6],超時的時候如果未確認(rèn)字節(jié)數(shù)計數(shù)器大于0,就會發(fā)送一個確認(rèn),并且將計數(shù)器設(shè)置為0,確認(rèn)定時器只確認(rèn)以前沒有確認(rèn)過的數(shù)據(jù)。創(chuàng)建確認(rèn)時,其首部各字段的取值如下:
rwnd:如果失序表不為空,就使用第一個表項記錄的滑動窗口值,否則rwnd字段值使用swSize。
acknowledgment:滑動窗口左邊緣swLeft;
sequence:LAST_SEND_SEQ系統(tǒng)變量的值;
TSval:當(dāng)前時間值;
TSecr:TS_RECENT系統(tǒng)變量的值。
RUTP不會重傳已丟失了的確認(rèn),要等到接收到發(fā)送方發(fā)送的數(shù)據(jù)包才會繼續(xù)發(fā)送確認(rèn)。
4 數(shù)據(jù)的發(fā)送
圖5顯示了數(shù)據(jù)的發(fā)送流程。
4.1 數(shù)據(jù)包類型
在一個功能完整的發(fā)送方,除了可以發(fā)送數(shù)據(jù)段、重傳數(shù)據(jù)包、發(fā)送PZW數(shù)據(jù)包之外,還必須處理接收到的確認(rèn)和重復(fù)確認(rèn),根據(jù)RFC5681中的定義,當(dāng)同時滿足如下條件,一個確認(rèn)就被認(rèn)為是一個重復(fù)確認(rèn)[7]:
⑴ 該確認(rèn)的接收者有發(fā)出但未確認(rèn)的數(shù)據(jù);
⑵ 該確認(rèn)不攜帶有數(shù)據(jù);
⑶ 首部syn和fin標(biāo)志都為0;
⑷ 確認(rèn)序號等于MAX_RECV_ACK;
⑸ 首部的rwnd值與上一個確認(rèn)的rwnd值相同。
對于接收方而言,并沒有重復(fù)確認(rèn)這個概念,其所發(fā)送的所有確認(rèn)都是遵循相同的方法創(chuàng)建的,是否重復(fù)確認(rèn)由接收方進(jìn)行判斷。
4.2 發(fā)送過程
從圖5可以看到,如果不滿足發(fā)送條件,發(fā)送進(jìn)程將進(jìn)入等待狀態(tài),在滿足等待發(fā)送隊列不為空或發(fā)送緩沖區(qū)不為空且RWND>0這兩個條件之一,發(fā)送進(jìn)程才被喚醒。
當(dāng)接收到一個確認(rèn)后,首先檢查該確認(rèn)是否攜帶SACK信息,如果有就對未確認(rèn)隊列進(jìn)行掃描,將那些被確認(rèn)的數(shù)據(jù)包打上被確認(rèn)(SACKed)標(biāo)志,避免被重傳,接著從未確認(rèn)隊列中刪除序號小于確認(rèn)的ack字段的數(shù)據(jù)包,因為這些被刪除的數(shù)據(jù)包已經(jīng)確定被接收方接收到了。
4.3 擁塞控制
擁塞控制在RFC5681中定義,是發(fā)送方的一項重要功能,由慢啟動、擁塞避免、快速重傳和快速恢復(fù)功能組成。有兩個用于擁塞控制的變量:
⑴ CWND:發(fā)送方在接收到一個響應(yīng)之前可以發(fā)送到網(wǎng)絡(luò)的數(shù)據(jù)的最大字節(jié)數(shù)。根據(jù)RFC5681的定義CWND的初始值IW如下。
如果SMSS>2190字節(jié):
IW=2×SMSS。
如果SMSS>1095字節(jié)并且SMSS<=2190字節(jié):
IW=3×SMSS字節(jié)。
如果SMSS<=1095字節(jié):
IW=4×SMSS字節(jié)。
⑵ SSTHRESH:一個用于判斷是使用慢啟動算法還是擁塞避免算法的閥值,當(dāng)CWND
開始發(fā)送數(shù)據(jù)的時候由于不了解網(wǎng)絡(luò)的擁塞狀況,應(yīng)該以較慢的速度將數(shù)據(jù)包發(fā)送到網(wǎng)絡(luò)中,以避免大量的突發(fā)數(shù)據(jù)包對網(wǎng)絡(luò)造成擁塞,這就是慢啟動的目的。
擁塞避免是為了在發(fā)現(xiàn)網(wǎng)絡(luò)出現(xiàn)擁塞狀況的時候,降低數(shù)據(jù)包進(jìn)入網(wǎng)絡(luò)的速率。
快速重傳指的是連續(xù)接到三個重復(fù)確認(rèn)就立刻重傳序號與該確認(rèn)的ack字段的值相同的數(shù)據(jù)包,而不用等到重傳定時器超時。在發(fā)生了快速重傳后,就進(jìn)入了快速恢復(fù)的過程而不是重新使用慢啟動算法發(fā)送數(shù)據(jù)包??焖倩謴?fù)的CWND初始值更大,可以允許更多的數(shù)據(jù)包進(jìn)入網(wǎng)絡(luò)。
假設(shè)N是某個確認(rèn)數(shù)據(jù)包確認(rèn)的字節(jié)數(shù),D是接收到的重復(fù)確認(rèn)的個數(shù),接收到確認(rèn)時擁塞控制的工作流程如圖6所示。
CWND=SSTHRESH? ? ? ? ? ? ? ?⑵
CWND=CWND+min(N,SMSS)? ? ? ⑶
CWND=CWND+max(1,SMSS×SMSS/CWND) ⑷
CWND=CWND+SMSS? ? ? ? ? ? ? ? ⑸
SSTHRESH=max(FLIGHT_SIZE/2,2×SMSS) ⑹
CWND=SSTHRESH+3×SMSS ⑺
另外,如果在重傳定時器超時的時候重傳了數(shù)據(jù)包,就要執(zhí)行式⑹和式⑻。
CWND=SMSS? ?⑻
超時重傳之后的發(fā)送過程從慢啟動算法開始執(zhí)行。
4.4 重傳定時器
定時重傳是一個更重要的重傳機制,快速重傳只能根據(jù)接收方的提示逐個重傳丟失的數(shù)據(jù)包,而在重傳定時器中結(jié)合SACK機制,一次可以重傳一批數(shù)據(jù)包,另外PZW數(shù)據(jù)包也是在重傳定時器中發(fā)送的。
重傳定時器的重傳超時時間(Retransmission TimeOut,下稱RTO)使用RFC1323和RFC6298定義的機制進(jìn)行計算,每接收到一個確認(rèn)了新數(shù)據(jù)的確認(rèn)數(shù)據(jù)包都會重新計算一次RTO,同時也會重置一次定時器。
4.4.1 RTO的計算
RUTP采用RFC1323定義的RTT測量方法,為此定義了一個系統(tǒng)變量TS_RECENT, 它的值出現(xiàn)在每個發(fā)送出去的數(shù)據(jù)包首部的Tsecr字段中。
假設(shè)接收到的數(shù)據(jù)包序號為SEQ,攜帶的數(shù)據(jù)字節(jié)數(shù)為L,如果SEQ<=LAST_SEND_ACK 在接收到一個確認(rèn)了數(shù)據(jù)的確認(rèn)數(shù)據(jù)包后,將當(dāng)前時間減去其首部的Tsecr字段值,就可以得到往返時間(round-trip time,下稱RTT),然后根據(jù)RFC6298中定義的方法就可以計算出RTO。 4.4.2 工作流程 圖7顯示了重傳定時器的工作流程。 根據(jù)RFC2018中的定義,在圖7中被重傳的數(shù)據(jù)包指的是所有沒有設(shè)置SACKed標(biāo)志且序號小于設(shè)置了SACKed標(biāo)志的數(shù)據(jù)包的最大序號。 5 結(jié)束語 RUTP協(xié)議可以用于點對點傳輸數(shù)據(jù),也可以用于客戶端/服務(wù)器結(jié)構(gòu)的應(yīng)用之間傳輸數(shù)據(jù)。RUTP協(xié)議目前主要關(guān)注的是可靠性、易用性和通用性,應(yīng)用場景接近于TCP,但是要求能夠應(yīng)用于某些TCP不適用的場合。經(jīng)過測試,所有傳輸?shù)臄?shù)據(jù)都能正確到達(dá)目的地,沒有出現(xiàn)過傳輸錯誤的情況。在易用性方面,RUTP為應(yīng)用程序提供了與標(biāo)準(zhǔn)套接字類似的API接口,熟悉套接字編程的程序員可以輕松掌握RUTP協(xié)議的使用方法。從應(yīng)用情況來看,RUTP協(xié)議在各方面都能滿足當(dāng)前需求。 參考文獻(xiàn)(References): [1] 福羅贊著.王海譯.TCP/IP協(xié)議族(第4版)[M].清華大學(xué)出版社,2011. [2] Information Sciences Institute University of SouthernCalifornia.RFC793 transmission control protocol[S/OL].(1981-9)[2013-5].http://tools.ietf.org/html/rfc0793.html [3] S.Floyd,A.Romanow, M.Mathis,J.Mahdavi.RFC2018 TCPSelective Acknowledgment Options [S/OL].(1996-10)[2013-5].http://tools.ietf.org/html/rfc2018 [4] Internet Engineering Task Force R. Braden.RFC1122Requirements for Internet Hosts-Communication Layers [S/OL].(1989-10)[2013-5].http://tools.ietf.org/html/rfc1122 [5] V.Jacobson,R.Braden.RFC1323 TCP Extensions for?High-Performance[S/OL].(1989-10)[2013-5].http://www.ietf.org/rfc/rfc1323.txt [6] V.Paxson,M.Allman.RFC6298 Computing TCP's Retrans-mission Timer [S/OL]. (2000-9)[2013-5].http://tools.ietf.org/html/rfc6298 [7] M.Allman,V.Paxson,E.Blanton.RFC5681 TCP CongestionControl [S/OL].(2009-9)[2013-5].http://tools.ietf.org/html/rfc5681