ns3源码阅读(一)UdpSocketFactory的创建

 本篇主要记录,在阅读源程序的过程中,一个困惑我的地方,什么时候Node通过函数AggregateObject注册了ns3::UdpSocketFactory对象。在代码分析中,只摘取与流程分析相关的代码。
 主代码为/ns-allinone-3.28/ns-3.28/examples/udp/udp-echo.cc

  NodeContainer n;
  n.Create (4);

  InternetStackHelper internet;
  internet.Install (n);//(1)


  UdpEchoClientHelper client (serverAddress, port);
  client.SetAttribute ("MaxPackets", UintegerValue (maxPacketCount));
  client.SetAttribute ("Interval", TimeValue (interPacketInterval));
  client.SetAttribute ("PacketSize", UintegerValue (packetSize));
  apps = client.Install (n.Get (0));
  apps.Start (Seconds (2.0));//(2)

 在上一篇中[2],打印出了调用函数(1)之后,Node中注册的对象。可以看到ns3::UdpSocketFactory赫然在列。追踪下这个对象是何时创建的。
 /ns-allinone-3.28/ns-3.28/src/internet/helper/internet-stack-helper.cc?line=292(函数在相应文件中第292行)。

void
InternetStackHelper::Install (Ptr node) const
{
CreateAndAggregateObjectFromTypeId (node, "ns3::UdpL4Protocol");//line=349
}

 一个新的对象通过函数CreateAndAggregateObjectFromTypeId创建。在函数中调用了node->AggregateObject。

void
InternetStackHelper::CreateAndAggregateObjectFromTypeId (Ptr node, const std::string typeId)
{
  ObjectFactory factory;
  factory.SetTypeId (typeId);
  Ptr<Object> protocol = factory.Create <Object> ();
  node->AggregateObject (protocol);
}

 /ns-allinone-3.28/ns-3.28/src/core/model/object.cc?line=252。AggregateObject会调用对象中的NotifyNewAggregate函数。

void 
Object::AggregateObject (Ptr<Object> o)
{
  for (uint32_t i = 0; i < n; i++)
    {
      Object *current = aggregates->buffer[i];
      current->m_aggregates = aggregates;
    }
  for (uint32_t i = 0; i < b->n; i++)
    {
      Object *current = b->buffer[i];
      current->NotifyNewAggregate ();
    }
}

 /ns-allinone-3.28/ns-3.28/src/internet/model/udp-l4-protocol.cc?line=90中的NotifyNewAggregate创建了UdpSocketFactoryImpl。

void
UdpL4Protocol::NotifyNewAggregate ()
{
          this->SetNode (node);
          Ptr<UdpSocketFactoryImpl> udpFactory = CreateObject<UdpSocketFactoryImpl> ();
          udpFactory->SetUdp (this);
          node->AggregateObject (udpFactory);
}

 UdpSocketFactoryImp即UdpSocketFactory的实现。也就是在这里创建了UdpSocketFactoryImp,并AggregateObject到Node节点中。
 再次翻到主函数中的标号(2)的代码,启动相应的Application。/ns-allinone-3.28/ns-3.28/src/applications/model/udp-echo-client.cc?line=120。

void 
UdpEchoClient::StartApplication (void)
{
  if (m_socket == 0)
    {
      TypeId tid = TypeId::LookupByName ("ns3::UdpSocketFactory");
      m_socket = Socket::CreateSocket (GetNode (), tid);
      }
}

 创建Socket对象。/ns-allinone-3.28/ns-3.28/src/network/model/socket.cc,根据tid参数,确保拿到的对象为UdpSocketFactory。

Ptr<Socket> 
Socket::CreateSocket (Ptr<Node> node, TypeId tid)
{
  NS_LOG_FUNCTION (node << tid);
  Ptr<Socket> s;
  NS_ASSERT (node != 0);
  Ptr<SocketFactory> socketFactory = node->GetObject<SocketFactory> (tid);
  NS_ASSERT (socketFactory != 0);
  s = socketFactory->CreateSocket ();
  NS_ASSERT (s != 0);
  return s;
}

 /ns-allinone-3.28/ns-3.28/src/internet/model/udp-socket-factory-impl.cc?line=42。这里m_udp为UdpL4Protocol对象。

Ptr<Socket>
UdpSocketFactoryImpl::CreateSocket (void)
{
  return m_udp->CreateSocket ();
}

 UdpL4Protocol对象创建Socket对象。

Ptr
UdpL4Protocol::CreateSocket (void)
{
  NS_LOG_FUNCTION_NOARGS ();
  Ptr socket = CreateObject ();
  socket->SetNode (m_node);
  socket->SetUdp (this);
  m_sockets.push_back (socket);
  return socket;
}

 接下来就可以大致分析下Packet是怎样发送的,参看[1]。
 这是这几天来困惑我的地方,其实也就是数据包的发送问题。
[1]NS3 WiFi环境中Socket发送Packet的过程
[2]ns3程序运行
[3]NS3 WiFi环境中Packet从Socket到NetDevice的调用过程

你可能感兴趣的:(仿真,ns3,仿真)