精通
英语
和
开源
,
擅长
开发
与
培训
,
胸怀四海
第一信赖
网站首页
技术服务
技术中心
开源优势
英语优势
服务流程
典型客户
服务分类
软件开发
商业项目优势
产品列表
服务流程
典型客户
软件开发培训
在线教育
连锁培训
高校合作
兴趣
科研
就业
企业合作
人才委托培训
HR整体外包
关于我们
公司理念
公司荣誉
公司架构
人才招聘
视频下载
软件开发培训高品质源自卓越软件开发能力
高端企业级软件开发培训模式,承诺掌握软件开发工作经验
软件开发在线教育品质出众和软件开发培训实地面授效果一致
软件开发培训诚信经营
当前位置:
锐英源
/
开源技术
/
基于UDP的数据传输协议UDT
/ UDT开发文档详解-来自国外专家
服务方向
人工智能数据处理
人工智能培训
kaldi数据准备
小语种语音识别
语音识别标注
语音识别系统
语音识别转文字
kaldi开发技术服务
软件开发
运动控制卡上位机
机械加工软件
软件开发培训
Java 安卓移动开发
VC++
C#软件
汇编和破解
驱动开发
联系方式
固话:0371-63888850
手机:138-0381-0136
Q Q:396806883
微信:ryysoft
基于UDP高性能传输协议UDT UDT的国外精华翻译
UDT文档阅读理解
一、 概述
UDT是一个高性能的基于UDP的数据传输协议,它是为支持高速广域网上海量数据传输而设计,为解决TCP的效率和公平问题,同时提供可靠的数据流和报文传输。
UDT是C++库,几乎类同于BSD socket APIs。
UDT是多线程安全的,但并不是多进程共享。
二、 原理
UDT有两种传输模式:数据流模式(SOCK_STREAM)和数据报模式(SOCK_DGRAM)
数据流模式类似于传统的BSD套接字,这种模式下不能保证任何一端一个调用就把所有的数据发送了,因为在数据流中没有边界信息,进程需用loop来发送和接收。
数据报模式会将数据作为整个单元来传送,不需要循环来接收和发送数据,要么全部发送,要么一点也不发送。在接收端如果缓冲区不够大,则只会接收到部分数据,其他的将被丢弃。
UDT发送数据有阻塞与非阻塞方式,在阻塞方式下,会直到把需要发送的数据发送完再返回,而非阻塞方式下,会根据socket底层的可用缓冲的大小,将缓冲区中的数据拷贝过去,有多大缓冲就拷贝多少,缓冲区满了就立即返回,这个时候的返回值只是拷贝了多少,不代表发送了多少,同时剩下的部分需要再次调用send
UDT增加了rendezvous模式,这是一种连接模式,用来穿透防火墙。这种模式下,UDT不能调用listen和accept,而是两端bind后同时建立连接。
UDT允许用户自己定义拥塞控制。可以继承DUT/CCC下的CCC类来改变一些变量,如拥塞窗口,./app/cc.h下的实例是学习的快速途径。
三、 安装及平台
UDT是基于源码的库,所以没有安装文件工具,我们只需要根据不同的系统和CPU架构使用命令来make相应的库即可。
UDT支持的系统:linux,BSD,OSX
UDT支持的架构:IA32,IA64,POWERPC,AMD64
命令: make –e os=XXX arch=XXX
UDT来源于BSD socket API只有一个头文件<udt.h>,一些继续使用BSDAPI 另一些需要加标示符UDT::
库:libudt.h udt.dll udt.dylib libudt.a udt.lib
四、 配置设置
读取和设置选项通过getsockopt和setsockopt方法,一般不要修改默认选项除非应用不能正常运行。
UDT_MSS用来设置包的大小,一般情况下最佳的UDT包的大小是网络MTU(默认1500字节)的大小,连接的两端都要设置这个值,传输时取两端的较小者。
UDT用不同的同步方式语义UDT_SNDSYN和UDT_RCVSYN,它可以独立的设置发送和接收同步,具有更多的灵活性。它不允许在连接建立和关闭的时候进行非阻塞操作。
UDT缓冲区的大小理论上越大越好,要运行的好两端buffer至少为【带宽*RTT】
UDT使用UDP数据通道,所以UDP缓冲大小影响程序运行,但随着buffer变大效果也会越来越不明显。一般来说发送端的buffer小一点,因为包的发送没有限制太多,但太大会增加端到端的延时。
UDT_LINGER是设置socket关闭时是否立即停止发送缓冲区的数据。
UDT_RENDEZVOUS设置集合点模式,在穿越防火墙时很有用。
UDT_SNDTIMEO和UDT_RCVTIMEO是timeout值
UDT_REUSEADDR设置UDP端口是否可以给其他UDT使用,默认值是true。
以下情况需设置false
1,两个UDT socket不能在同一端口监听。
2,两个UDT socket绑定在同一IP同一端口而不能建立连接。
发送发有两种选择:
1,TTL(默认无限)为timeout时间。
2,消息有序到达,直到上一个消息到达或被丢弃才发下一个。
UDT提供文件传输,UDT::sendfile和UDT::recvfile这种发送接收方式跟
UDT::send和UDT::recv是正交的。也就是说用sendfile发送不一定要用recvfile接收。另外,sendfile和recvfile不受SNDSYN,RCVSYN,SNDTIMEO,RCVTIMEO影响。它使用C++ fstream进行文件IO。
UDT打洞,在传统方式下,穿越防火墙时是用SO_REUSEADDR选项去打开两个socket绑定同一个端口,一个监听一个建立连接。而UDT提供直接相连的方式。
UDT允许一个进程中的所有socket绑定到同一端口但只允许一个监听。
UDT允许绑定已经存在的UDP端口有两个好处:
1,当应用程序向服务器发送一个空包去获得它的地址(尤其是在NAT防火墙下)时,用户会创建一个UDP包发送个server确定绑定的端口,然后UDP端口可以顺便给UDT使用。
2,一些本地防火墙在关闭“打洞”时会改变映射端口,新的UDT绑定的端口将失效,此时用UDP的是必须的。
错误处理:所有的UDT API在遇到错误时都会返回error UDT定义两种错误,
UDT::INVALID_SOCK和UDT::ERROR。可以用getErrorCode和getErrorMessage方法查看存放在ERRORINFO数据结构中的错误代码及信息。
成功的调用不会清楚错误,所以应用程序应该利用返回值检查调用结果,可以调用个体lasterror().clean()来清除错误日志。
五、 接口描述
socket方法
方法名
socket方法
功能
用于创建一个新的socket
详细接口
UDTSOCKET socket(
int af,
int type,
int protocol
);
返回值
成功:返回socket描述符
错误:返回UDT::INVALID_SOCK
描述
type:指SICK_STREAM或SOCK_DARAM
protocol:忽略
af:AF_INET(IPv4)或者AF_INET(IPv6)
UDT支持IPv4和IPv6可以通过af参数选择。
accept方法
方法名
accept方法
功能
用于接收一个进来的连接
详细接口
UDTSOCKET accept(
UDTSOCKET u,
struct sockaddr* addr,
int* addrlen
);
返回值
成功:返回新连接的描述符
错误:返回UDT::INVALID_SOCK
描述
当一个UDT socket处于监听状态,它将接收到的连接存放在一个队列里,一个accept调用会依次从队列里首先取出对头的连接,并将其移出队列。
当队列里没有连接请求时,一个阻塞式的socket就会等待下一个连接,遇到错误时会有一个非阻塞式的socket立即返回。
接收到的socket会继承监听socket的属性。
bind方法
方法名
bind方法
功能
用于绑定一个端口
详细接口
int bind(
UDTSOCKET u,
struct sockaddr* name,
int* namelen
);
int bind(
#ifndef WIN32
int udpsock
#else
SOCKET udpsock
#endif
);
返回值
成功:返回0
错误:返回UDT::ERROR
描述
绑定内容包括IP地址和端口,如果设置了INADDR_ANY,则表示0.0.0.0任意地址(多网卡时),当端口使用0则会使用一个随机的可用端口,用getsockname可以获得端口号,另一种方式UDT允许绑定在已存在的UDP端口(前面已写)此时需注意代码的健壮性,一旦UDP描述符被UDT使用,不要再随便使用除非你对系统非常了解。
绑定过程是必须的,除了在监听下,如果没有绑定,UDT会自动随机绑定一个地址
cleanup方法
方法名
cleanup方法
功能
用于释放UDT库
详细接口
int cleanup(
);
返回值
成功:返回0
错误:返回UDT::ERROR
描述
当它被调用有如下两个操作:
1,所有存在的打开的连接都会被关闭
2,后台垃圾回收也被关闭。
这个方法有效的前提是:startup方法在之前调用。
startup方法
方法名
startup方法
功能
用于初始化UDT库
详细接口
int startup(
);
返回值
成功:返回0
错误:返回UDT::ERROR(此版本总会成功)
描述
初始化库,开启垃圾回收线程,必须在所有UDT调用之前调用它,否则会造成内存泄露。
若多次调用则只有第一次有效。
close方法
方法名
close方法
功能
用于关闭一个UDT连接
详细接口
int close(
UDTSOCKET u
);
返回值
成功:返回0
错误:返回UDT::ERROR
描述
它温和地关闭UDT连接并释放有关的数据结构,如果没有连接,则只释放与socket相关的资源。
在阻塞方式下,如果UDT_LINGER设为非0,则会等待发送缓存发送完或者时间到。非阻塞下立即关闭。
关闭socket会发送一个关闭消息给另一端,通知其关闭连接,如果没有成功传送,对方也会在一个TIME_OUT的时间后关闭。
不用的socket都应该被关掉。
connect方法
方法名
connect方法
功能
用于连接到服务端socket(常规)或者peer side(集合点模式)
详细接口
int connect(
UDTSOCKET u,
const struct sockaddr* name,
int* namelen
);
返回值
成功:返回0
错误:返回UDT::ERROR
描述
UDT是面向连接的。有两种模式:SOCK_STREA,和SOCK_DARAM模式,
name是需要建立连接的服务端或者peer side。
C/S模式下服务端要调用bind和listen,在rendezvous模式下,两端都要bind并同时连接。
UDT至少需要一个来回建立连接,这对于频繁建立连接又断开的应用是一个瓶颈。
当UDT_RCVSYN=false(接收不同步)connect会立即返回,并在后台运行建立连接,线程可以用epoll来等待连接完成。
当失败是sicket可以重连,失败的socket也要用close来关闭。
epoll方法
方法名
epoll方法
功能
用于有效地对大量的socket轮询IO事件
详细接口
#ifndef WIN32
typedef int SYSSOCKET;
#else
typedef SOCKET SYSSOCKET;
#endif
int epoll_create();
int epoll_add_usock(const int eid, const UDTSOCKET usock, const int* events = NULL);
int epoll_add_ssock(const int eid, const UDTSOCKET ssock, const int* events = NULL);
int epoll_remove_usock(const int eid, const UDTSOCKET usock, const int* events = NULL);
int epoll_remove_ssock(const int eid, const UDTSOCKET ssock, const int* events = NULL);
int epoll_wait(const int eid, std::set<UDTSOCKET>* readfds, std::set<UDTSOCKET>* writefds, int64_t msTimeOut, std::set<SYSSOCKET>* lrfds = NULL, std::set<SYSSOCKET>* wrfds = NULL);
int epoll_release(const int eid);
返回值
成功:epoll_create返回epoll ID,
epoll_wait返回准备好IO的socket数量
其他三个函数返回0.
错误:返回UDT::ERROR
描述
当线程需等待很多socket时,应该用epoll代替select和selectEx来查询。
它也提供等待系统socket,这样应用就可以同时接受UDT和TCP/UDP。
线程可以用epoll_create去创建一个epoll ID用epoll_add_usock和epoll_remove_usock去添加和删除socket,如果已经存在,添加会被忽略。
添加无效的或者关闭的socket会引发错误。删除不存在的则不会错误(忽略)
在linux上,开发者可以用EPOLLIN(read)和EPOLLOUT(write)以及EPOLLERR(异常)来查看具体事件。可以创建多个epoll。
epoll_wait是一个timeout值
getlasterror方法
方法名
getlasterror方法
功能
用于获得一个线程最近一次的UDT错误
详细接口
ERRORINFO& getlasterror(
);
返回值
成功:返回0
错误:返回UDT::ERROR
描述
读出线程中最近一次的错误。
getpeername方法
方法名
getpeername方法
功能
用于获得peer side的地址
详细接口
int getpeername(
UDTSOCKET u,
struct sockaddr* name,
int* namelen
);
返回值
成功:返回0,并将地址存储在name变量中。
错误:返回UDT::ERROR
描述
前提是:UDT socket已经建立了连接。
getsockname方法
方法名
getsockname方法
功能
用于获得相关DUT的本地地址
详细接口
int getsockname(
UDTSOCKET u,
struct sockaddr* name,
int* namelen
);
返回值
成功:返回0,并将地址存储在name变量中。
错误:返回UDT::ERROR
描述
调用该方法前,UDT socket必须明确地绑定了或隐式地连接了。
如果该调用在bind之后且在connect之前,IP地址会返回用于绑定的地址,如果在连接之后,返回的是peer side看到的地址。
例如:
有一个代理地址,连接后,将返回代理IP地址,不是本地地址,但不管哪种情况,返回的端口号是一样的。
因为UDP是无连接的,用此调用返回0.0.0.0作为IP地址,而UDT是面向连接的,UDT会返回一个有效的IP地址(如果没有代理)。
UDT暂时还没有多重连接功能,当有多个网卡时会出错。
getsockopt方法和setsockopt方法
方法名
getsockopt方法和setsockopt方法
功能
用于获得和设置UDT的配置选项
详细接口
int getsockopt(
UDTSOCKET u,
int level,
SOCKOPT optname,
char* optval,
int* optlen
);
int setsockopt(
UDTSOCKET u,
int level,
SOCKOPT optname,
const char* optval,
int optlen
);
返回值
成功:返回0。
错误:返回UDT::ERROR
描述
optname选项描述符
optval存放设置选项的指针
optlen是optval的长度
不是任何时候都可以设置这些选项
perfmon方法
方法名
perfmon方法
功能
用于取得内部协议参数和执行追踪
详细接口
int perfmon(
UDTSOCKET u,
TRACEINFO* perf,
bool clear= true
);
返回值
成功:返回0。并且将追踪结果存放在trace中。
错误:返回UDT::ERROR
描述
追踪最近一次的记录,结果写进TRACEINFO结构中。
有三种信息可读:
1, 自连接以来的连接总数
2, 自上次清除counts后的数
3, 立即参数值
recv方法和send方法
方法名
recv方法和send方法
功能
用于读取数据到本地缓冲区和将线程缓冲区中的数据发出去。
详细接口
int recv(
UDTSOCKET u,
char* buf,
int len,
int flags
);
int send(
UDTSOCKET u,
const char* buf,
int len,
int flags
);
返回值
成功:返回发送或接受数据的大小。
错误:返回UDT::ERROR
描述
recv从协议buf读len长度的数据,不够的话,读取存在的,在阻塞方式下recv等待buf中存入数据,非阻塞方式下立即返回error。
可以给recv设置UDT_RCVTIMEO
同理发送一个大小一定的数据,如果发送缓冲buff不够存入一定len长度的数据,则发送一部分。在阻塞方式下send等待buffer有空余再发,非阻塞方式下返回错误。
sendfile方法和recvfile方法
方法名
sendfile方法和recvfile方法
功能
用于发送部分或全部本地文件数据和读出一定数量数据到本地文件
详细接口
int64_t recvfile(
UDTSOCKET u,
fstream& ofs,
int64_t& offset,
int64_t size,
int block= 366000
);
int64_t sendfile(
UDTSOCKET u,
fstream& ifs,
const int64_t& offset,
const int64_t size,
const int block= 7320000
);
返回值
成功:返回发送或接收的数据大小。
错误:返回UDT::ERROR
描述
sendfile通常是阻塞方式发送,UDT_SNDSYN和UDTTIMEO都不影响它的发送。
在peer side不一定非要用recvfile接收sendfile
recvfile调用前必须知道数据的大小,否则可能会造成死锁。
recvmsg方法和sendmsg方法
方法名
recvmsg方法和sendmsg方法
功能
用于发送和接收有效的数据报
详细接口
int recvmsg(
UDTSOCKET u,
char* msg,
int len
);
int sendmsg(
UDTSOCKET u,
const char* msg,
int len,
int ttl= -1,
bool inorder= false
);
返回值
成功:返回发送或接收的数据大小。
错误:返回UDT::ERROR
描述
recvmsg和sendmsg只能在SOCK_DGRAM模式下。
接收不够的message会被丢弃。
在阻塞方式下和send跟recv一样需等待buffer
TTL限定了送达的时间,时间到没送达将被丢弃。
inorder参数决定了数据报的有序到达,先前的报文到达后来的才能发。
友情链接
汕头招聘网
|
山东招聘网
|
郑州教育培训
|
软件下载
版权所有 Copyright(c)2004-2024 锐英源软件
统一社会信用代码:91410105098562502G 豫ICP备08007559号 最佳分辨率 1440*900
地址:郑州市金水区文化路97号郑州大学北区院内南门附近