ns-3_ Day 5
理解ns-3的网络模拟方法:离散事件
还是以first.cc中的PPP网络为例。
一个分组从n0到n1的过程可以理解成:
- T1:n0开始向信道发送分组(第一个字节)。
- T2:分组的最后一个字节被发送,网络设备释放。
- T3:分组被n1接收(事实上没有考虑n1的传输延迟,也就是只考虑n1完全接收分组的时刻)。
可以看出,T2-T1就是传输延迟,T3-T2就是传播延迟。
ns-3不关注过程,仅关注事件发生的时刻。因此上述过程在ns-3的眼里就是3个事件:
- 事件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; }
- 事件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); }
- 事件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.cc
和src/point-to-point/model/point-to-point-channel.cc
在更复杂的场景下,同一时间会有多个节点争夺信道资源,需要更多计划事件操作和状态变量。
posted on 2023-01-08 10:33 LeewayTang 阅读(88) 评论(0) 编辑 收藏 举报
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本