ns-3_ Day 5

理解ns-3的网络模拟方法:离散事件

还是以first.cc中的PPP网络为例。
一个分组从n0到n1的过程可以理解成:
image.png

  • T1:n0开始向信道发送分组(第一个字节)。
  • T2:分组的最后一个字节被发送,网络设备释放。
  • T3:分组被n1接收(事实上没有考虑n1的传输延迟,也就是只考虑n1完全接收分组的时刻)。

可以看出,T2-T1就是传输延迟,T3-T2就是传播延迟。
ns-3不关注过程,仅关注事件发生的时刻。因此上述过程在ns-3的眼里就是3个事件:

  1. 事件T1:n0发送分组。注意代码并不模拟逐字节发送的过程,而是认为n0一次性将整个分组发送给PPP信道,并锁定网络设备。然后,n0计划一个新事件T2。计划事件用的就是Simulator::Schedule函数。
bool PointToPointNetDevice::TransmitStart (Ptr<Packet> p)
{
NS_LOG_FUNCTION (this << p);
NS_LOG_LOGIC ("UID is " << p->GetUid () << ")");
NS_ASSERT_MSG (m_txMachineState == READY, "Must be READY to transmit");
//锁定网络设备
m_txMachineState = BUSY;
m_currentPkt = p;
m_phyTxBeginTrace (m_currentPkt);
Time txTime = m_bps.CalculateBytesTxTime (p->GetSize ());
Time txCompleteTime = txTime + m_tInterframeGap;
NS_LOG_LOGIC ("Schedule TransmitCompleteEvent in " << txCompleteTime.GetSeconds () << "sec");
//计划事件T2
Simulator::Schedule (txCompleteTime, &PointToPointNetDevice::TransmitComplete, this);
//将分组一次性转交给信道
bool result = m_channel->TransmitStart (p, this, txTime);
if (result == false)
{
m_phyTxDropTrace (p);
}
return result;
}
  1. 事件T2:解锁网络设备,因为分组已经发送完毕。
void PointToPointNetDevice::TransmitComplete (void)
{
NS_LOG_FUNCTION (this);
NS_ASSERT_MSG (m_txMachineState == BUSY, "Must be BUSY if transmitting");
//解锁网络设备
m_txMachineState = READY;
NS_ASSERT_MSG (m_currentPkt != 0, "PointToPointNetDevice::TransmitComplete(): m_currentPkt zero");
m_phyTxEndTrace (m_currentPkt);
m_currentPkt = 0;
Ptr<Packet> p = m_queue->Dequeue ();
if (p == 0)
{
NS_LOG_LOGIC ("No pending packets in device queue after tx complete");
return;
}
m_snifferTrace (p);
m_promiscSnifferTrace (p);
TransmitStart (p);
}
  1. 事件T3:PPP信道把分组转交给n1
bool PointToPointChannel::TransmitStart (Ptr<const Packet> p,Ptr<PointToPointNetDevice> src,Time txTime)
{
NS_LOG_FUNCTION (this << p << src);
NS_LOG_LOGIC ("UID is " << p->GetUid () << ")");
NS_ASSERT (m_link[0].m_state != INITIALIZING);
NS_ASSERT (m_link[1].m_state != INITIALIZING);
uint32_t wire = src == m_link[0].m_src ? 0 : 1;
//计划分组接收事件
Simulator::ScheduleWithContext (m_link[wire].m_dst->GetNode ()->GetId (), txTime + m_delay, &PointToPointNetDevice::Receive, m_link[wire].m_dst, p->Copy ());
m_txrxPointToPoint (p, src, m_link[wire].m_dst, txTime, txTime + m_delay);
return true;
}

ns-3按顺序执行上述事件,事件之间并没有时间间隔而是立刻发生。具体的代码参见src/point-to-point/model/point-to-point-net-device.ccsrc/point-to-point/model/point-to-point-channel.cc
在更复杂的场景下,同一时间会有多个节点争夺信道资源,需要更多计划事件操作和状态变量。

posted on   LeewayTang  阅读(88)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示