文章目录
1.创建节点:NodeContainer
创建两个 ns-3 节点 对象,代表仿真中的计算机
NodeContainer nodes;
//创建n个 ns-3 节点 对象,代表仿真中的计算机
nodes.Create (uint n);
nodes.add(Node xx / NodeContainer xx);
NodeContainer.Get(uint n);
2.建立物理层PointToPointHelper
自底向上创建 —— 先建立物理层
构建一个点到点的连接。使用PointToPointHelper来配置和连接ns-3的PointToPointNetDevice和PointToPointChannel对象。
//初始化
PointToPointHelper p2p;
//设置信道时延和速率
pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));
//Helper类的install操作都是连接两个层 , 然后会生成接口
//这里install生成netDevice,channel以2ms和5Mbps的速率传输数据连接物理层和链路层
NetDeviceContainer device = p2p.install(node1,node2);
3.网络层和传输层: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::CreateSocket (Ptr node, TypeId tid)
{
NS_LOG_FUNCTION (node << tid);
Ptr s;
NS_ASSERT (node != 0);
Ptr socketFactory = node->GetObject (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 = node->GetObject (tid);
1
这一行代码返回的对象socketFactory 对象不是UdpSocketFactory对象,应该是它的子类对象或者父类对象,但是编程思想上看,父类对象基本不可能。只能是其子类对象。
UdpSocketFactory类的子类只有一个:UdpSocketFactoryImpl。【必定只有一个子类或者说只有一个子类对象 不然这么写的话 程序就分不清返回哪个子类对象了不是】
此时再看UdpSocketFactoryImpl的CreateSocket()方法:
Ptr
UdpSocketFactoryImpl::CreateSocket (void)
{
NS_LOG_FUNCTION_NOARGS();
return m_udp->CreateSocket ();
}
1
2
3
4
5
6
其中的m_udp对象是Ptr,再看UdpL4Protocol的CreateSocket ():
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;
}
看到这个代码就知道了,UdpSocketFactory的实现类UdpSocketFactoryImpl利用UdpL4Protocol对象来创建Socket对象。而UdpL4Protocol对象的CreateSocket 方法通过创建UdpSocket的实现类UdpSocketImpl来创建socket,并返回。
也就是说,最终创建的socket对象是UdpSocketImpl类型的。
参考连接
https://blog.csdn.net/Hesy_H/article/details/95179160