大坡3D软件开发

关注3D软件技术

用户操作
[即时聊天] [发私信] [加为好友]
蔡军生ID:caimouse
1235000次访问,排名17好友254人,关注者406
C++,3D,VC++软件开发,写技术文章,操作系统开发
caimouse的文章
原创 602 篇
翻译 0 篇
转载 41 篇
评论 940 篇
蔡军生的公告

点击这里给我发消息

MSN: caimouse1976 at sina.com

最近评论
xavierye:发现另外一个源码分析blog,可以和楼主的一起看:
http://www.cnblogs.com/duguguiyu/archive/2008/10/02/1303095.html
xavierye:发现另外一个源码分析blog:
http://www.cnblogs.com/duguguiyu/archive/2008/10/02/1303095.html
shada:前面两个混帐,没资格评论开源。
用着盗版的Word写文章批评开源的人真不少。
shada:前面两个混帐,没资格评论开源。
用着盗版的Word写文章批评开源的人大有人在。
andylrj:Google的浏览器真差劲!!!体验一把真心说出,要做的事还很多,终于明白微软的IE为什么要做这么庞大了,做小确实不行!
文章分类
收藏
相册
3D引擎
第二人生
谷歌浏览器
开发板
历史回忆
常用连接
人生历程
存档
软件项目交易
订阅我的博客
XML聚合  FeedSky

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

新一篇: 第二人生的源码分析(三十二)消息解包的实现 | 旧一篇: 第二人生的源码分析(三十)UDP接收数据和Windows网络关闭

数据接收回来后,本来就应立即处理掉,这样是比较简单的想法。但由于网络带宽有限,这时就需要限制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 }
 
通过上面的代码,可以学习到接收流量的限制方法是先把接收到数据计算出流量来,然后根据流量来丢掉后面的数据包。因此中间就需要一个中间缓冲区来保存缓冲的数据,方便计算流量。 

发表于 @ 2008年04月08日 21:52:00|评论(loading...)|编辑

新一篇: 第二人生的源码分析(三十二)消息解包的实现 | 旧一篇: 第二人生的源码分析(三十)UDP接收数据和Windows网络关闭

评论

#netatrs 发表于2008-04-10 20:46:10  IP: 218.199.25.*
谢谢哦
#xmhero 发表于2008-04-11 02:17:25  IP: 220.160.180.*
谢谢哦
发表评论  


当前用户设置只有注册用户才能发表评论。如果你没有登录,请点击登录
Csdn Blog version 3.1a
Copyright © 蔡军生