在UDP可靠传输领域,能与UDX比较的协议,目前应该只有VTCP。
今天我们谈一下各种协议的缓冲问题。
滑动窗口算法,是比较重要的算法。
窗口越大,那么可以一次性提交的数据量就会越大,可以在网络中漂流的数据量也越大,意味着吞吐量越大。
UDX支持从8KB~16M的缓冲,VTCP是8K~4MB截止本文目前为止。如果以RTT = 100ms的网络,最大吞吐量,理论值分别是16M * 1000/100 = 160MB,和40MB.这里只是理论值,最大为多少,要看具体的环境,因为影响吞吐量除了延迟,还有丢包。
那是不是窗口越大越好呢?显然不是。对于不同的应用,缓冲的设置是完全不同的,比如传输文件,可以有较大的传输窗口,而象视频,语音就不能有较大的缓冲,缓冲过大意味着当有丢包时,延迟也就越大,我们如果能控制合理的缓冲,不光可以克服丢包引起的解码问题,还可以提高用户体验及实时性。
今天,我就UDX协议在编程时对缓冲设计上,进行限制。
UDX协议控制缓冲的机制,和底层协议实现有很大关系,UDX协议,实现的原则是 发送的内容和接收的内容完全一致原则,每成功发送一次,必会通知应用发送完成。什么意思呢?用户可以这样操作,发送一个100KB的数据包,比如Udx.SendBuff(100KB),接收方触发接收事件OnStreamRead(pData,100KB)的时候,pData的内容完全和你调用发送时一样,而发送方会收到OnStreamWrite(pData,100KB)的发送成功的通知,一一对应关系。这样的好处是,用户只用关心自己的业务不用关心网络底层的分包,组包。
比如,用户发送自己的协议数据,数据结构,图片等,可以完全直接强制转化为发送内容。这对复杂的业务来说,是非常有用的功能,使开发人员只用关心自己的业务功能,定制功能即可。
由于有以上的机制,那么, 我们就可以控制这个,缓冲长度了。我们可以这样理解,调用SendBuff成功后,可以理解为,用户已经将数据拷贝给UDX缓冲,而还没有到达用户端,停留在网络上的数据量,这个量为多大就是我们设置的缓冲了。如何控制这个长度就是我们今天要说的问题。
我们可以这样解决,我们设置两个变量,用来分别统计发送的长度,和通知完成的长度。这里有两个分支方法,你可以通过调用次数来统计,也可以用发送的长度来统计,前者粗略一点,后者更精确一点。
我们先以简单的发送个数来统计。
如以下代码
if(udx.SendBuff(data,len)
{
m_sendcount ++;
m_sendsize += len;
}
在onstreamwrite事件中
void CP2pVideoClientDlg::OnStreamWrite(IUdxTcp * pTcp,BYTE* pData,int len)
{
m_sendcountack ++;
m_sendsizeack += len;
}
那么,缓冲长度控制可以这样写
int dcount = m_sendcount - m_sendcountack;
int dsize = m_sendsize - m_sendsizeack;
if(dcount > 30)//一般在视频中,30侦意味着是1秒,这样无论是多大或多小的尺寸中,都表示1秒的缓冲
{ //停止发送,等网络恢复
return;
}
if(udx.SendBuff(data,len))
{
m_sendcount ++;
m_sendsize += len;
}
同理,用长度精确控制代码与上面差不多,大家可以自己发挥。