很抱歉也许是个愚蠢的问题,但是如何计算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%,它增加了,或者我在第一次尝试时犯了错误。 怎么做对了?
答案 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;
}
};