龍恒
摘? 要: 用戶(hù)數(shù)據(jù)報(bào)協(xié)議(UDP)是一種無(wú)連接傳輸層協(xié)議,提供的是一種不可靠的數(shù)據(jù)傳輸服務(wù),不能保證將數(shù)據(jù)按順序、完整地傳送到目的地。本文引入了一些TCP的機(jī)制并進(jìn)行了部分調(diào)整,在應(yīng)用層上基于UDP實(shí)現(xiàn)了一個(gè)具有擁塞控制、重傳等機(jī)制的新的數(shù)據(jù)傳輸協(xié)議。測(cè)試結(jié)果表明使用該協(xié)議傳輸?shù)乃袛?shù)據(jù)都能正確地到達(dá)目的地,成功解決了可靠性問(wèn)題,同時(shí)其他方面都能滿(mǎn)足設(shè)計(jì)要求。
關(guān)鍵詞: UDP; 可靠性; 重傳; 擁塞控制; 流量控制
中圖分類(lèi)號(hào):TP311? ? ? ? ? 文獻(xiàn)標(biāo)識(shí)碼:A? ? ?文章編號(hào):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é)議,但是傳輸過(guò)程中容易出現(xiàn)數(shù)據(jù)包的丟失或失序等問(wèn)題。而TCP協(xié)議則供了一套完善的保證可靠性的機(jī)制,可以保證將數(shù)據(jù)按順序完整地發(fā)送到目的地。本文在UDP的基礎(chǔ)上,引入了一些TCP的概念,在應(yīng)用層上實(shí)現(xiàn)了一個(gè)可靠的數(shù)據(jù)傳輸協(xié)議,稱(chēng)為RUTP(Reliable Udp Transmission Protocol)。RUTP實(shí)現(xiàn)了接收方流量控制、擁塞控制、重傳和往返時(shí)間測(cè)量這些保證傳輸可靠性的基本機(jī)制[1],并且實(shí)現(xiàn)了SACK、Timestamp和Window Scale這三個(gè)對(duì)提高性能有幫助的功能。
1 協(xié)議首部
RUTP使用一個(gè)20字節(jié)的首部,結(jié)構(gòu)如圖1所示,各個(gè)字段的含義如表1所示。
其中確認(rèn)序號(hào)(acknowledgment)是一個(gè)32位的無(wú)符號(hào)整數(shù)。與RFC793中定義的acknowledgment number作用相同,是對(duì)接收到的字節(jié)數(shù)的確認(rèn),取值為被確認(rèn)的數(shù)據(jù)包的序號(hào)(sequence)加上該數(shù)據(jù)包所攜帶的數(shù)據(jù)字節(jié)數(shù),也就是下一個(gè)期望接收的字節(jié)的序號(hào)[2]。
另外還有一些只在特定數(shù)據(jù)包中才會(huì)出現(xiàn)的字段,稱(chēng)為選項(xiàng)字段,其緊跟在RUTP固定首部字段之后。其中與保證可靠性有關(guān)的有兩個(gè):SACK和PZW。SACK是選擇性確認(rèn)字段,其功能與RFC2018中描述的相同[3],但是組織方式有所不同;PZW選項(xiàng)實(shí)現(xiàn)的是RFC1122的Probing Zero Windows[4]功能。在一個(gè)數(shù)據(jù)包中,RUTP首部出現(xiàn)在UDP首部之后。
2 系統(tǒng)變量
RUTP定義了一系列的系統(tǒng)變量,為了更好地講明問(wèn)題,把本文中用到的變量做一個(gè)簡(jiǎn)單的說(shuō)明:
RMSS:接收方能接收的最大報(bào)文段。
SMSS:發(fā)送方能發(fā)送的最大報(bào)文段。
MAX_RECV_SEQ:接收到的數(shù)據(jù)包的最大序號(hào)。
MAX_RECV_ACK:接收到的數(shù)據(jù)包的最大確認(rèn)序號(hào)。
LAST_SEND_SEQ:最后發(fā)送出去的序號(hào),為最近一次發(fā)送出去的攜帶數(shù)據(jù)的數(shù)據(jù)包的序號(hào)加上其數(shù)據(jù)字節(jié)數(shù)。
LAST_SEND_ACK:最后發(fā)送出去的確認(rèn)序號(hào),為最近一次接收到的數(shù)據(jù)包的序號(hào)加上所包含的數(shù)據(jù)字節(jié)數(shù)。
TS_RECENT:記錄接收到的帶有數(shù)據(jù)的有效數(shù)據(jù)包的時(shí)間,當(dāng)該數(shù)據(jù)包的序號(hào)小于等于LAST_
SEND_ACK的時(shí)候更新TS_RECENT的值。
FLIGHT_SIZE:當(dāng)前發(fā)送出去但是還沒(méi)有被接收方確認(rèn)的數(shù)據(jù)的字節(jié)數(shù)。
3 數(shù)據(jù)的接收
RUTP是一種全雙工協(xié)議,通訊的雙方可以同時(shí)接收和發(fā)送數(shù)據(jù)。其中接收流程如圖2所示。
3.1 滑動(dòng)窗口
接收方使用一個(gè)稱(chēng)為“滑動(dòng)窗口”的機(jī)制進(jìn)行流量控制,這是對(duì)接收方的接收緩沖區(qū)使用狀況的一個(gè)形象的描述,也是判斷數(shù)據(jù)包是否合法的重要依據(jù)之一,圖3顯示了一個(gè)滑動(dòng)窗口在某個(gè)時(shí)間點(diǎn)的狀態(tài)。
用于描述滑動(dòng)窗口的重要變量有:窗口大小的最大值(swMax),窗口左邊緣(swLeft)、當(dāng)前窗口大?。╯wSize)、窗口的右邊緣(swRight),需要注意的是swLeft與swSize相加并不總是等于swRight,因?yàn)槿绻霈F(xiàn)丟失/失序的情況,滑動(dòng)窗口的左邊緣將會(huì)停留在接收到的序號(hào)連續(xù)的數(shù)據(jù)的最右的位置,在這種情況下接收到的序號(hào)更大的合法數(shù)據(jù)包,將會(huì)被保存起來(lái)等待丟失/失序的數(shù)據(jù)包到達(dá)后再提交給應(yīng)用程序,數(shù)據(jù)保存后,swSize的值將減小。
3.2 數(shù)據(jù)包分類(lèi)
依據(jù)接收到的數(shù)據(jù)包的序號(hào)、TSval值、MAX_RECV_SEQ系統(tǒng)變量、MAX_RECV_ACK系統(tǒng)變量和滑動(dòng)窗口的狀態(tài)將它們進(jìn)行分類(lèi)。
3.2.1 非法數(shù)據(jù)包
假設(shè)數(shù)據(jù)包的序號(hào)為SEQ,攜帶的數(shù)據(jù)的字節(jié)數(shù)為L(zhǎng),符合以下條件之一的數(shù)據(jù)包被認(rèn)為是非法數(shù)據(jù)包:
⑴ 首部ack標(biāo)志為1,并且符合下列條件之一。
① 攜帶有數(shù)據(jù);
② 確認(rèn)序號(hào)小于MAX_RECV_ACK;
③ 序號(hào)不處于swLeft-swMax與swLeft+swMax之間。
⑵ 首部的TSval值小于TS_RECENT。這是RFC1323中的PAWS(Protect Against Wrapped Sequence Numbers)[5]要求。
⑶ 序號(hào)處于滑動(dòng)窗口之外,也就是SEQ
3.2.2 失序數(shù)據(jù)包
指的是攜帶有數(shù)據(jù),但是不按順序到達(dá)接收方的數(shù)據(jù)包。這可能是由于延遲、丟失后被重傳等原因造成的。其特點(diǎn)是序號(hào)不等于swLeft。
3.2.3 重復(fù)數(shù)據(jù)包
指的是合法的攜帶有數(shù)據(jù),但是前面已經(jīng)成功接收過(guò)的數(shù)據(jù)包,其特點(diǎn)是序號(hào)大于等于swLeft-swMax并且序號(hào)加上L小于swLeft。重復(fù)數(shù)據(jù)包的作用是為了在接收到后立刻發(fā)送一個(gè)確認(rèn),這與重傳的算法有關(guān)。
3.2.4 PZW數(shù)據(jù)包
這種數(shù)據(jù)包與在RFC1122中定義的Probing Zero Windows數(shù)據(jù)包類(lèi)似,但是實(shí)現(xiàn)有所不同,在RUTP中PZW數(shù)據(jù)包指的是首部的ack和opt標(biāo)志都為1,且在首部指定了PZW選項(xiàng)的數(shù)據(jù)包。
3.2.5 數(shù)據(jù)段
指的是除了上面各種類(lèi)型之外、攜帶有數(shù)據(jù)并且按順序到達(dá)的合法數(shù)據(jù)包。
3.3 數(shù)據(jù)的保存
RUTP協(xié)議使用一個(gè)接收隊(duì)列和一個(gè)失序鏈表來(lái)保存接收到的數(shù)據(jù)。接收隊(duì)列用于保存接收到的數(shù)據(jù)包,每個(gè)接收到的數(shù)據(jù)包的序號(hào)通過(guò)了合法性檢驗(yàn)后就會(huì)被放入接收隊(duì)列中,這些數(shù)據(jù)包按序號(hào)的從小到大從隊(duì)列的首部開(kāi)始向后排列。
失序鏈表與接收隊(duì)列一起工作,它的表項(xiàng)指向接收隊(duì)列的失序位置的下一項(xiàng),與swLeft一起可以標(biāo)識(shí)出所有的失序情況。
圖4顯示了swLeft、接收隊(duì)列和失序表在某一時(shí)刻的狀態(tài)。
為了支持發(fā)送重復(fù)確認(rèn),失序鏈表的每個(gè)表項(xiàng)還會(huì)保存其創(chuàng)建時(shí)滑動(dòng)窗口的大小。在發(fā)送確認(rèn)時(shí),如果出現(xiàn)失序的情況就使用第一個(gè)表項(xiàng)的滑動(dòng)窗口的值作為其首部的rwnd字段的值,這樣對(duì)于發(fā)送方就能符合重復(fù)確認(rèn)的rwnd值相同的要求。
上述設(shè)計(jì)方式對(duì)生成選擇性確認(rèn)(SACK)信息也有幫助,RUTP的SACK功能與RFC2018中定義的功能相同,但是實(shí)現(xiàn)方式有所不同,RUTP中SACK塊是按順序從小到大在首部選項(xiàng)中排序的,而且RUTP的選項(xiàng)沒(méi)有TCP的最長(zhǎng)40字節(jié)的限制。在生成SACK選項(xiàng)的時(shí)候只需遍歷一次失序鏈表即可。
3.4 確認(rèn)的發(fā)送
確認(rèn)指的是接收方發(fā)送的、對(duì)本方已經(jīng)接收到的數(shù)據(jù)的情況起告知作用的數(shù)據(jù)包,RUTP的確認(rèn)數(shù)據(jù)包將首部的ack標(biāo)志設(shè)置為1。RUTP協(xié)議在如下幾種情況下會(huì)發(fā)送確認(rèn):
⑴ 接收到失序數(shù)據(jù)包、重復(fù)數(shù)據(jù)包或PZW數(shù)據(jù)包都會(huì)立刻發(fā)送一個(gè)確認(rèn);
⑵ 連續(xù)接收到的未確認(rèn)字節(jié)數(shù)大于等于2×RMSS并且滿(mǎn)足式⑴的要求:
swSize>=min(0.5×swMax,RMSS) ⑴
式⑴是為了防止出現(xiàn)RFC1122中定義的糊涂窗口綜合癥(SWS)。
⑶ 確認(rèn)定時(shí)器超時(shí),確認(rèn)定時(shí)器實(shí)現(xiàn)的是RFC1122中定義的delayed ACK功能,RFC6298要求延遲的時(shí)間必須少于500毫秒[6],超時(shí)的時(shí)候如果未確認(rèn)字節(jié)數(shù)計(jì)數(shù)器大于0,就會(huì)發(fā)送一個(gè)確認(rèn),并且將計(jì)數(shù)器設(shè)置為0,確認(rèn)定時(shí)器只確認(rèn)以前沒(méi)有確認(rèn)過(guò)的數(shù)據(jù)。創(chuàng)建確認(rèn)時(shí),其首部各字段的取值如下:
rwnd:如果失序表不為空,就使用第一個(gè)表項(xiàng)記錄的滑動(dòng)窗口值,否則rwnd字段值使用swSize。
acknowledgment:滑動(dòng)窗口左邊緣swLeft;
sequence:LAST_SEND_SEQ系統(tǒng)變量的值;
TSval:當(dāng)前時(shí)間值;
TSecr:TS_RECENT系統(tǒng)變量的值。
RUTP不會(huì)重傳已丟失了的確認(rèn),要等到接收到發(fā)送方發(fā)送的數(shù)據(jù)包才會(huì)繼續(xù)發(fā)送確認(rèn)。
4 數(shù)據(jù)的發(fā)送
圖5顯示了數(shù)據(jù)的發(fā)送流程。
4.1 數(shù)據(jù)包類(lèi)型
在一個(gè)功能完整的發(fā)送方,除了可以發(fā)送數(shù)據(jù)段、重傳數(shù)據(jù)包、發(fā)送PZW數(shù)據(jù)包之外,還必須處理接收到的確認(rèn)和重復(fù)確認(rèn),根據(jù)RFC5681中的定義,當(dāng)同時(shí)滿(mǎn)足如下條件,一個(gè)確認(rèn)就被認(rèn)為是一個(gè)重復(fù)確認(rèn)[7]:
⑴ 該確認(rèn)的接收者有發(fā)出但未確認(rèn)的數(shù)據(jù);
⑵ 該確認(rèn)不攜帶有數(shù)據(jù);
⑶ 首部syn和fin標(biāo)志都為0;
⑷ 確認(rèn)序號(hào)等于MAX_RECV_ACK;
⑸ 首部的rwnd值與上一個(gè)確認(rèn)的rwnd值相同。
對(duì)于接收方而言,并沒(méi)有重復(fù)確認(rèn)這個(gè)概念,其所發(fā)送的所有確認(rèn)都是遵循相同的方法創(chuàng)建的,是否重復(fù)確認(rèn)由接收方進(jìn)行判斷。
4.2 發(fā)送過(guò)程
從圖5可以看到,如果不滿(mǎn)足發(fā)送條件,發(fā)送進(jìn)程將進(jìn)入等待狀態(tài),在滿(mǎn)足等待發(fā)送隊(duì)列不為空或發(fā)送緩沖區(qū)不為空且RWND>0這兩個(gè)條件之一,發(fā)送進(jìn)程才被喚醒。
當(dāng)接收到一個(gè)確認(rèn)后,首先檢查該確認(rèn)是否攜帶SACK信息,如果有就對(duì)未確認(rèn)隊(duì)列進(jìn)行掃描,將那些被確認(rèn)的數(shù)據(jù)包打上被確認(rèn)(SACKed)標(biāo)志,避免被重傳,接著從未確認(rèn)隊(duì)列中刪除序號(hào)小于確認(rèn)的ack字段的數(shù)據(jù)包,因?yàn)檫@些被刪除的數(shù)據(jù)包已經(jīng)確定被接收方接收到了。
4.3 擁塞控制
擁塞控制在RFC5681中定義,是發(fā)送方的一項(xiàng)重要功能,由慢啟動(dòng)、擁塞避免、快速重傳和快速恢復(fù)功能組成。有兩個(gè)用于擁塞控制的變量:
⑴ CWND:發(fā)送方在接收到一個(gè)響應(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:一個(gè)用于判斷是使用慢啟動(dòng)算法還是擁塞避免算法的閥值,當(dāng)CWND
開(kāi)始發(fā)送數(shù)據(jù)的時(shí)候由于不了解網(wǎng)絡(luò)的擁塞狀況,應(yīng)該以較慢的速度將數(shù)據(jù)包發(fā)送到網(wǎng)絡(luò)中,以避免大量的突發(fā)數(shù)據(jù)包對(duì)網(wǎng)絡(luò)造成擁塞,這就是慢啟動(dòng)的目的。
擁塞避免是為了在發(fā)現(xiàn)網(wǎng)絡(luò)出現(xiàn)擁塞狀況的時(shí)候,降低數(shù)據(jù)包進(jìn)入網(wǎng)絡(luò)的速率。
快速重傳指的是連續(xù)接到三個(gè)重復(fù)確認(rèn)就立刻重傳序號(hào)與該確認(rèn)的ack字段的值相同的數(shù)據(jù)包,而不用等到重傳定時(shí)器超時(shí)。在發(fā)生了快速重傳后,就進(jìn)入了快速恢復(fù)的過(guò)程而不是重新使用慢啟動(dòng)算法發(fā)送數(shù)據(jù)包??焖倩謴?fù)的CWND初始值更大,可以允許更多的數(shù)據(jù)包進(jìn)入網(wǎng)絡(luò)。
假設(shè)N是某個(gè)確認(rèn)數(shù)據(jù)包確認(rèn)的字節(jié)數(shù),D是接收到的重復(fù)確認(rèn)的個(gè)數(shù),接收到確認(rèn)時(shí)擁塞控制的工作流程如圖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í)器超時(shí)的時(shí)候重傳了數(shù)據(jù)包,就要執(zhí)行式⑹和式⑻。
CWND=SMSS? ?⑻
超時(shí)重傳之后的發(fā)送過(guò)程從慢啟動(dòng)算法開(kāi)始執(zhí)行。
4.4 重傳定時(shí)器
定時(shí)重傳是一個(gè)更重要的重傳機(jī)制,快速重傳只能根據(jù)接收方的提示逐個(gè)重傳丟失的數(shù)據(jù)包,而在重傳定時(shí)器中結(jié)合SACK機(jī)制,一次可以重傳一批數(shù)據(jù)包,另外PZW數(shù)據(jù)包也是在重傳定時(shí)器中發(fā)送的。
重傳定時(shí)器的重傳超時(shí)時(shí)間(Retransmission TimeOut,下稱(chēng)RTO)使用RFC1323和RFC6298定義的機(jī)制進(jìn)行計(jì)算,每接收到一個(gè)確認(rèn)了新數(shù)據(jù)的確認(rèn)數(shù)據(jù)包都會(huì)重新計(jì)算一次RTO,同時(shí)也會(huì)重置一次定時(shí)器。
4.4.1 RTO的計(jì)算
RUTP采用RFC1323定義的RTT測(cè)量方法,為此定義了一個(gè)系統(tǒng)變量TS_RECENT, 它的值出現(xiàn)在每個(gè)發(fā)送出去的數(shù)據(jù)包首部的Tsecr字段中。
假設(shè)接收到的數(shù)據(jù)包序號(hào)為SEQ,攜帶的數(shù)據(jù)字節(jié)數(shù)為L(zhǎng),如果SEQ<=LAST_SEND_ACK 在接收到一個(gè)確認(rèn)了數(shù)據(jù)的確認(rèn)數(shù)據(jù)包后,將當(dāng)前時(shí)間減去其首部的Tsecr字段值,就可以得到往返時(shí)間(round-trip time,下稱(chēng)RTT),然后根據(jù)RFC6298中定義的方法就可以計(jì)算出RTO。 4.4.2 工作流程 圖7顯示了重傳定時(shí)器的工作流程。 根據(jù)RFC2018中的定義,在圖7中被重傳的數(shù)據(jù)包指的是所有沒(méi)有設(shè)置SACKed標(biāo)志且序號(hào)小于設(shè)置了SACKed標(biāo)志的數(shù)據(jù)包的最大序號(hào)。 5 結(jié)束語(yǔ) RUTP協(xié)議可以用于點(diǎn)對(duì)點(diǎn)傳輸數(shù)據(jù),也可以用于客戶(hù)端/服務(wù)器結(jié)構(gòu)的應(yīng)用之間傳輸數(shù)據(jù)。RUTP協(xié)議目前主要關(guān)注的是可靠性、易用性和通用性,應(yīng)用場(chǎng)景接近于TCP,但是要求能夠應(yīng)用于某些TCP不適用的場(chǎng)合。經(jīng)過(guò)測(cè)試,所有傳輸?shù)臄?shù)據(jù)都能正確到達(dá)目的地,沒(méi)有出現(xiàn)過(guò)傳輸錯(cuò)誤的情況。在易用性方面,RUTP為應(yīng)用程序提供了與標(biāo)準(zhǔn)套接字類(lèi)似的API接口,熟悉套接字編程的程序員可以輕松掌握RUTP協(xié)議的使用方法。從應(yīng)用情況來(lái)看,RUTP協(xié)議在各方面都能滿(mǎn)足當(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