每秒字符数,KBps,每秒Kilo [位/字节],(计算机网络),计算权如何

时间:2011-06-11 08:52:13

标签: c++ networking network-programming

很抱歉也许是个愚蠢的问题,但是如何计算Kbps / ...(每秒千比特,每秒千字节)? 我现在有这样的计算:

DWORD ibytesin=0,ibytes_sttime=0,ibytes_st=0,ibps=0,ilastlen;
DWORD obytesin=0,obytes_sttime=0,obytes_st=0,obps=0,olastlen;

ibytesin - 所有时间的总字节数;

ibytes_sttime - 分配启动ibytes_st的时间;

ibytes_st - ibytes_sttime时的字节数;

ibps - kbps / bps /...;

ilastlen - 为了更准确,因为我的协议使用请求数据包,我不想采取最后的长度;

与流量相同的规则(o *)。

第一次收获,例如以字节为单位:

len = recv(ConnectSocket, (char*)p, readleft, 0);
if(len>0) {
    ibytesin+=len;
    ilastlen=len;
}

同样的。

然后在一些经常执行的快速执行的地方,例如:stats thread:

if ((GetTickCount() - obytes_sttime) >= 1000) // update once per second
{
    obps = (obytesin-obytes_st-olastlen) / 1024 * 8;
    obytes_sttime = GetTickCount();
    obytes_st = obytesin;
    olastlen=0;
}

if ((GetTickCount() - ibytes_sttime) >= 1000) // update once per second
{
    ibps = (ibytesin-ibytes_st-ilastlen) / 1024* 8; // get kilobytes*8 == Kbps ?
    ibytes_sttime = GetTickCount();
    ibytes_st = ibytesin;
    ilastlen=0;
}

sprintf(str, "In/Out %3d / %-3d Kbps/сек", ibps,obps);

当我尝试增加更新bps节目时,我的速度是错误的。例如,我想每100毫秒重新计算一次,而不是1秒,所以我可以想象我需要将ibps除以1024而不是1024(因为1000/10 = 100,所以1024/10 = 102.4),但是速度没有正确计算100%,它增加了,或者我在第一次尝试时犯了错误。 怎么做对了?

1 个答案:

答案 0 :(得分:1)

塞吉,

我假设您的计数器不必精确到任何特定的公差或标准。并且您只想定期显示“运行平均值”。如果是这种情况,你可以使用下面我的“计数器”类,我从之前编写的一些代码中加入了其他代码。它只是每隔几秒重新计算一次“速率”。

创建“Counter”的实例。在recv函数之后,使用接收的字节数调用“Increment”。然后只要你想打印平均值就调用Counter :: GetRate。 (将结果除以1024并乘以8以将“每秒字节数”转换为“kbps”。)

您会注意到每两秒(而不是每一秒)重新计算“每秒平均N”。您可以更改此设置,但我发现保持移动平均值一次稳定2秒会产生“更平滑”的结果,因为当计数出现差异时,计数器打印输出不会显得不稳定。如果你想要一个更接近“在最后一秒收到多少kbits”的计数,那么调用counter.SetInterval(1000)。我想你可以将间隔设置为100。由于网络抖动,你会得到更不稳定的结果。

class Counter
{

    static const DWORD DEFAULT_INTERVAL = 2000; // 2000ms = 2 seconds
    bool m_fFirst;
    DWORD m_dwInterval;  // how often we recompute the average
    DWORD m_dwCount;
    DWORD m_dwStartTime;
    DWORD m_dwComputedRate;

public:
    Counter()
    {
        Reset();
        m_dwInterval = DEFRAULT_INTERVAL;
    }



    void Reset()
    {
        m_dwFrames = 0;
        m_dwStartTime = 0;
        m_dwComputedRate = 0;
        m_fFirst = true;
    }



    void Increment(DWORD dwIncrement)
    {
        DWORD dwCurrentTime = GetTickCount();
        DWORD dwActualInterval = dwCurrentTime - m_dwStartTime;

        if (m_fFirst)
        {
            m_dwStartTime = dwCurrentTime;
            m_fFirst = false;
        }
        else
        {

            m_dwCount += dwIncrement;

            if (dwActualInterval >= m_dwInterval)
            {
                // "round up" by adding 500 to the formula below
                 // that way a computed average of "234.56" gets rounded up to "235" 
                 // instead of "rounded down" to 234
                 const DWORD ROUND_UP = 500;
                 // multiply by 1000 to convert from milliseconds to seconds
                 m_dwComputedRate = (m_dwCount * 1000 + ROUND_UP) / dwActualInterval; 

                 // reset counting
                 m_dwStartTime = dwCurrentTime;
                 m_dwCount = 0;
            }
        }
    }


    // returns rate in terms of "per second"

    DWORD GetRate()
    {
        return m_dwComputedRate;
    }


    void SetInterval(DWORD dwInterval)
    {
        m_dwInterval = dwInterval;
    }
};