本篇主要记录,在阅读源程序的过程中,一个困惑我的地方,什么时候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的调用过程