• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            大龍的博客

            常用鏈接

            統(tǒng)計(jì)

            最新評(píng)論

            (TCP-over-UDP library):基于UDP協(xié)議之上實(shí)現(xiàn)通用、可靠、高效的TCP協(xié)議 ---------- 轉(zhuǎn)

            隨著互聯(lián)網(wǎng)應(yīng)用廣泛推廣,出現(xiàn)了越來越多的網(wǎng)絡(luò)應(yīng)用,其中基于p2p思想的各種網(wǎng)絡(luò)技術(shù)的產(chǎn)品也越來越多的出現(xiàn)在我們的視野當(dāng)中。從最早聞名的Napster到現(xiàn)在的Bittorrent、eMule、skype等產(chǎn)品,P2P這種網(wǎng)絡(luò)應(yīng)用模式已經(jīng)從各個(gè)方面深入人心。這些產(chǎn)品在各自的網(wǎng)絡(luò)實(shí)現(xiàn)技術(shù)上,都以各自的方法解決著同樣面臨的一個(gè)問題,如何讓他們的軟件產(chǎn)品在各異的網(wǎng)絡(luò)拓?fù)浣Y(jié)構(gòu)中順利的進(jìn)行P2P通信。
             眾所周知,在當(dāng)今的網(wǎng)絡(luò)拓?fù)浣Y(jié)構(gòu)中,普遍存在使用NAT設(shè)備來進(jìn)行網(wǎng)絡(luò)地址轉(zhuǎn)換,而讓應(yīng)用程序能跨越這些NAT設(shè)備進(jìn)行全雙工的通信,就成為非常重要的一個(gè)問題。對(duì)于實(shí)現(xiàn)跨越NAT通信可以采取很多種辦法(對(duì)于能夠直接連接、反向連接的情況不在此列):首先是通過服務(wù)器進(jìn)行轉(zhuǎn)發(fā),這是比較粗暴的方法,而且在用戶量大的時(shí)候,轉(zhuǎn)發(fā)服務(wù)器需要付出相當(dāng)大的代價(jià);第二,可以使用NAT穿透技術(shù)。而大家知道關(guān)于NAT穿透中,UDP穿透的成功率比起TCP穿透要高出許多,這一點(diǎn)這里將不做多述,可以參考Bryan Ford的文章《Peer-to-Peer Communication Across Network Address Translators》(http://www.brynosaurus.com/pub/net/p2pnat/)。因此在UDP協(xié)議上構(gòu)建一些大型的網(wǎng)絡(luò)應(yīng)用程序可能會(huì)成為很多人的需求。
             當(dāng)然也可能基于更多的原因,會(huì)有很多人希望能在UDP協(xié)議上進(jìn)行大型應(yīng)用程序的構(gòu)建。然而UDP協(xié)議本身存在著不通信不可靠的缺點(diǎn),于是對(duì)于基于UDP進(jìn)行可靠通信的需求就浮現(xiàn)出來了。目前在網(wǎng)絡(luò)上有許多人正做著這一工作,UDT、RakNet、eNet等都是構(gòu)建在UDP之后網(wǎng)絡(luò)可靠通信開發(fā)庫。然后這些庫開發(fā)時(shí)都針對(duì)了一些特殊應(yīng)用來進(jìn)行設(shè)計(jì)的,不具備通用性。比如RakNet是為游戲應(yīng)用而設(shè)計(jì),對(duì)于實(shí)時(shí)性等游戲相關(guān)的網(wǎng)絡(luò)需求有很好的支持,對(duì)于大批量數(shù)據(jù)傳輸卻有點(diǎn)力所不及。而UDT基于一種基于帶寬速率控制的擁塞控制算法進(jìn)行設(shè)計(jì)(http://udt.sourceforge.net/doc/draft-gg-udt-01.txt),主要用在小數(shù)量的bulk源共享富裕帶寬的情況下,最典型的例子就是建立在光纖廣域網(wǎng)上的網(wǎng)格計(jì)算,而在ISP提供帶寬有限的情況下運(yùn)行卻顯得消耗資源并性能不足。甚至可能被防火墻,或ISP服務(wù)商判斷為惡意帶寬使用攻擊。這些都使用得他們不能被廣泛地用于各種網(wǎng)絡(luò)應(yīng)用程序。另外大家也陸續(xù)發(fā)現(xiàn)目前的UDT實(shí)現(xiàn)版本存在的一些問題。比如UDT做服務(wù)端接收連接時(shí),總是新開一個(gè)端口與客戶端進(jìn)行連接,這樣會(huì)帶來幾個(gè)問題:1)較多客戶端連接上來時(shí),服務(wù)端新打開的眾多端口中可能有的端口會(huì)被防火墻攔截而導(dǎo)致通信失敗,2)如果客戶端處于Symmetric NAT和Port-Restricted Cone NAT后面時(shí),將導(dǎo)致服務(wù)器端與客戶端連接無法成功建立,3)由于udp端口數(shù)最大值有限,所以UDT服務(wù)器端可接收的連接數(shù)也因些受限。再有就是不僅僅是UDT庫,基本上所有的UDP-based可靠通信庫,都未提供穿越proxy代理的功能(socks5);再有就是對(duì)UDP打洞技術(shù)有的支持得不完善或并不支持。
             基于這些原因,使得我需要開發(fā)一個(gè)基于UDP協(xié)議之上實(shí)現(xiàn)一個(gè)可靠、高效、通用的通信庫,來滿足我目前所開發(fā)的項(xiàng)目的需要。TCP協(xié)議算法已經(jīng)是經(jīng)過多方面及多年的驗(yàn)證,是最具通用性,且可靠高效的。雖然UDT等各種庫指出TCP在這樣或那樣的網(wǎng)絡(luò)環(huán)境下存在不足,但眾多實(shí)現(xiàn)當(dāng)中他仍然是最通用、可靠、高效的。相信有許多人跟我一樣,需要這么一個(gè)開發(fā)庫,所以我打算在開發(fā)過程中,陸續(xù)公開相關(guān)的文檔及這個(gè)開發(fā)庫。
             
            二、設(shè)計(jì)目標(biāo)
             
             TDP主要的目標(biāo)就是在UDP層之上實(shí)現(xiàn)TCP的協(xié)議算法,使得應(yīng)用程序能夠在UDP層之上獲得通用、可靠、高效的通信能力。
             TDP網(wǎng)絡(luò)開發(fā)庫所實(shí)現(xiàn)的算法,都來自久經(jīng)考驗(yàn)的TCP協(xié)議算法,網(wǎng)上有著非常多的參考資料。在實(shí)現(xiàn)當(dāng)中,參考最多的是Richard Stevens的《TCP/IP詳解》。
             TDP提供的用于開發(fā)的應(yīng)用程序接口與Socket API非常相像,姑且稱之為TDP Socket API,基本上的函數(shù)名與參數(shù)等都與Socket API相一致,但是TDP Socket API的API接口都位于命名空間TDP當(dāng)中。只要使用過Socket API進(jìn)行開發(fā)過的朋友,將都會(huì)使用TDP庫進(jìn)行開發(fā)。下圖為TDP及TDP Socket API所處在的協(xié)議棧應(yīng)用中的位置,以及與TCP協(xié)議棧應(yīng)用的對(duì)比。
             
             
            三、協(xié)議說明
             
             1.協(xié)議格式
             
             TDP的實(shí)現(xiàn)的算法雖然與TCP實(shí)現(xiàn)的算法是大致相同的,但TDP的協(xié)議格式只是從TCP協(xié)議格式獲得參考,但并不完全與他相同。TDP的協(xié)議格式如下:
             
             
             
             接下來介紹一下協(xié)議格式的各個(gè)字段含義。
             4位首部長(zhǎng)度:表示用戶數(shù)據(jù)在數(shù)據(jù)包中的起始位置。
             LIV:連接保活標(biāo)志,用于表示TDP連接通路存活狀態(tài)。
             ACK:確認(rèn)序號(hào)有效。
             PSH:接收方應(yīng)該盡快將這個(gè)報(bào)文段交給應(yīng)用層。
             RST:重建連接。
             SYN:同步序號(hào)用來發(fā)起一個(gè)連接。
             FIN:發(fā)端完成發(fā)送任務(wù)。
             16位窗口大小:接收端可接收數(shù)據(jù)的窗口大小。
             選項(xiàng):只有一個(gè)選項(xiàng)字段,為最長(zhǎng)報(bào)文大小,即MSS。TDP選項(xiàng)格式與TCP選項(xiàng)格式一致,kind=0時(shí)表示選項(xiàng)結(jié)束,kind=1時(shí)表示無操作,kind=2時(shí)表示最大報(bào)文段長(zhǎng)度。如下圖:
             
             
             
             數(shù)據(jù):用戶通過TDP傳輸?shù)臄?shù)據(jù)。
             
             2.TDP連接建立與終止
             
             TDP的連接建立與終止可以參考TCP的狀態(tài)變遷圖(此圖的詳細(xì)解釋請(qǐng)參考《TCP/IP詳解 卷一》第18章),如下:
             
             
             2.1連接建立
             
             2.1.1三次握手
             連接建立分要經(jīng)過三次握手過程:1)客戶端發(fā)送一個(gè)SYN段到指明客戶打算連接的服務(wù)器的端口,報(bào)文段中要設(shè)置客戶端初始序號(hào)。2)服務(wù)器發(fā)回包含服務(wù)器的初始序號(hào)的SYN報(bào)文段作為應(yīng)答。同時(shí),將確認(rèn)序號(hào)設(shè)置為客戶的初始序號(hào)加1,并設(shè)置ACK位標(biāo)志報(bào)文段為確認(rèn)報(bào)文段。3)客戶端必須將確認(rèn)序號(hào)設(shè)置為服務(wù)器初始序號(hào)加1,對(duì)服務(wù)器的SYN報(bào)文段進(jìn)行確認(rèn)。
             TDP在全局維護(hù)一個(gè)初始序號(hào)種子,這個(gè)初始序號(hào)為隨時(shí)產(chǎn)生的32位整數(shù)。
             連接建立的超時(shí)和重傳初始值為3秒,超時(shí)采用指數(shù)退避算法,3秒超時(shí)后超時(shí)值為6秒,然后是12秒,24秒……。連接建立最長(zhǎng)時(shí)間限制為75秒。
             
             2.1.2 NAT UDP PUNCH模式
             當(dāng)TDP工作模式是NAT UDP PUNCH時(shí),在三次握手之前,向?qū)Χ薔AT端口及預(yù)測(cè)端口間隔默認(rèn)2ms發(fā)送默認(rèn)為10個(gè)LIV報(bào)文段,一來用于打開自已的NAT端口,二來是用于進(jìn)入對(duì)端NAT端口。默認(rèn)值可以由用戶程序設(shè)置。這時(shí)的LIV報(bào)文段中初始序號(hào)及確認(rèn)序號(hào)都為0。
             當(dāng)接收到對(duì)端LIV報(bào)文段后,立即停止LIV報(bào)文段發(fā)送,發(fā)出SYN報(bào)文段進(jìn)行連接建立。這時(shí)有兩種可能:其一是另一端直到接收到該SYN報(bào)文段之前,都沒有接收到LIV報(bào)文段,或是剛接收到但沒有來得及發(fā)送SYN報(bào)文段,此時(shí)將會(huì)如上文描述的正常模式下連接建立的過程一致,將經(jīng)歷三次握手。基二是另一端在接收到該SYN報(bào)文段之前,也已經(jīng)發(fā)送出SYN報(bào)文段,此時(shí)雙方都需要對(duì)SYN報(bào)文段進(jìn)行確認(rèn),可以稱之為四次握手。

             2.1.3 最大傳輸報(bào)文大小(MSS)
             TCP報(bào)文段在連接建立時(shí)需要通報(bào)MSS,在TDP的實(shí)現(xiàn)中也進(jìn)行通報(bào),默認(rèn)通報(bào)為1460字節(jié)(符合以太網(wǎng)標(biāo)準(zhǔn),這個(gè)默認(rèn)值允許20字節(jié)的IP首部、8字節(jié)的UDP首部和12字節(jié)的TDP首部,以適合 1500字節(jié)的IP數(shù)據(jù)報(bào))默認(rèn)值可以由用戶程序設(shè)置。
             TCP在對(duì)端地址為非本地IP時(shí),默認(rèn)通報(bào)為536字節(jié)。TDP之所以默認(rèn)通報(bào)為1460,是因?yàn)門DP在數(shù)據(jù)傳輸過程中,實(shí)現(xiàn)了路徑MTU發(fā)現(xiàn)技術(shù),通過實(shí)際發(fā)現(xiàn)的MTU,進(jìn)行MSS的動(dòng)態(tài)調(diào)整,以盡量避免報(bào)文段在網(wǎng)絡(luò)中的傳輸產(chǎn)生分片的情況。路徑MTU發(fā)現(xiàn)技術(shù)在傳輸數(shù)據(jù)流一節(jié)中進(jìn)行描述。
             
             2.1.4 半打開連接及連接保活
             半打開連接是指對(duì)端異常關(guān)閉,如網(wǎng)線拔掉、突然斷電等情況將引發(fā)一端導(dǎo)演關(guān)閉,而另一端的連接卻仍然認(rèn)為連接處于打開當(dāng)中,這種情況稱之為半打開連接。TDP中的一個(gè)TDP SOCKET描述符由本地IP、本地端口、遠(yuǎn)端IP、遠(yuǎn)端端口唯一確定。當(dāng)遠(yuǎn)端客戶端連接請(qǐng)求到來時(shí),服務(wù)端將接收到一個(gè)新的TDP SOCKET描述符,當(dāng)這一個(gè)描述符唯一確定信息已經(jīng)存在時(shí),對(duì)新的連接請(qǐng)求發(fā)送RST報(bào)文段,通知其重置連接請(qǐng)求。對(duì)于舊的連接,由保活機(jī)制自動(dòng)發(fā)現(xiàn)是否為半打開連接,如果是半打開連接,則自動(dòng)關(guān)閉該連接。這里RST報(bào)文段與TCP中的RST報(bào)文段有些不一樣,TCP的RST報(bào)文段工作描述請(qǐng)參考《TCP/IP詳解 卷一》。
             連接建立之后,TDP連接需要啟動(dòng)保活機(jī)制。TCP連接在沒有數(shù)據(jù)通信的情況下也能保持連接,但TDP連接不行。TDP連接在一定時(shí)間段內(nèi)如果沒有數(shù)據(jù)交互的話,將主動(dòng)發(fā)送保活LIV報(bào)文段。這個(gè)時(shí)間段根據(jù)TDP連接工作模塊不同有所差異,在NAT UDP PUNCH模式下,這個(gè)時(shí)間段默認(rèn)值為1分鐘(大多數(shù)的NAT中,UDP會(huì)話超時(shí)時(shí)間為2-5分鐘左右);而在常規(guī)模塊下這個(gè)時(shí)間段默認(rèn)值為5分鐘。默認(rèn)值可以由用戶程序設(shè)置,用戶程序需要指明兩種模塊下的保活時(shí)間周期。這里TDP的保活機(jī)制與TCP中的保活機(jī)制完全不一樣,TCP的保活機(jī)制描述請(qǐng)參考《TCP/IP詳解 卷一》。
             
             2.2連接關(guān)閉
             
             TDP連接與TCP連接一樣是全雙工的,因此每個(gè)方向必須單獨(dú)地進(jìn)行關(guān)閉。客戶機(jī)給服務(wù)器一個(gè)FIN報(bào)文段,然后服務(wù)器返回給客戶端一個(gè)確認(rèn)ACK報(bào)文,并且發(fā)送一個(gè)FIN報(bào)文段,當(dāng)客戶機(jī)回復(fù)ACK報(bào)文后(四次握手),連接就結(jié)束了。
             TDP連接的一端接收到FIN報(bào)文段時(shí),如果還有數(shù)據(jù)要發(fā)送,需要繼續(xù)將數(shù)據(jù)進(jìn)行發(fā)送完成,然后才發(fā)出FIN報(bào)文段;如果還有數(shù)據(jù)未從緩存中取出,將取出數(shù)據(jù),并進(jìn)行確認(rèn),直到所有確認(rèn)完成之后,然后才發(fā)出FIN報(bào)文段(此時(shí)如果有亂序的報(bào)文段情況不進(jìn)行處理)。上面的描述也表現(xiàn)出,TDP是支持半關(guān)閉的,當(dāng)一端發(fā)出FIN報(bào)文段時(shí),仍然允許接收另一端數(shù)據(jù)。但是半關(guān)閉可能導(dǎo)致連接永遠(yuǎn)停留在狀態(tài)圖中FIN_WAIT_2狀態(tài)中,此時(shí)保活機(jī)制仍然在工作當(dāng)中,如果對(duì)端已經(jīng)關(guān)閉,那么保活機(jī)制將在檢測(cè)到時(shí)立即關(guān)閉這一連接。
             
             下圖是一個(gè)典型的連接建立與連接關(guān)閉的示意圖,此圖摘自《TCP/IP詳解 卷一》。
             
             
             
            四、TDP傳輸數(shù)據(jù)流
             
             1.傳輸?shù)膱?bào)文段
             
             在TDP工作過程中傳輸?shù)乃袌?bào)文段,只有SYN報(bào)文段、FIN報(bào)文段、數(shù)據(jù)報(bào)文段是可靠的之外,其它報(bào)文段如ACK報(bào)文段、LIV報(bào)文段、RST報(bào)文段等都不是可靠的。SYN報(bào)文段與FIN報(bào)文段傳輸中都占用一個(gè)序號(hào),數(shù)據(jù)報(bào)文段在傳輸中根據(jù)傳輸?shù)臄?shù)據(jù)字節(jié)數(shù)占用相應(yīng)的序號(hào),其它報(bào)文段不占用傳輸序號(hào)。
             成功接收數(shù)據(jù)報(bào)文段,應(yīng)當(dāng)將按序?qū)ο乱粋€(gè)期望的數(shù)據(jù)報(bào)文段的序號(hào)作為確認(rèn)序號(hào)發(fā)送ACK報(bào)文段進(jìn)行確認(rèn)。當(dāng)出現(xiàn)接收到亂序的數(shù)據(jù)報(bào)文段時(shí),將亂序數(shù)據(jù)報(bào)文段按序緩存,并發(fā)送期望報(bào)文段的ACK報(bào)文段進(jìn)行確認(rèn)。ACK報(bào)文段的發(fā)送并非即時(shí)的,也并非是對(duì)應(yīng)接收數(shù)據(jù)報(bào)進(jìn)行一對(duì)一確認(rèn)發(fā)送。ACK報(bào)文段由200ms定時(shí)觸發(fā)發(fā)送,也就是說ACK報(bào)文段要經(jīng)受最多200ms的時(shí)延進(jìn)行發(fā)送。ACK報(bào)文段對(duì)此時(shí)期望的數(shù)據(jù)序號(hào)進(jìn)行確認(rèn),因此并不是與接收數(shù)據(jù)報(bào)相對(duì)應(yīng)。ACK報(bào)文段是不可靠的,當(dāng)丟失時(shí)對(duì)端將無法了解接收情況,因此發(fā)送方將會(huì)有一個(gè)超時(shí)機(jī)制,如果發(fā)現(xiàn)確認(rèn)的ACK報(bào)文段超時(shí),發(fā)送方將重發(fā)該數(shù)據(jù)報(bào),這一點(diǎn)在第五節(jié)進(jìn)行詳細(xì)描述。
             
             2.路徑MTU發(fā)現(xiàn)及MSS通告
             
             前面已經(jīng)提到要在連接建立過程中會(huì)通告初始MSS,這個(gè)值可以由用戶程序進(jìn)行設(shè)置。但這個(gè)初始值是一個(gè)靜態(tài)的。當(dāng)通信的兩個(gè)端點(diǎn)之間跨越多個(gè)網(wǎng)絡(luò)時(shí),使用設(shè)置的MSS進(jìn)行報(bào)文段發(fā)送時(shí),可能導(dǎo)致傳輸?shù)腎P報(bào)文分片情況的產(chǎn)生。為了避免分片情況的產(chǎn)生,TDP在數(shù)據(jù)傳輸過程中進(jìn)行動(dòng)態(tài)的路徑MTU發(fā)現(xiàn),并進(jìn)行MSS的更新及通告。
             TDP創(chuàng)建UDP SOCKET時(shí),即將描述符設(shè)置IP選項(xiàng)為不允許進(jìn)行分片(setsockopt (clientSock, IPPROTO_IP, IP_DONTFRAGMENT,(char*)&dwFlags, sizeof(dwFlags)))。在發(fā)送數(shù)據(jù)時(shí)以當(dāng)前MSS大小值進(jìn)行數(shù)據(jù)發(fā)送,如果返回值為錯(cuò)誤碼WSAEMSGSIZE(10040)表示為報(bào)文段盡寸大于MTU,需要進(jìn)行IP分片傳輸。此時(shí),縮減MSS大小再次進(jìn)行報(bào)文段發(fā)送,直至不再返回錯(cuò)誤碼WSAEMSGSIZE(10040)。當(dāng)MSS變更并能成功發(fā)送報(bào)文段后,需要向?qū)Χ送▓?bào)新的MSS值。每次MSS縮小后,默認(rèn)隔30秒,TDP將默認(rèn)擴(kuò)大MSS大小,以檢查是否路徑MTU增大了(默認(rèn)值可以由用戶程序設(shè)置),之后隔30*2秒、30*2*2秒進(jìn)行檢測(cè),如果三次都未發(fā)現(xiàn)MTU增大則停止進(jìn)行檢測(cè)。見RFC1191描述,網(wǎng)絡(luò)中MTU值的個(gè)數(shù)是有限的,如下圖描述(摘自RFC1191)。因此MSS的擴(kuò)大及縮減,可依據(jù)一些由近似值按序構(gòu)成的表,依照此表索引進(jìn)行MSS值的擴(kuò)大與縮減計(jì)算。
             
             TDP中MSS與MTU之間關(guān)系的計(jì)算公式如下:
             MSS = MTU – 20(IP首部) – 8(UDP首部) – 12(TDP首部)。
             
             3.Nagle算法
             
             有些人誤認(rèn)為經(jīng)受時(shí)延的捎帶ACK發(fā)送是Nagle算法,其實(shí)不是。經(jīng)受時(shí)延的捎帶ACK發(fā)送是TCP的通常實(shí)現(xiàn),在TDP中也是如此。而Nagle算法是要求一個(gè)TCP(TDP也是如此)連接上最多只能有一個(gè)未被確認(rèn)的未完成的報(bào)文段,在該報(bào)文段的確認(rèn)到達(dá)之前不能發(fā)送其他的報(bào)文段。相反,TCP(TDP也是如此)在這個(gè)時(shí)候收集這些報(bào)文段,關(guān)在確認(rèn)到來時(shí)合并作為一個(gè)報(bào)文段發(fā)送出去。Nagle算法對(duì)于處理應(yīng)用程序產(chǎn)生大量小報(bào)文段的情況,有利于避免網(wǎng)絡(luò)中由于發(fā)送太多的包而過載(這便是發(fā)送端的糊涂窗口綜合癥,關(guān)于糊涂窗口綜合癥在下文將做更詳細(xì)描述)。
             Nagle算法適用于產(chǎn)生大量小報(bào)文段的情況,但有時(shí)我們需要關(guān)閉Nagle算法。一個(gè)典型的例子是X窗口系統(tǒng)服務(wù)器:小消息(鼠標(biāo)移動(dòng))必須無時(shí)延地發(fā)送,以便為進(jìn)行某種操作的交互用戶提供實(shí)時(shí)的反饋。
             默認(rèn)的TDP實(shí)現(xiàn)中Nagle算法是關(guān)閉的,用戶程序可以設(shè)置打開它。
             
             4.窗口大小通告與滑動(dòng)窗口
             
             雙方接收模塊需要依據(jù)各自的緩沖區(qū)大小,相互通告還能接受對(duì)方數(shù)據(jù)的尺寸。雙方發(fā)送模塊則必須根據(jù)對(duì)方通告的接收窗口大小,進(jìn)行數(shù)據(jù)發(fā)送。這種機(jī)制稱之謂滑動(dòng)窗口,它是TDP接收方的流量控制方法。它允許發(fā)送方在停止并等待確認(rèn)前可以連續(xù)發(fā)送多個(gè)分組(依據(jù)滑動(dòng)窗口的大小),由于發(fā)送方不必每發(fā)一個(gè)分組就停下來等待確認(rèn),因此可以加速數(shù)據(jù)的傳輸。
             參照《TCP/IP詳解 卷一 20.3滑動(dòng)窗口》一節(jié),滑動(dòng)窗口在排序數(shù)據(jù)流上不時(shí)的向右移動(dòng),窗口兩個(gè)邊沿的相對(duì)運(yùn)動(dòng)增加或減少了窗口的大小,關(guān)于窗口邊沿的運(yùn)動(dòng)有三個(gè)術(shù)語:窗口合攏(當(dāng)左邊沿向右邊沿靠近)、窗口張開(當(dāng)右邊沿向右移動(dòng))、窗口收縮(當(dāng)右邊沿向左移動(dòng))。RFC文檔強(qiáng)烈建議不要在實(shí)現(xiàn)當(dāng)中出現(xiàn)窗口收縮的情況出現(xiàn),在我們的實(shí)現(xiàn)中也將不會(huì)出現(xiàn)。
             當(dāng)遇到快的發(fā)送方與慢的接收方的情況時(shí),接收方的窗口會(huì)很快被發(fā)送方的數(shù)據(jù)填滿,此時(shí)接收方將通告窗口大小為0,發(fā)送方則停止發(fā)送數(shù)據(jù)。直到接收方用戶程序取走數(shù)據(jù)后更新窗口大小,發(fā)送方可以繼續(xù)發(fā)送數(shù)據(jù);另外,因?yàn)锳CK報(bào)文段有可能丟失,發(fā)送方可能沒有成功接收到更新的窗口大小,因此發(fā)送方將啟動(dòng)一個(gè)堅(jiān)持定時(shí)器,當(dāng)堅(jiān)持定時(shí)器超時(shí),發(fā)送方將發(fā)送一個(gè)字節(jié)的數(shù)據(jù)到接收方,嘗試檢查窗口大小的更新。
             在Nagle算法中接到過糊涂窗口綜合癥,在這里要進(jìn)一步進(jìn)行描述。糊涂窗口綜合癥是指眾多少量數(shù)據(jù)的報(bào)文段將通過連接進(jìn)行交換,而不是滿長(zhǎng)度的報(bào)文段,這將導(dǎo)致連接占用過多帶寬,降低傳輸速率。糊涂窗口綜合癥產(chǎn)生是分兩端的,接收方可以通告一個(gè)小的窗口(而不是一直等到有大的窗口時(shí)才通告),發(fā)送方也可以發(fā)送少量的數(shù)據(jù)(而不是等待其他的數(shù)據(jù)以便發(fā)送一個(gè)大的報(bào)文段)。要以采用如下方法避免這一現(xiàn)象:
             1)接收方不通告小窗口。通常的算法是接收方不通告一個(gè)比當(dāng)前窗口大的窗口(可以為0),除非窗口可以增加一個(gè)報(bào)文段大小(也就是將要接收的MSS)或者可以增加緩存空間的一半,不論實(shí)際有多少。
             2)發(fā)送方避免出現(xiàn)糊涂窗口綜合癥的措施是只有以下條件之一滿足時(shí)才發(fā)送數(shù)據(jù):(a)可以發(fā)送一個(gè)滿長(zhǎng)度的報(bào)文段;(b)可以發(fā)送至少是接收方通告窗口大小一半的報(bào)文段;(c)可以發(fā)送任何數(shù)據(jù)并且不希望接收ACK(也就是說,我們沒有還未被確認(rèn)的數(shù)據(jù))或者該連接上不能使用Nagle算法。
             
             5.PUSH標(biāo)志
             
             PSUH標(biāo)志的作用是發(fā)送方使用PUSH標(biāo)志通知接收方將所收到的數(shù)據(jù)全部提交給接收進(jìn)程。在TDP實(shí)現(xiàn)中,用戶程序并不需要關(guān)心PUSH標(biāo)志。因?yàn)門DP實(shí)現(xiàn)從不將接收到的數(shù)據(jù)推遲交付給用戶程序,因此這個(gè)標(biāo)志在TDP的實(shí)現(xiàn)中是被忽略的。
             
            五、TDP超時(shí)與重傳
             
             1.帶寬時(shí)延乘積與擁塞
             
             每個(gè)網(wǎng)絡(luò)通道都有一定的容量,可以計(jì)算通道的容量大小:
             Capacity(bit) = bandwidth(b/s) * round-trip time(s)
             這個(gè)值一般稱之為帶寬時(shí)延乘積。這個(gè)值依賴于網(wǎng)絡(luò)速度和兩端的RTT,可以有很大的變動(dòng)。不論是帶寬還是時(shí)延均會(huì)影響發(fā)送方與接收方之間通路的容量。
             當(dāng)數(shù)據(jù)到達(dá)一個(gè)大的網(wǎng)絡(luò)通道并向一個(gè)小的網(wǎng)絡(luò)通道發(fā)送,將發(fā)生擁塞現(xiàn)象。另外當(dāng)多個(gè)輸入流到達(dá)一個(gè)路由器,而路由器的輸出流小于這些輸入流的總和時(shí)也會(huì)發(fā)生擁塞。TDP超時(shí)與重傳機(jī)制剛采用TCP的擁塞控制算法來進(jìn)行發(fā)送端的流量控制。
             
             2.往返時(shí)間與重傳超時(shí)時(shí)間測(cè)量
             
             超時(shí)與重傳中最重要的部分就是對(duì)一個(gè)給定連接的往返時(shí)間(RTT)的測(cè)量。由于路由器和網(wǎng)絡(luò)流量均會(huì)發(fā)生變化,因此一般認(rèn)為RTT可能經(jīng)常會(huì)發(fā)生變化,TDP應(yīng)該跟蹤這些變化并相應(yīng)地改變相應(yīng)的超時(shí)時(shí)間。
             首先是必須測(cè)量在發(fā)送一個(gè)帶有特別序號(hào)的字節(jié)和接收到包含字節(jié)的確認(rèn)之間的RTT。由于數(shù)據(jù)報(bào)文段與ACK之間通常沒有一一對(duì)應(yīng)的關(guān)系,如下圖(摘自《TCP/IP詳解 卷一》圖20.1)中,這意味著發(fā)送方可以測(cè)量到的一個(gè)RTT,是在發(fā)送報(bào)文段4和接收?qǐng)?bào)文段7之間的時(shí)間,用M表示所測(cè)量到的RTT。
             根據(jù)[Jacobson 1988]描述(見《TCP/IP詳解 卷一》參考文獻(xiàn)),用A表示被平滑的RTT(均值估計(jì)器),用D表示被平滑的均值偏差,用Err表示剛得到的測(cè)量結(jié)果M與當(dāng)前RTT估計(jì)器之差,則可以計(jì)算下一個(gè)超時(shí)重傳時(shí)間(用RTO表示下一個(gè)超時(shí)重傳時(shí)間)。
             A = 0 (未進(jìn)行測(cè)量往返時(shí)間之前,A的初始值)
             D = 3 (未進(jìn)行測(cè)量往返時(shí)間之前,D的初始值)
             RTO = A + 2D = 6 (未進(jìn)行測(cè)量往返時(shí)間之前,RTO的初始值)
             A = M + 0.5 (第一次測(cè)量到往返時(shí)間結(jié)果,對(duì)RTT估計(jì)器計(jì)算初始值)
             D = A / 2 (第一次測(cè)量到往返時(shí)間結(jié)果,對(duì)均值偏差D計(jì)算初始值)
             RTO = A + 4D (第一次測(cè)量到往返時(shí)間結(jié)果,對(duì)均值偏差RTO計(jì)算初始值)
             之后的計(jì)算方法如下:
             Err = M – A
             A <- A + gErr
             D <- D + h(|Err| - D)
             RTO = A + 4D
             其中g(shù)是常量增量,取值為1/8(0.125);h也是常量增量,取值為1/4(0.25)。
             
             
             
             Karn算法:Karn算法是解決所謂的重傳多義性問題的。[Karn and Partridge 1987]規(guī)定(見《TCP/IP詳解 卷一》參考文獻(xiàn)),當(dāng)一個(gè)超時(shí)和重傳發(fā)生時(shí),在重傳數(shù)據(jù)的確認(rèn)最后到達(dá)之前,不能更新RTT估計(jì)器,因?yàn)槲覀儾⒉恢繟CK對(duì)應(yīng)哪次傳輸(也許第一次傳輸被延遲而并沒有被丟棄,也有可能是第一次傳輸?shù)腁CK被延遲丟棄)。并且,由于數(shù)據(jù)被重傳,RTO已經(jīng)得到了一個(gè)指數(shù)退避,我們?cè)谙乱淮蝹鬏敃r(shí)使用這個(gè)退避后的RTO。對(duì)一個(gè)沒有被重傳的報(bào)文段而言,除非收到了一個(gè)確認(rèn),否則不要計(jì)算新的RTO。
             在任何時(shí)候?qū)γ總€(gè)連接并行僅測(cè)量一次RTT值,在發(fā)送一個(gè)報(bào)文段時(shí),如果給定連接的定時(shí)器已經(jīng)被使用,則該報(bào)文段不被計(jì)時(shí),反之如果給定連接的定時(shí)器未被使用,則開始計(jì)時(shí)以測(cè)量RTT值。即并非每個(gè)發(fā)出報(bào)文段都進(jìn)行測(cè)量RTT值,同一時(shí)間段里只能有一個(gè)RTT值測(cè)量行為進(jìn)行,不會(huì)并行進(jìn)行多個(gè)RTT值測(cè)量。
             
             3.慢啟動(dòng)
             
             如果發(fā)送方一開始便向網(wǎng)絡(luò)發(fā)送多個(gè)報(bào)文段,直至達(dá)到接收方通告窗口大小為止。當(dāng)發(fā)送方與接收方在同一局域網(wǎng)時(shí),這種方式是可以的。但如果在發(fā)送方與接收方之間存在多個(gè)路由器和速率較慢的鏈路時(shí),就可能出現(xiàn)問題。一些中間路由器必須緩存分組,并有可能耗盡存儲(chǔ)器的空間,將來得降低TCP連接的吞吐量。于是需要一種叫“慢啟動(dòng)”的擁塞控制算法。
             慢啟動(dòng)為發(fā)送方增加一個(gè)擁塞窗口,記為cwnd,當(dāng)與另一個(gè)網(wǎng)絡(luò)的主機(jī)建立連接時(shí),擁塞窗口被初始化為1個(gè)報(bào)文段。每收到一個(gè)ACK,擁塞窗口就增加一個(gè)報(bào)文段(cwnd以字節(jié)為單位,但慢啟動(dòng)以報(bào)文段大小為單位進(jìn)行增加)。發(fā)送方取擁塞窗口與通告窗口中的最小值作為發(fā)送上限。擁塞窗口是發(fā)送方使用的流量控制,而通告窗口是接收方使用的流量控制。
             發(fā)送方開始時(shí)發(fā)送一個(gè)報(bào)文段,然后等待ACK。當(dāng)收到該ACK時(shí),擁塞窗口從1增加到2,即可以發(fā)送兩個(gè)報(bào)文段。當(dāng)收到這兩個(gè)報(bào)文段的ACK時(shí),擁塞窗口就增加為4。這是一種指數(shù)增加的關(guān)系。
             
             4.擁塞避免
             
             慢啟動(dòng)算法增加擁塞窗口大小到某些點(diǎn)上可能達(dá)到了互聯(lián)網(wǎng)的容量,于是中間路由器開始丟棄分組。這就通知發(fā)送方它的擁塞窗口開得太大。擁塞避免算法是一種處理丟失分組的方法。該算法假定由于分組受到損壞引起的丟失是非常少的(遠(yuǎn)小于1%),因此分組丟失就意味著在源主機(jī)和目標(biāo)主機(jī)之間的某處網(wǎng)絡(luò)上發(fā)生了擁塞。有兩種分組丟失的指示:發(fā)生超時(shí)和接收到重復(fù)的確認(rèn)。擁塞避免算法與慢啟動(dòng)算法是兩個(gè)獨(dú)立的算法,但實(shí)際中這兩個(gè)算法通常在一起實(shí)現(xiàn)。
             擁塞避免算法和慢啟動(dòng)算法需要對(duì)每個(gè)連接維持兩個(gè)變量:一個(gè)擁塞窗口cwnd和一個(gè)慢啟動(dòng)門限ssthresh。算法的工作過程如下:
             1) 對(duì)一個(gè)給定的連接,初始化cwnd為1個(gè)報(bào)文段,ssthresh為65535個(gè)字節(jié)。
             2) TCP輸出例程的輸出不能超過cwnd和接收方通告窗口的大小。擁塞避免是發(fā)送方使用的流量控制,而通告窗口則是接收方進(jìn)行的流量控制。前者是發(fā)送方感受到的網(wǎng)絡(luò)擁塞的估計(jì),而后者則與接收方在該連接上的可用緩存大小有關(guān)。
             3) 當(dāng)擁塞發(fā)生時(shí)(超時(shí)或收到重復(fù)確認(rèn)),ssthresh被設(shè)置為當(dāng)前窗口大小的一半(cwnd和接收方通告窗口大小的最小值,但最少為2個(gè)報(bào)文段)。此外,如果是超時(shí)引起了擁塞,則cwnd被設(shè)置為1個(gè)報(bào)文段(這就是慢啟動(dòng))。
             4) 當(dāng)新的數(shù)據(jù)被對(duì)方確認(rèn)時(shí),就增加cwnd,但增加的方法依賴于我們是否正在進(jìn)行慢啟動(dòng)或擁塞避免。如果cwnd小于或等于ssthresh,則正在進(jìn)行慢啟動(dòng),否則正在進(jìn)行擁塞避免。慢啟動(dòng)一直持續(xù)到我們回到當(dāng)擁塞發(fā)生時(shí)所處位置的半時(shí)候才停止(因?yàn)槲覀冇涗浟嗽诓襟E2中給我們制造麻煩的窗口大小的一半),然后轉(zhuǎn)為執(zhí)行擁塞避免。
             慢啟動(dòng)算法初始設(shè)置cwnd為1個(gè)報(bào)文段,此后每收到一個(gè)確認(rèn)就加1。這會(huì)使窗口按指數(shù)方式增長(zhǎng):發(fā)送1個(gè)報(bào)文段,然后是2個(gè),接著是4個(gè)……。擁塞避免算法要求每次收到一個(gè)確認(rèn)時(shí)將cwnd增加1/cwnd。與慢啟動(dòng)的指數(shù)增加比起來,這是一種加性增長(zhǎng)。我們希望在一個(gè)往返時(shí)間內(nèi)最多為cwnd增加1個(gè)報(bào)文段(不管在這個(gè)RT T中收到了多少個(gè)ACK),然而慢啟動(dòng)將根據(jù)這個(gè)往返時(shí)間中所收到的確認(rèn)的個(gè)數(shù)增加cwnd。
             處于擁塞避免狀態(tài)時(shí),擁塞窗口的計(jì)算公式如下(引公式參照BSD的實(shí)現(xiàn),segsize/8的值是一個(gè)匹配補(bǔ)充量,不在算法描述當(dāng)中):
             cwnd <- cwnd + segsize * segsize / cwnd + segsize / 8
             
             5.快速重傳與快速恢復(fù)
             
             由于我們不知道一個(gè)重復(fù)的ACK是由一個(gè)丟失的報(bào)文段引起的,還是由于僅僅出現(xiàn)了幾個(gè)報(bào)文段的重新排序,因此我們等待少量重復(fù)的ACK到來。假如這只是一些報(bào)文段的重新排序,則在重新排序的報(bào)文段被處理并產(chǎn)生一個(gè)新的ACK之前,只可能產(chǎn)生1 ~ 2個(gè)重復(fù)的ACK。如果一連串收到3個(gè)或3個(gè)以上的重復(fù)ACK,就非常可能是一個(gè)報(bào)文段丟失了。于是我們就重傳丟失的數(shù)據(jù)報(bào)文段,而無需等待超時(shí)定時(shí)器溢出。這就是快速重傳算法。接下來執(zhí)行的不是慢啟動(dòng)算法而是擁塞避免算法。這就是快速恢復(fù)算法。
             這個(gè)算法通常按如下過程進(jìn)行實(shí)現(xiàn):
             1) 當(dāng)收到第3個(gè)重復(fù)的ACK時(shí),將ssthresh設(shè)置為當(dāng)前擁塞窗口cwnd的一半。重傳丟失的報(bào)文段。設(shè)置cwnd為ssthresh加上3倍的報(bào)文段大小。
             2) 每次收到另一個(gè)重復(fù)的ACK時(shí),cwnd增加1個(gè)報(bào)文段大小并發(fā)送1個(gè)分組(如果新的cwnd允許發(fā)送)。
             3) 當(dāng)下一個(gè)確認(rèn)新數(shù)據(jù)的ACK到達(dá)時(shí),設(shè)置cwnd為ssthresh(在第1步中設(shè)置的值)。這個(gè)ACK應(yīng)該是在進(jìn)行重傳后的一個(gè)往返時(shí)間內(nèi)對(duì)步驟1中重傳的確認(rèn)。另外,這個(gè)ACK也應(yīng)該是對(duì)丟失的分組和收到的第1個(gè)重復(fù)的A C K之間的所有中間報(bào)文段的確認(rèn)。這一步采用的是擁塞避免,因?yàn)楫?dāng)分組丟失時(shí)我們將當(dāng)前的速率減半。
             
            六、代理socks5支持
             
             參照RFC1928、RFC1929,在TDP實(shí)現(xiàn)中,支持匿名通過socks5代理以及用戶名/密碼驗(yàn)證方式通過socks5代理。
             由于socks5代理是工作于運(yùn)輸層上,因此連接當(dāng)中對(duì)IP層選項(xiàng)的設(shè)置都將沒有效果。socks5代理起到的作用只是應(yīng)用數(shù)據(jù)的轉(zhuǎn)發(fā),但這已經(jīng)基本上能支持大部分用戶程序的應(yīng)用需求。在使用socks5代理進(jìn)行工作中,路徑MTU的發(fā)現(xiàn)機(jī)制,將無法有效工作,此時(shí)MSS默認(rèn)為536(MTU默認(rèn)為576),用戶程序可以修改使用的MSS值。
             
            七、安全考慮
             
             TDP協(xié)議及算法方面并不對(duì)數(shù)據(jù)的安全性做任何考慮,用戶程序在傳輸數(shù)據(jù)時(shí)如果對(duì)安全性有要求,可以自行在應(yīng)用數(shù)據(jù)層做相應(yīng)的工作。但TDP實(shí)現(xiàn)中,會(huì)提供一個(gè)簡(jiǎn)單的AES256位加解密方法,提供給用戶程序使用。用戶程序可以調(diào)用該加解密方法,對(duì)數(shù)據(jù)進(jìn)行加密然后再通過網(wǎng)絡(luò)進(jìn)行發(fā)送,接收時(shí)將加密數(shù)據(jù)流進(jìn)行解密再將會(huì)用戶程序數(shù)據(jù)邏輯處理模塊進(jìn)行處理。
             
            八、定時(shí)器
             
             如BSD的TCP實(shí)現(xiàn)類似,TDP也為每條連接建立了六個(gè)定時(shí)器,簡(jiǎn)要介紹如下:
             1)“連接建立”定時(shí)器,在發(fā)送SYN報(bào)文段建立一條新的連接時(shí)啟動(dòng)。如果沒有在75秒內(nèi)收到響應(yīng),連接建立將中止。
             2)“重傳”定時(shí)器,在發(fā)送數(shù)據(jù)時(shí)設(shè)定。如果定時(shí)器已超時(shí)而對(duì)端的確認(rèn)還未到達(dá),將重傳數(shù)據(jù)。重傳定時(shí)器的值是動(dòng)態(tài)計(jì)算的,取決來RTT與該報(bào)文段被重傳的次數(shù)。
             3)“延遲ACK”定時(shí)器,收到必須確認(rèn)但無需馬上發(fā)出確認(rèn)的數(shù)據(jù)時(shí)設(shè)定。等待200ms后發(fā)送確認(rèn)響應(yīng)。如果,在這200ms內(nèi),有數(shù)據(jù)要在該連接上發(fā)送,延遲的ACK響應(yīng)就可隨數(shù)據(jù)一起發(fā)送回對(duì)端,稱為捎帶確認(rèn)。
             4)“堅(jiān)持”定時(shí)器,在連接對(duì)端通告接收窗口為0,阻止繼續(xù)發(fā)送數(shù)據(jù)時(shí)設(shè)定。堅(jiān)持定時(shí)器在超時(shí)后向?qū)Χ税l(fā)送1字節(jié)的數(shù)據(jù),判定對(duì)端接收窗口是否已經(jīng)打開。堅(jiān)持定時(shí)器的值是動(dòng)態(tài)的計(jì)算的,取決于RTT值,在5秒與60秒之間取值。
             5)“保活”定時(shí)器。TDP連接在一定時(shí)間段內(nèi)如果沒有數(shù)據(jù)交互的話,將主動(dòng)發(fā)送保活LIV報(bào)文段。即當(dāng)“保活”定時(shí)器超時(shí),說明沒有數(shù)據(jù)交互,則發(fā)送保活數(shù)據(jù)包。保活定時(shí)器默認(rèn)時(shí)間為2分鐘,用戶程序可以進(jìn)行設(shè)置。
             6)TIME_WAIT定時(shí)器,也可稱為2MSL定時(shí)器(實(shí)現(xiàn)中,一個(gè)MSL為1分鐘)。當(dāng)連接狀態(tài)轉(zhuǎn)移到TIME_WAIT時(shí),即連接主動(dòng)關(guān)閉時(shí),定時(shí)器啟動(dòng)。
             
            九、開發(fā)接口
             
             使用TDP進(jìn)行網(wǎng)絡(luò)程序開發(fā)是非常容易的,它的開發(fā)接口(API)與socket API是非常相似的,尤其是對(duì)應(yīng)功能的函數(shù)名稱都是一致的,需要注意的是TDP的所有API都處于名稱空間TDP之下。開發(fā)接口見下表:
             
            函數(shù) 描述 
            TDP::accept 接受一個(gè)鏈接 
            TDP::bind 綁定本地地址到一個(gè)TDP::SOCKET句柄 
            TDP::cleanup 清除TDP全局資源,一個(gè)進(jìn)程中只需要調(diào)用一次 
            TDP::close 關(guān)閉已打開的TDP::SOCKET句柄,并關(guān)閉連接 
            TDP::connect 連接到服務(wù)器端 
            TDP::getlasterror 獲得TDP最后的一個(gè)錯(cuò)誤 
            TDP::getpeername 讀取連接的對(duì)端的地址信息 
            TDP::getsockname 讀取連接的本地的地址信息 
            TDP::getsockopt 讀取TDP的選項(xiàng)信息 
            TDP::listen 等待客戶端來連接 
            TDP::recv 接收數(shù)據(jù) 
            TDP::select 等待集合中的TDP SOCKET改變狀態(tài) 
            TDP::send 發(fā)送數(shù)據(jù) 
            TDP::setsockopt 修改TDP的選項(xiàng)信息 
            TDP::shutdown 指定關(guān)閉連接上雙工通信的部分或全部 
            TDP::socket 創(chuàng)建一個(gè)TDP SOCKET 
            TDP::startup 初始化TDP全局信息,一個(gè)進(jìn)程中只需要調(diào)用一次 
             
            十、作者簡(jiǎn)介
             
            黃洪波,男,1979年11月20日出生;
            2002.6年畢業(yè)于江西農(nóng)業(yè)大學(xué)計(jì)算機(jī)與信息工程學(xué)院;
            2002.6-2003.7年工作于先鋒軟件股份有限公司,從事電子政務(wù)及企業(yè)信息化研究與開發(fā);
            2003.7-2006.6年工作于金山軟件股份有限公司金山毒霸事業(yè)部,從事企業(yè)信息安全領(lǐng)域研發(fā)工作,專注于網(wǎng)絡(luò)應(yīng)用技術(shù)及安全的研究;
             2006年6月中旬至今,成為軟件自由人,目前從事TDP(TCP-over-UDP library)及項(xiàng)目PlumBlossom研發(fā)。 

            posted on 2009-03-17 22:05 大龍 閱讀(9699) 評(píng)論(14)  編輯 收藏 引用

            評(píng)論

            # re: (TCP-over-UDP library):基于UDP協(xié)議之上實(shí)現(xiàn)通用、可靠、高效的TCP協(xié)議 ---------- 轉(zhuǎn) 2009-05-25 14:04 freemel

            你的這種模式, 除了能穿越防火墻外, 性能上比TCP高多少? 感覺不如直接用TCP啊  回復(fù)  更多評(píng)論   

            # re: (TCP-over-UDP library):基于UDP協(xié)議之上實(shí)現(xiàn)通用、可靠、高效的TCP協(xié)議 ---------- 轉(zhuǎn) 2010-05-28 00:07 VALARIELara

            My essays writing skills are poor. So, to order literary essays using some <a href="http://www.bestwritingservice.com">essay writing</a> service supposes to be the best way in this case.   回復(fù)  更多評(píng)論   

            # re: (TCP-over-UDP library):基于UDP協(xié)議之上實(shí)現(xiàn)通用、可靠、高效的TCP協(xié)議 ---------- 轉(zhuǎn) 2010-06-15 19:12 buy resume

            Yeah doubtless very
            crucial for the lector it was pleasant to read about this post! If you need to get a great job firstofall you need resume services. Study and don't forget - if you have to work and study at the same time, there areexperts who are ready to benefit you with your resume when you under time encumbrance and looking for a great job.  回復(fù)  更多評(píng)論   

            # re: (TCP-over-UDP library):基于UDP協(xié)議之上實(shí)現(xiàn)通用、可靠、高效的TCP協(xié)議 ---------- 轉(zhuǎn) 2010-06-18 22:38 essay example

            Do you remember that the essay writing service will be able to create A+ analysis term papers, hence don't miss your opportunity, purchase customized essay.   回復(fù)  更多評(píng)論   

            # re: (TCP-over-UDP library):基于UDP協(xié)議之上實(shí)現(xiàn)通用、可靠、高效的TCP協(xié)議 ---------- 轉(zhuǎn) 2010-09-23 10:01 jangsong

            tcp over udp  回復(fù)  更多評(píng)論   

            # re: (TCP-over-UDP library):基于UDP協(xié)議之上實(shí)現(xiàn)通用、可靠、高效的TCP協(xié)議 ---------- 轉(zhuǎn) 2012-12-26 17:33 shuiren

            @freemel
            搞笑,你覺得會(huì)比tcp快?
            想都不用想,肯定會(huì)慢  回復(fù)  更多評(píng)論   

            # re: (TCP-over-UDP library):基于UDP協(xié)議之上實(shí)現(xiàn)通用、可靠、高效的TCP協(xié)議 ---------- 轉(zhuǎn) 2012-12-26 17:39 shuiren

            就是在udp上在加一層,算法上和tcp一模一樣,把tcp中原來ip層干的事情由udp層做了而已。相比tcp協(xié)議直接使用ip層的數(shù)據(jù),既然加了個(gè)層,必然會(huì)變慢。
            這個(gè)網(wǎng)絡(luò)層結(jié)構(gòu)看起來會(huì)很詭異。本人確實(shí)不知道nat穿透有多少人需要,udp在做穿透時(shí)比tcp又有多大優(yōu)勢(shì),但真心覺得,這個(gè)東東性價(jià)比不高。  回復(fù)  更多評(píng)論   

            # re: (TCP-over-UDP library):基于UDP協(xié)議之上實(shí)現(xiàn)通用、可靠、高效的TCP協(xié)議 ---------- 轉(zhuǎn) 2012-12-26 17:44 shuiren

            擼主有這時(shí)間不如直接在ip層上實(shí)現(xiàn)一個(gè)和tcp udp平級(jí)而不同于tcp的另一套可靠傳輸協(xié)議得了,并編譯好驅(qū)動(dòng)去發(fā)布,豈不靠譜多了,還能順帶搞搞方校長(zhǎng)的墻,功德無量  回復(fù)  更多評(píng)論   

            # re: (TCP-over-UDP library):基于UDP協(xié)議之上實(shí)現(xiàn)通用、可靠、高效的TCP協(xié)議 ---------- 轉(zhuǎn) 2013-10-23 23:49 shui

            我個(gè)人認(rèn)為這是應(yīng)用場(chǎng)景不同,采用udp的,比如流媒體的視頻,是可以丟包了,這時(shí)候,如果是tcp,壓力就比較大了!  回復(fù)  更多評(píng)論   

            # re: (TCP-over-UDP library):基于UDP協(xié)議之上實(shí)現(xiàn)通用、可靠、高效的TCP協(xié)議 ---------- 轉(zhuǎn) 2015-12-21 13:11 pcplayer

            你這個(gè)思路,我在04年實(shí)現(xiàn)過。當(dāng)時(shí)只花了一周的時(shí)間就寫出來了,工作很穩(wěn)定,當(dāng)然,因?yàn)橹换艘恢埽瑳]去做優(yōu)化,通訊效率不高。

            看到有人留言說這樣做性價(jià)比不高,沒什么用。這些人都是不懂具體需求的。  回復(fù)  更多評(píng)論   


            只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


            av无码久久久久久不卡网站| 日本免费久久久久久久网站| 欧美日韩中文字幕久久久不卡| 伊人久久精品影院| 久久婷婷五月综合色高清| 国产精品久久自在自线观看| 久久狠狠一本精品综合网| 天天躁日日躁狠狠久久 | 色综合久久88色综合天天| 久久免费精品视频| 亚洲国产精品综合久久一线| 精品久久久久久无码专区| 久久久久国产亚洲AV麻豆| av色综合久久天堂av色综合在| 久久久久久国产精品无码下载| 一本久久知道综合久久| 性做久久久久久久久老女人| 国产精品美女久久久网AV| 无码人妻久久一区二区三区免费| 久久国产成人亚洲精品影院| 久久伊人精品青青草原高清| 久久久久久午夜成人影院| 囯产极品美女高潮无套久久久 | 夜夜亚洲天天久久| 精品久久久久久无码中文字幕一区 | 亚洲中文字幕久久精品无码APP| 久久精品二区| 国产精品成人99久久久久| a级成人毛片久久| 久久婷婷激情综合色综合俺也去| 日产精品久久久久久久| 久久久久国产一级毛片高清板| 国产精品福利一区二区久久| 久久A级毛片免费观看| 精品无码久久久久国产| 99久久精品费精品国产一区二区| 久久精品亚洲日本波多野结衣| 青青草原精品99久久精品66| 少妇人妻88久久中文字幕| 日本欧美久久久久免费播放网 | 国产精自产拍久久久久久蜜|