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

网络的带宽,目前来说已经变得很大了,但那是相对以前的网络来说的。对于需求流量越来越大,传送的数据越来越多来说,远远不能满足现实的需要。在有限的带宽里,总有一些信息比较重要,有一些信息次要的,面对这样的需求,就需要把重要的信息能按时发送出去,而次要的信息延时发送。因此,就需要引入流量控制的机制。下面就来分析一下第二人生发送数据的流量控制方式。
 
#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 深圳
 
posted @ 2008-03-27 22:23  ajuanabc  阅读(123)  评论(0编辑  收藏  举报