您的位置:首页 > 其它

第二人生的源码分析(三十一)接收数据的流量控制

2008-04-08 21:52 567 查看
数据接收回来后,本来就应立即处理掉,这样是比较简单的想法。但由于网络带宽有限,这时就需要限制UDP接收数据的速度。下面就来分析这种需求的实现,它的代码如下:
#001 S32 LLPacketRing::receivePacket (S32 socket, char *datap)
#002 {
#003 S32 packet_size = 0;
#004

下面判断是否使用接收的流量限制。
#005 // If using the throttle, simulate a limited size input buffer.
#006 if (mUseInThrottle)
#007 {
#008 BOOL done = FALSE;
#009
#010 // push any current net packet (if any) onto delay ring
下面开始循环地接收数据,并且判断是否到达流量的最大值。
#011 while (!done)
#012 {
#013 LLPacketBuffer *packetp;
#014 packetp = new LLPacketBuffer(socket);
#015
上面创建LLPacketBuffer对象来接收数据。

#016 if (packetp->getSize())
#017 {
#018 mActualBitsIn += packetp->getSize() * 8;
#019
#020 // Fake packet loss
#021 if (mDropPercentage && (ll_frand(100.f) < mDropPercentage))
#022 {
#023 mPacketsToDrop++;
#024 }
#025
#026 if (mPacketsToDrop)
#027 {
#028 delete packetp;
#029 packetp = NULL;
#030 packet_size = 0;
#031 mPacketsToDrop--;
#032 }
#033 }
上面的代码计算流量mActualBitsIn的大小,并判断mDropPercentage是否需要把接收到的数据包丢掉。

#034
#035 // If we faked packet loss, then we don't have a packet
#036 // to use for buffer overflow testing
#037 if (packetp)
#038 {
#039 if (mInBufferLength + packetp->getSize() > mMaxBufferLength)
#040 {
#041 // Toss it.
#042 llwarns << "Throwing away packet, overflowing buffer" << llendl;
#043 delete packetp;
#044 packetp = NULL;
这里接收到的数据大于缓冲区长度,所以要把数据丢掉。

#045 }
#046 else if (packetp->getSize())
#047 {
#048 mReceiveQueue.push(packetp);
#049 mInBufferLength += packetp->getSize();
这里把最后接收到数据保存到缓冲区后面。

#050 }
#051 else
#052 {
#053 delete packetp;
#054 packetp = NULL;
#055 done = true;
这是没有数据接收到就退出处理。

#056 }
#057 }
#058 else
#059 {
#060 // No packetp, keep going? - no packetp == faked packet loss
#061 }
#062 }
#063
#064 // Now, grab data off of the receive queue according to our
#065 // throttled bandwidth settings.
#066 packet_size = receiveFromRing(socket, datap);
上面从数据接收缓冲区里返回一个可用的数据包给上一层调用者。

#067 }
#068 else
#069 {

下面是没有接收流量限制的处理,相对来说是比较简单的。
#070 // no delay, pull straight from net
#071 packet_size = receive_packet(socket, datap);
#072 mLastSender = ::get_sender();
#073
#074 if (packet_size) // did we actually get a packet?
#075 {
#076 if (mDropPercentage && (ll_frand(100.f) < mDropPercentage))
#077 {
#078 mPacketsToDrop++;
#079 }
#080
#081 if (mPacketsToDrop)
#082 {
#083 packet_size = 0;
#084 mPacketsToDrop--;
#085 }
#086 }
#087 }
#088
#089 return packet_size;
#090 }

通过上面的代码,可以学习到接收流量的限制方法是先把接收到数据计算出流量来,然后根据流量来丢掉后面的数据包。因此中间就需要一个中间缓冲区来保存缓冲的数据,方便计算流量。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐