如何获取Header 数据
根据list of TraceSources,与QueueDiscItems 关联的TraceSources 用于队列。我猜您正试图附加到其中一个 TraceSource。
QueueDiscItem 封装了几样东西:Ptr<Packet>、MAC 地址和更多东西。由于您使用的是 IPv4,因此 QueueDiscItem 实际上是 Ipv4QueueDiscItem (后者是前者的子类)。所以,让我们首先将QueueDiscItem 转换为Ipv4QueueDiscItem by
Ptr<const Ipv4QueueDiscItem> ipItem = DynamicCast<const Ipv4QueueDiscItem>(item);
接下来,您需要知道在模拟的这一点上,Ipv4Header还没有添加到Ptr<Packet>。这可能是一个设计选择(我不明白)。那么,我们怎样才能得到这些信息呢?好吧,Ipv4QueueDiscItem 封装了Ipv4Header,并且在将Ptr<Packet> 传递到 L2 之前的某个时间点,将标头添加到数据包中。这个Header可以通过
检索
const Ipv4Header ipHeader = ipItem->GetHeader();
所以,现在我们有了您感兴趣的数据包的Ipv4Header。现在,我们可以安全地从Ipv4QueueDiscItem 中获取地址
ipHeader.GetSource();
ipHeader.GetDestination();
总而言之,您的 TraceSource 函数应如下所示:
void
EnqueueTrace (Ptr<const QueueDiscItem> item) {
Ptr<const Ipv4QueueDiscItem> ipItem = DynamicCast<const Ipv4QueueDiscItem>(item);
const Ipv4Header ipHeader = ipItem->GetHeader();
NS_LOG_UNCOND("Packet received at " << Simulator::Now() << " going from " << ipHeader.GetSource() << " to " << ipHeader.GetDestination());
}
为什么item->Print(std::cout); 有效?
以上都说得通,但是为什么
item->Print(std::cout);
打印正确的地址?首先,重要的是要认识到这里Print() 是QueueDiscItem 的函数,而不是Packet。如果我们去这个函数的the source,我们发现Print()只是打印Header如果它已经被添加了。