假设数据包不重复,能够容忍一定程度的失序。一个适用于UDP的传输场景,周期性统计数据包的丢包率。若上个周期统计的丢失包在本周期中到来,不对这些数据包进行统计。
其中,capacity表示一轮中数据包的个数,比如,数据包序号可以取值0-29,capacity就是30;若数据包序号可以取值0-65535,capacity就是65536.
/*
*author zsy
*stat packets loss in network
*handle out of order packets
*/
#include<iostream>
#include<stdio.h>
#include<stdbool.h>
class PacketLoss
{
public:
PacketLoss(uint64_t start_seq,uint64_t capacity);
~PacketLoss(){}
void IncomingPacket(uint64_t seq);
float GetLossRate();
void Reset();
private:
uint64_t min_seq_;
uint64_t max_seq_;
uint64_t total_packet_;
float loss_rate_;
uint64_t capacity_;
bool first_;//
};
PacketLoss::PacketLoss(uint64_t start_seq,uint64_t capacity)
{
min_seq_=start_seq;
max_seq_=start_seq;
total_packet_=0;
loss_rate_=0.0;
capacity_=capacity;
first_=true;
}
void PacketLoss::IncomingPacket(uint64_t seq)
{
if(first_&&seq==0)
{
total_packet_++;//packet seq 0;
}
if(seq>max_seq_)
{
if(seq-max_seq_>capacity_/2)
{
}else{
max_seq_=seq;
printf("mark%d\n",seq);
}
}
if(seq<max_seq_)
{
if(max_seq_-seq>capacity_/2)
{
max_seq_=seq;
}
}
if(seq>min_seq_)
{
if(seq-min_seq_>capacity_/2)
{
//receive packets belongs to last round;
}else{
total_packet_++;
}
}
if(seq<min_seq_)
{
if(min_seq_-seq>capacity_/2)
{
total_packet_++;
}
}
}
float PacketLoss::GetLossRate()
{
float range=0.0;
if(max_seq_>min_seq_)
{
printf("%d\n",max_seq_-min_seq_);
printf("fuck %llu,%llu,%llu\n",min_seq_,max_seq_,total_packet_);
range=max_seq_-min_seq_;
if(first_)
{
loss_rate_=(range+1-total_packet_)/(range+1);
}else
{
loss_rate_=(range-total_packet_)/range;
}
}
if((max_seq_<min_seq_)&&(min_seq_-max_seq_)>capacity_/2)
{
printf("%llu,%llu,%llu\n",min_seq_,max_seq_,total_packet_);
range=capacity_-min_seq_+max_seq_;
loss_rate_=(range-total_packet_)/range;
}
return loss_rate_;
}
void PacketLoss::Reset()
{
total_packet_=0;
min_seq_=max_seq_;
first_=false;
}
int main()
{
uint64_t array[10]={0,1,2,5,6,7,3,8,9,10};
PacketLoss packetloss(0,30);
int i=0;
for(i=0;i<10;i++)
{
packetloss.IncomingPacket(array[i]);//0 as marker
}
printf("loss rate %f\n",packetloss.GetLossRate());
packetloss.Reset();
uint64_t array1[10]={11,13,12,15,19,17,18,16,20,22};
for(i=0;i<10;i++)
{
packetloss.IncomingPacket(array1[i]);//0 as marker
}
printf("loss rate %f\n",packetloss.GetLossRate());
uint64_t array2[10]={14,21,23,24,29,25,26,0,1,2};
packetloss.Reset();
for(i=0;i<10;i++)
{
packetloss.IncomingPacket(array2[i]);//0 as marker
}
printf("loss rate %f\n",packetloss.GetLossRate());
}