您的位置:首页 > 其它

蔡军生先生第二人生的源码分析(二十七)发送数据的流量控制

2008-05-17 15:02 681 查看
网络的带宽,目前来说已经变得很大了,但那是相对以前的网络来说的。对于需求流量越来越大,传送的数据越来越多来说,远远不能满足现实的需要。在有限的带宽里,总有一些信息比较重要,有一些信息次要的,面对这样的需求,就需要把重要的信息能按时发送出去,而次要的信息延时发送。因此,就需要引入流量控制的机制。下面就来分析一下第二人生发送数据的流量控制方式。

#001 BOOL LLPacketRing::sendPacket(int h_socket, char * send_buffer, S32 buf_size, LLHost host)
#002 {
#003 BOOL status = TRUE;
#004 if (!mUseOutThrottle)
#005 {
#006 return send_packet(h_socket, send_buffer, buf_size, host.getAddress(), host.getPort() );
#007 }
#008 else
#009 {
#010 mActualBitsOut += buf_size * 8;
#011 LLPacketBuffer *packetp = NULL;
#012 // See if we've got enough throttle to send a packet.
#013 while (!mOutThrottle.checkOverflow(0.f))
#014 {
#015 // While we have enough bandwidth, send a packet from the queue or the current packet
#016
#017 S32 packet_size = 0;
#018 if (!mSendQueue.empty())
#019 {
#020 // Send a packet off of the queue
#021 LLPacketBuffer *packetp = mSendQueue.front();
#022 mSendQueue.pop();
#023
#024 mOutBufferLength -= packetp->getSize();
#025 packet_size = packetp->getSize();
#026
#027 status = send_packet(h_socket, packetp->getData(), packet_size, packetp->getHost().getAddress(), packetp->getHost
#028 ().getPort());
#029
#030 delete packetp;
#031 // Update the throttle
#032 mOutThrottle.throttleOverflow(packet_size * 8.f);
#033 }
#034 else
#035 {
#036 // If the queue's empty, we can just send this packet right away.
#037 status = send_packet(h_socket, send_buffer, buf_size, host.getAddress(), host.getPort() );
#038 packet_size = buf_size;
#039
#040 // Update the throttle
#041 mOutThrottle.throttleOverflow(packet_size * 8.f);
#042
#043 // This was the packet we're sending now, there are no other packets
#044 // that we need to send
#045 return status;
#046 }
#047
#048 }
#049
#050 // We haven't sent the incoming packet, add it to the queue
#051 if (mOutBufferLength + buf_size > mMaxBufferLength)
#052 {
#053 // Nuke this packet, we overflowed the buffer.
#054 // Toss it.
#055 llwarns << "Throwing away outbound packet, overflowing buffer" << llendl;
#056 }
#057 else
#058 {
#059 static LLTimer queue_timer;
#060 if ((mOutBufferLength > 4192) && queue_timer.getElapsedTimeF32() > 1.f)
#061 {
#062 // Add it to the queue
#063 llinfos << "Outbound packet queue " << mOutBufferLength << " bytes" << llendl;
#064 queue_timer.reset();
#065 }
#066 packetp = new LLPacketBuffer(host, send_buffer, buf_size);
#067
#068 mOutBufferLength += packetp->getSize();
#069 mSendQueue.push(packetp);
#070 }
#071 }
#072
#073 return status;
#074 }

通过类成员mUseOutThrottle来判断是否发送流量控制,如果需要控制流量,就调用mOutThrottle.checkOverflow来判断是否可以发送数据。如果可以发送数据,就先把队列里的数据发送出去,再发送当前需要发送的数据。如果数据不能发送出去,就把要发送的数据添加队列mSendQueue里。通过这样的方式,就可以把数据按流量控制的方式平稳地发送出去,而不占用过多的网络带宽,不影响其它应用程序的使用。



蔡军生 2008/3/27 QQ:9073204 深圳
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐