ns3可以根据数据包的序列号自己统计丢包,统计方法如下:

发送端

//添加头文件
#include "ns3/packet-loss-counter.h"
//在生成数据包时,添加包头
  SeqTsHeader seqTs;
  seqTs.SetSeq (m_sent);
  Ptr<Packet> p = Create<Packet> (m_size-(8+4)); // 8+4 : the size of the seqTs header
  p->AddHeader (seqTs);

接收端

//添加头文件
#include "ns3/packet-loss-counter.h"

//定义全局变量
PacketLossCounter m_lossCounter; //!< Lost packet counter

//收到数据包后,读取包头标号
SeqTsHeader seqTs;
packet->RemoveHeader (seqTs);
uint32_t currentSequenceNumber = seqTs.GetSeq (); //记录数据包序号
m_lossCounter.NotifyReceived (currentSequenceNumber);

//结束运行时
 std::cout << "Total number of Packet lossed " << m_lossCounter.GetLost() << std::endl;

不过这种方法有个缺点,就是m_lossCounter只记录到目前为止接受序列中断层数据包,比如你发了五个数据包,收到的序列为0 1 2 4,那么显示丢包数为1,如果收到的序列为0 1 2 3,则不显示丢包。如果你要显示这类数据包的丢包数据的话,可以这样:

非断层丢包统计

大致思路是定义队列丢包为TraceSources,一旦发生丢包,就回调统计函数,进行丢包统计

//在main函数前定义全局变量及函数
uint32_t		i = 0; //定义丢包数变量
static void DropCounter(Ptr<const QueueDiscItem> queue)
{
  i++;
  std::cout << "Total Drop Packet: "<<  i << " at " <<  Simulator::Now ().GetSeconds () << " " <<std::endl;
}

//在main函数中,丢包回调丢包统计函数
//不过需要提前知道在那个节点上产生丢包
Config::ConnectWithoutContext ("/NodeList/0/$ns3::TrafficControlLayer/RootQueueDiscList/0/Drop", MakeCallback(&DropCounter));

不过这种方法需要知道在哪个节点上丢包的,当然也可也可以直接把上面语句中的

/NodeList/0/$ns3::TrafficControlLayer/RootQueueDiscList/0/Drop
替换为:
/NodeList/*/$ns3::TrafficControlLayer/RootQueueDiscList/*/Drop
输出全部节点由于流控产生丢包的数据包数量

如要查看哪个节点丢包的话也可以在这里看

//在脚本里添加这句话
CommandLine cmd;
cmd.Parse(argc, argv);    

//运行时
./waf --run scratch/filename --vis

出现图形化界面后,右键点击"show interface statistics"

深度学习 通信丢包率预测 统计丢包率_深度学习 通信丢包率预测


如果收包和发包数不匹配就说明丢包了。

但是比较麻烦的地方在于,丢包的原因有很多,比如物理层、数据链路层、网络层等等,不同的原因都有不一样的tracesources,这种方法你就需要查明丢包是由于何种原因,在根据该原因修改tracesources来进行回调,具体的tracesource可以查看:
https://www.nsnam.org/doxygen/_trace_source_list.html 选择你想要trace 的丢包原因,点进去后,在页面搜索“Config Paths”就会有对应的路径

如果有不对的地方,别骂别骂…

以上,顺心顺意~!!!