1. linux 应用层用udp发送数据时有大小限制吗

从理论上来说,UDP数据的总长度为 65535(IP最大长度)-20(IP头)-8(UDP头) = 65507个字节,但大多数系统都达不到这个长度。这一般是受到两个方面的因素限制:
1) 应用程序编程接口限制。一般socket的缓冲区大小是8K,但都提供API来设置缓冲区的大小(SetSockOpt)。一般发送UDP最好不要超过512字节,这样基本可以保证不丢包(因为大部分网络和主机的MTU都大于512).
2) TCP/IP内核的限制。可能存在一些实现特性使得IP长度不能达到65535。

由于IP能够发送或接收特定长度的数据报并不意味着接收应用程序可以读取该长度的数据。因此,UDP编程接口允许应用程序指定每次返回的最大字节数。如果接收到的数据报长度大于应用程序所能处理的长度,那么会发生什么情况呢?典型的Berkeley版socket API对数据报进行截断,并丢弃任何多余的数据;SVR4下的socket API(包括Solaris 2.x) 并不截断数据报。超出部分数据在后面的读取中返回。它也不通知应用程序从单个UDP数据报中多次进行读取操作;TLI API不丢弃数据。相反,它返回一个标志表明可以获得更多的数据,而应用程序后面的读操作将返回数据报的其余部分。

UDP不会分片,分片是IP层做的事,而且分片重组也是IP层负责的。
如果用UDP发送数据,数据量最好不要太大,应该避免IP层和链路层分包,防止分片丢失,导致整个UDP数据包丢失。

2. 如何让UDP实现可靠传输

如何让UDP实现可靠传输
自定义通讯协议,在应用层定义一些可靠的协议,比如检测包的顺序,重复包等问题,如果没有收到对方的ACK,重新发包
UDP没有Delievery Garuantee,也没有顺序保证,所以如果你要求你的数据发送与接受既要高效,又要保证有序,收包确认等,你就需要在UDP协议上构建自己的协议。比如RTCP,RTP协议就是在UPD协议之上专门为H.323协议簇上的IP电话设计的一种介于传输层和应用层之间的协议。
下面分别介绍三种使用UDP进行可靠数据传输的协议
RUDP
RTP
UDT
RUDP(Reliable User Datagram Protocol)
可靠用户数据报协议(RUDP)是一种基于可靠数据协议(RDP: RFC908 和 1151 (第二版))的简单分组传输协议。作为一个可靠传输协议,RUDP 用于传输 IP 网络间的电话信号。它允许独立配置每个连接属性,这样在不同的平台可以同时实施不同传输需求下的协议。
RUDP 提供一组数据服务质量增强机制,如拥塞控制的改进、重发机制及淡化服务器算法等,从而在包丢失和网络拥塞的情况下, RTP 客户机(实时位置)面前呈现的就是一个高质量的 RTP 流。在不干扰协议的实时特性的同时,可靠 UDP 的拥塞控制机制允许 TCP 方式下的流控制行为。
为了与网络 TCP 通信量同时工作,
RUDP 使用类似于 TCP 的重发机制和拥塞控制算法。
在最大化利用可用带宽上,这些算法都得到了很好的证明。
RUDP特性
客户机确认响应服务器发送给客户机的包;
视窗和拥塞控制,服务器不能超出当前允许带宽;
一旦发生包丢失,服务器重发给客户机;
比实时流更快速,称为“缓存溢出”。
用户数据报协议(UDP)
RTP(Real Time Protocol)
RTP,实时协议被用来为应用程序如音频,视频等的实时数据的传输提供端到端(end to end)的网络传输功能。传输的模型可以是单点传送或是多点传送。数据传输被一个姐妹协议——实时控制协议(RTCP)来监控,后者允许在一个大的多点传送网络上监视数据传送,并且提供最小限度的控制和识别功能。
RTP是被IETF在RFC1889中提出来的。顺带提及,RTP已经被接受为实时多媒体传送的通用标准。ITU-T跟IETF都在各自的系统中将这一协议标准化。
1.1 为何需要RTP?
TCP不能支持像交互视频,会议等的实时服务,这一原因是由于TCP只是一个“慢”协议,需要三次握手。就此在IP层上UDP是一个比TCP更好的选择。但是UDP是本质上是一个不可靠协议,不支持在包丢情况下的重传机制。诚然,UDP有一些特性,比如多路复用跟校验和服务,这些都是对实时服务很有利的。为了消除UDP的缺点,RTP是作为应用层而被提出来的。
RTP提供的各种服务包括有效负载识别,序列编号,时间戳和投递监听。RTP能够序列化包,当这些包在收端不是按顺序到达的时。序列号也能被用来识别包丢失。时间戳被用于媒体有效的播放。到达的数据一直被RTCP监听,以通知RTP层来校正其编码和传输的参数。例如,如果RTCP层检测到包丢失,它会通知RTP层减缓发送速率。
尽管RTP有助于实时媒体的有效的播放,但是要注意的是RTP自身并不提供任何机制来确保及时传递或提供其他服务质量(QoS)的保证,而是依靠低层服务来完成这些。同样,RTP也不保证投递或防止无序投递。RTP被设计出来主要是为了满足有多个参加者的多媒体会议的需要。RTP也同样适合于象持续数据的储存,分布式交互仿真,主动标记以及应用程序的控制和测量。
1.2 RTP特性一览
RTP提供有效负荷类型识别,乱序重排和利用时间戳的媒体有效播放。
RTCP监控服务质量,也提供在一个当前进行的会话中传送关于参加者的信息作用。
RTP对于下层协议是独立的,它能够工作在像TCP/IP,ATM,帧时延等类型的网络上。
如果被下层网络支持,RTP支持利用多路技术的对于多点的数据传输。
RTP序列号也能被用来确定包的合适位置。例如在视频解码,包无需按序解码。
2.0 技术概览
2.1 RTP
RTP头具有如下的格式。开始的12个八位字节在每一个RTP包中都会出现;而CSRC标识符列表只在通过混合器的包中出现.
Version (V) (版本号):这个域长度为2比特,标出了RTP的最近版本。当前的版本为2.0
Padding (P) (填充):这个域长度为1比特,如果P被置位,包在结尾处包含有一个或多个附加的填充字节,这些填充字节不是有效负荷的一部分。填充是一些需要固定块大小的加密算法所要求的,或是为了在低层PDU搬运RTP包。
Extension (X):这个域长度为1比特,如果被置位,固定的头后面紧跟了一个头的扩展。
CSRC count (CC):这个域长度为4比特。这个域表示了跟在固定头后面的CSRC标识符的数目。如前所述,这个域只有在通过一个混合器才有非零值。
Marker bit (M): 这个域长度为1比特,如果M被置位,表示一些重要的项目如帧边界在包中被标记。例如,如果包中有几个比特的当前帧,连同前一帧,那么RTP的这一位就被置位。
Payload type (PT) (有效负荷类型):这个域长度为7比特,PT指示的是有RTP包中的有效负荷的类型。RTP音频视频简介(AVP)包含了一个默认的有效负荷类型码到有效负荷格式的映射。附加的有效负荷类型可以向IANA注册。
Sequence number(序列号):这个域长度为16个比特,每送一个RTP包数目就增加一,初始值被设为一个随机数。接收方不仅可以用这个序列号检测包丢失,也可以重组包序列。
Time stamp(时间戳):这个域长度为32个比特,时间戳反映了RTP数据包的头一个字节的采样时刻。采样时刻必须是由一个单调线性增加的时钟产生,这样做是为了接收方的同步和抖动计算。初始值必须为随机数,这是为了避免对原码的攻击。例如,如果RTP源使用了一个编码器,缓冲20ms的音频数据,那么RTP时间戳必须每个包增加160,无论包是被传递了还是被丢失了。
SSRC:这个域长度为32比特,这个域表示了正在为会话产生RTP包的源。这个标识符是随机选中的,目的是为了避免同一个RTP会话中两个源有相同的标识符。
CSRC list: 这个列表标识了在这个包中对有效负荷起作用的所有源。标识符的最大数目限定为15,这是由CC域所限定的(全零在CC域中是被禁止的)。如果有超过15个的分配源,只有前15个被标识。
仔细观察RTP可以注意到它不像更低层的协议比如PDU一样,包含一个“定边界”的域。这一原因是RTP的有效负荷是跟IP的有效负荷相同,因此也就不需要了。
如果相同的用户在一个会话中使用多个媒体,比如说视频跟音频,每个媒体都会打开单独的RTP会话。因此在RTP层面上不存在多路复用。多路复用由更低层来决定。但是RTCP保留了一个叫CNAME的标识符,这个标识符对于由同一用户初始化的媒体是相同的。因此CNAME是在RTP层面上能识别从一个用户产生的不同媒体的唯一的标识符。
UDT(UDP-based Data Transfer Protocol)
基于UDP的数据传输协议(UDP-based Data Transfer Protocol,简称UDT)是一种互联网数据传输协议。UDT的主要目的是支持高速广域网上的海量数据传输,而互联网上的标准数据传输协议TCP在高带宽长距离网络上性能很差。 顾名思义,UDT建于UDP之上,并引入新的拥塞控制和数据可靠性控制机制。UDT是面向连接的双向的应用层协议。它同时支持可靠的数据流传输和部分可靠的数据报传输。 由于UDT完全在UDP上实现,它也可以应用在除了高速数据传输之外的其它应用领域,例如点到点技术(P2P),防火墙穿透,多媒体数据传输等等。
UDT是双工的,每个UDT实体有两个部分:发送和接收。发送者根据流量控制和速率控制来发送(和重传)应用程式数据。接收者接收数据包和控制包,并根据接收到的包发送控制包。发送和接收程式共享同一个UDP端口来发送和接收。
接收者也负责触发和处理任何的控制事件,包括拥塞控制和可靠性控制和他们的相对机制,例如RTT估计、带宽估计、应答和重传。
UDT总是试着将应用层数据打包成固定的大小,除非数据不够这么大。和TCP相似的是,这个固定的包大小叫做MSS(最大包大小)。由于期望UDT用来传输大块数据流,我们假定只有很小的一部分不规则的大小的包在UDT session中。MSS能够通过应用程式来安装,MTU是其最优值(包括任何包头)。
UDT拥塞控制算法将速率控制和窗口(流量控制)合并起来,前者调整包的发送周期,后者限制最大的位被应答的包。在速率控制中使用的参数通过带宽估计技术来更新,他继承来自基于接收的包方法。同时,速率控制周期是估计RTT的常量,流控制参数依赖于对方的数据到达速度,另外接收端释放的缓冲区的大小。
UDP构建可靠数据传输
简单来讲,要使用UDP来构建可靠的面向连接的数据传输,就要实现类似于TCP协议的超时重传,有序接受,应答确认,滑动窗口流量控制等机制,等于说要在传输层的上一层(或者直接在应用层)实现TCP协议的可靠数据传输机制,比如使用UDP数据包+序列号,UDP数据包+时间戳等方法,在服务器端进行应答确认机制,这样就会保证不可靠的UDP协议进行可靠的数据传输,不过这好像也是一个难题!