基于UDP高性能传输协议UDT
UDP詳解
一、??概述
UDT是一個(gè)高性能的基于UDP的數(shù)據(jù)傳輸協(xié)議,它是為支持高速?gòu)V域網(wǎng)上海量數(shù)據(jù)傳輸而設(shè)計(jì),為解決TCP的效率和公平問(wèn)題,同時(shí)提供可靠的數(shù)據(jù)流和報(bào)文傳輸。
UDT是C++庫(kù),幾乎類(lèi)同于BSD socket APIs。
UDT是多線程安全的,但并不是多進(jìn)程共享。
二、??原理
UDT有兩種傳輸模式:數(shù)據(jù)流模式(SOCK_STREAM)和數(shù)據(jù)報(bào)模式(SOCK_DGRAM)
數(shù)據(jù)流模式類(lèi)似于傳統(tǒng)的BSD套接字,這種模式下不能保證任何一端一個(gè)調(diào)用就把所有的數(shù)據(jù)發(fā)送了,因?yàn)樵跀?shù)據(jù)流中沒(méi)有邊界信息,進(jìn)程需用loop來(lái)發(fā)送和接收。
數(shù)據(jù)報(bào)模式會(huì)將數(shù)據(jù)作為整個(gè)單元來(lái)傳送,不需要循環(huán)來(lái)接收和發(fā)送數(shù)據(jù),要么全部發(fā)送,要么一點(diǎn)也不發(fā)送。在接收端如果緩沖區(qū)不夠大,則只會(huì)接收到部分?jǐn)?shù)據(jù),其他的將被丟棄。
?
UDT發(fā)送數(shù)據(jù)有阻塞與非阻塞方式,在阻塞方式下,會(huì)直到把需要發(fā)送的數(shù)據(jù)發(fā)送完再返回,而非阻塞方式下,會(huì)根據(jù)socket底層的可用緩沖的大小,將緩沖區(qū)中的數(shù)據(jù)拷貝過(guò)去,有多大緩沖就拷貝多少,緩沖區(qū)滿了就立即返回,這個(gè)時(shí)候的返回值只是拷貝了多少,不代表發(fā)送了多少,同時(shí)剩下的部分需要再次調(diào)用send
?
UDT增加了rendezvous模式,這是一種連接模式,用來(lái)穿透防火墻。這種模式下,UDT不能調(diào)用listen和accept,而是兩端bind后同時(shí)建立連接。
?
UDT允許用戶自己定義擁塞控制。可以繼承DUT/CCC下的CCC類(lèi)來(lái)改變一些變量,如擁塞窗口,./app/cc.h下的實(shí)例是學(xué)習(xí)的快速途徑。
?
三、??安裝及平臺(tái)
UDT是基于源碼的庫(kù),所以沒(méi)有安裝文件工具,我們只需要根據(jù)不同的系統(tǒng)和CPU架構(gòu)使用命令來(lái)make相應(yīng)的庫(kù)即可。
UDT支持的系統(tǒng):Linux,BSD,OSX
UDT支持的架構(gòu):IA32,IA64,POWERPC,AMD64
命令:??make –e os=XXX arch=XXX
?
UDT來(lái)源于BSD socket API只有一個(gè)頭文件<udt.h>,一些繼續(xù)使用BSDAPI?另一些需要加標(biāo)示符UDT::
庫(kù):libudt.h???????udt.dll???????udt.dylib?????libudt.a???udt.lib?
四、??配置設(shè)置
讀取和設(shè)置選項(xiàng)通過(guò)getsockopt和setsockopt方法,一般不要修改默認(rèn)選項(xiàng)除非應(yīng)用不能正常運(yùn)行。
?
UDT_MSS用來(lái)設(shè)置包的大小,一般情況下最佳的UDT包的大小是網(wǎng)絡(luò)MTU(默認(rèn)1500字節(jié))的大小,連接的兩端都要設(shè)置這個(gè)值,傳輸時(shí)取兩端的較小者。
UDT用不同的同步方式語(yǔ)義UDT_SNDSYN和UDT_RCVSYN,它可以獨(dú)立的設(shè)置發(fā)送和接收同步,具有更多的靈活性。它不允許在連接建立和關(guān)閉的時(shí)候進(jìn)行非阻塞操作。
?
UDT緩沖區(qū)的大小理論上越大越好,要運(yùn)行的好兩端buffer至少為【帶寬*RTT】
UDT使用UDP數(shù)據(jù)通道,所以UDP緩沖大小影響程序運(yùn)行,但隨著buffer變大效果也會(huì)越來(lái)越不明顯。一般來(lái)說(shuō)發(fā)送端的buffer小一點(diǎn),因?yàn)榘陌l(fā)送沒(méi)有限制太多,但太大會(huì)增加端到端的延時(shí)。
?
UDT_LINGER是設(shè)置socket關(guān)閉時(shí)是否立即停止發(fā)送緩沖區(qū)的數(shù)據(jù)。
UDT_RENDEZVOUS設(shè)置集合點(diǎn)模式,在穿越防火墻時(shí)很有用。
UDT_SNDTIMEO和UDT_RCVTIMEO是timeout值
UDT_REUSEADDR設(shè)置UDP端口是否可以給其他UDT使用,默認(rèn)值是true。
以下情況需設(shè)置false
1,兩個(gè)UDT socket不能在同一端口監(jiān)聽(tīng)。
2,兩個(gè)UDT socket綁定在同一IP同一端口而不能建立連接。
發(fā)送發(fā)有兩種選擇:
1,TTL(默認(rèn)無(wú)限)為timeout時(shí)間。
2,消息有序到達(dá),直到上一個(gè)消息到達(dá)或被丟棄才發(fā)下一個(gè)。
?
UDT提供文件傳輸,UDT::sendfile和UDT::recvfile這種發(fā)送接收方式跟
UDT::send和UDT::recv是正交的。也就是說(shuō)用sendfile發(fā)送不一定要用recvfile接收。另外,sendfile和recvfile不受SNDSYN,RCVSYN,SNDTIMEO,RCVTIMEO影響。它使用C++ fstream進(jìn)行文件IO。
?
UDT打洞,在傳統(tǒng)方式下,穿越防火墻時(shí)是用SO_REUSEADDR選項(xiàng)去打開(kāi)兩個(gè)socket綁定同一個(gè)端口,一個(gè)監(jiān)聽(tīng)一個(gè)建立連接。而UDT提供直接相連的方式。
?
UDT允許一個(gè)進(jìn)程中的所有socket綁定到同一端口但只允許一個(gè)監(jiān)聽(tīng)。
UDT允許綁定已經(jīng)存在的UDP端口有兩個(gè)好處:
1,當(dāng)應(yīng)用程序向服務(wù)器發(fā)送一個(gè)空包去獲得它的地址(尤其是在NAT防火墻下)時(shí),用戶會(huì)創(chuàng)建一個(gè)UDP包發(fā)送個(gè)server確定綁定的端口,然后UDP端口可以順便給UDT使用。
2,一些本地防火墻在關(guān)閉“打洞”時(shí)會(huì)改變映射端口,新的UDT綁定的端口將失效,此時(shí)用UDP的是必須的。
?
錯(cuò)誤處理:所有的UDT API在遇到錯(cuò)誤時(shí)都會(huì)返回error UDT定義兩種錯(cuò)誤,
UDT::INVALID_SOCK和UDT::ERROR。可以用getErrorCode和getErrorMessage方法查看存放在ERRORINFO數(shù)據(jù)結(jié)構(gòu)中的錯(cuò)誤代碼及信息。
成功的調(diào)用不會(huì)清楚錯(cuò)誤,所以應(yīng)用程序應(yīng)該利用返回值檢查調(diào)用結(jié)果,可以調(diào)用個(gè)體lasterror().clean()來(lái)清除錯(cuò)誤日志。
總結(jié)
以上是生活随笔為你收集整理的基于UDP高性能传输协议UDT的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: MySQL 基本语法
- 下一篇: CMakeList.txt中设置一个可变