ns3 拓扑和基本功能构建过程演示

  • 先创建节点
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类型的

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值