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