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 阅读(125) 评论(0) 收藏 举报
浙公网安备 33010602011771号