- 先创建节点
NodeContainer nodes ;
nodes.create(uint n);
或者nodes.add(Node xx / NodeContainer xx);
# 还有一些获取其中点的操作 like:
NodeContainer.Get(uint n);
- 然后自底向上创建 —— 先建立物理层
PointToPointHelper ppp; # 对应的还有CsmaHelper
#a 链路设置一些属性
ppp.SetDeviceAttribute( string Attr, Value );
ppp.SetChannelAttribute( string Attr, Value );
# Helper类的install操作都是连接两个层 , 然后会生成接口,这里就是netDevice
NetDeviceContainer device = ppp.install(nodes);
- 然后网络层和传输层都是InternetStackHelper创建的
InternetStackHelper stack;
#a 创建了Ipv4L4Protocol的两个子类(UdpL4Protocol和TCpL4Protocol)和Ipv4L3Protoco(Ipv4L3Protocol和Ipv6L3Protocol)
stack.install( NodeContainer or Node );
- 传输层和网络层的连接比较复杂,隐含在install()里面了 ,但是此时网络层和链路层并没有连接起来,还需要IpInterface与device进行绑定
#a Ipv4AddressHelper生成ip
Ipv4AddressHelper address;
address.SetBase ("10.1.1.0", "255.255.255.0");
#a 分配ip给devices会返回IpInterface 【ip是存储在interface的聚合数组里面(netDevice自己本身不存储信息),所以要网卡的ip得用interafce::GetAddress( int order) 】
Ipv4InterfaceContainer p2pInterfaces = address.Assign (p2pDevices);
- 再上面就是应用层了
- 如果不创建app,直接创建socket也可以。以udpsocket的创建过程为例子,这部分参考这个
先查看Socket::CreateSocket方法的代码:
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;
}
从上面的代码可以看出,以UdpSocketFactory的TypeId创建一个UdpSocketFactory对象,然后利用UdpSocketFactory对象的CreateSocket ()方法创建一个Socket对象。
但是,我们看UdpSocketFactory的源代码,发现:
namespace ns3 {
NS_OBJECT_ENSURE_REGISTERED (UdpSocketFactory);
TypeId UdpSocketFactory::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::UdpSocketFactory")
.SetParent<SocketFactory> ()
.SetGroupName ("Internet")
;
return tid;
}
}
UdpSocketFactory非常简单,并且是一个包含虚函数,不能创建对象。
此时就需要回到Socket::CreateSocket方法的代码:
Ptr<SocketFactory> socketFactory = node->GetObject<SocketFactory> (tid);
这一行代码返回的对象socketFactory 对象不是UdpSocketFactory对象,应该是它的子类对象或者父类对象,但是编程思想上看,父类对象基本不可能。只能是其子类对象。
UdpSocketFactory类的子类只有一个:UdpSocketFactoryImpl。【必定只有一个子类或者说只有一个子类对象 不然这么写的话 程序就分不清返回哪个子类对象了不是】
此时再看UdpSocketFactoryImpl的CreateSocket()方法:
Ptr<Socket>
UdpSocketFactoryImpl::CreateSocket (void)
{
NS_LOG_FUNCTION_NOARGS();
return m_udp->CreateSocket ();
}
其中的m_udp对象是Ptr,再看UdpL4Protocol的CreateSocket ():
Ptr<Socket>
UdpL4Protocol::CreateSocket (void)
{
NS_LOG_FUNCTION_NOARGS ();
Ptr<UdpSocketImpl> socket = CreateObject<UdpSocketImpl> ();
socket->SetNode (m_node);
socket->SetUdp (this);
m_sockets.push_back (socket);
return socket;
}
看到这个代码就知道了,UdpSocketFactory的实现类UdpSocketFactoryImpl利用UdpL4Protocol对象来创建Socket对象。而UdpL4Protocol对象的CreateSocket 方法通过创建UdpSocket的实现类UdpSocketImpl来创建socket,并返回。
也就是说,最终创建的socket对象是UdpSocketImpl类型的。