首页 > 代码库 > 10、其他模块

10、其他模块

① 分组模块

分组(消息)是模拟器的基本对象。Ns-3中每个分组都包含一个字节缓冲区和一个Tag列表,通过Header类和Trailer类对缓冲区数据进行添加和删除。分组对象的接口提供一些私有数据的访问,Tags通过一个指针来实现,该指针指向TagData数据结构链表的开始,字节缓冲区和Tag链表的当前实现基于写时复制。

Ns-3的分组对象包含一个字节缓冲区:协议头部和尾部有用户提供的串行化(serialization)和还原串行化(deserialization)例程在这个字节缓冲区串行化。NS-3的分组类能够给每个分组额外的“Tags”,该Tags是16byte的数据。任何分组都可一存储任意个数的独一无二的Tags。其中的每个Tag都由自身的C++类型独一无二地标识。

对字节缓冲区进行添加和删除的基本类是class Header和class Trailer。头部更为常见,要使用重写虚函数的方法。注意Header要被串行化进邻近的缓冲区,而Tag是存储在一个数组中。在默认情况下,Tag的大小被限制为16byte。Tags可以被灵活的定义为任意类型,但是无论在任何时候,Tags缓冲区中只能存在某个类型的一个实例。

/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */

#include "ns3/ptr.h"

#include "ns3/packet.h"

#include "ns3/header.h"

#include <iostream>

using namespace ns3;

/* A sample Header implementation

*/

class MyHeader : public Header

{

public:

MyHeader ();

virtual ~MyHeader ();

void SetData (uint16_t data);

uint16_t GetData (void) const;

static TypeId GetTypeId (void);

virtual TypeId GetInstanceTypeId (void) const;

virtual void Print (std::ostream &os) const;

virtual void Serialize (Buffer::Iterator start) const;

virtual uint32_t Deserialize (Buffer::Iterator start);

virtual uint32_t GetSerializedSize (void) const;

private:

uint16_t m_data;

};

MyHeader::MyHeader ()

{

// we must provide a public default constructor,

// implicit or explicit, but never private.

}

MyHeader::~MyHeader ()

{

}

TypeId

MyHeader::GetTypeId (void)

{

static TypeId tid = TypeId ("ns3::MyHeader")

.SetParent<Header> ()

.AddConstructor<MyHeader> ()

;

return tid;

}

TypeId

MyHeader::GetInstanceTypeId (void) const

{

return GetTypeId ();

}

void

MyHeader::Print (std::ostream &os) const

{

// This method is invoked by the packet printing

// routines to print the content of my header.

//os << "data="http://www.mamicode.com/<< m_data << std::endl;

os << "data="http://www.mamicode.com/<< m_data;

}

uint32_t

MyHeader::GetSerializedSize (void) const

{

// we reserve 2 bytes for our header.

return 2;

}

void

MyHeader::Serialize (Buffer::Iterator start) const

{

// we can serialize two bytes at the start of the buffer.

// we write them in network byte order.

start.WriteHtonU16 (m_data);

}

uint32_t

MyHeader::Deserialize (Buffer::Iterator start)

{

// we can deserialize two bytes from the start of the buffer.

// we read them in network byte order and store them

// in host byte order.

m_data = http://www.mamicode.com/start.ReadNtohU16 ();

// we return the number of bytes effectively read.

return 2;

}

void

MyHeader::SetData (uint16_t data)

{

m_data = http://www.mamicode.com/data;

}

uint16_t

MyHeader::GetData (void) const

{

return m_data;

}

int main (int argc, char *argv[])

{

// Enable the packet printing through Packet::Print command.

Packet::EnablePrinting ();

//实例化报头

// instantiate a header.

MyHeader sourceHeader;

sourceHeader.SetData (2);

//实例化分组

// instantiate a packet

Ptr<Packet> p = Create<Packet> ();

//把报头存储在分组中

// and store my header into the packet.

p->AddHeader (sourceHeader);

//标准输出报头内容

// print the content of my packet on the standard output.

p->Print (std::cout);

std::cout << std::endl;

// you can now remove the header from the packet:删除分组中的报头

MyHeader destinationHeader;

p->RemoveHeader (destinationHeader);

// and check that the destination and source检查目的和源头,报头包含相同的值。

// headers contain the same values.

NS_ASSERT (sourceHeader.GetData () == destinationHeader.GetData ());

return 0;

}

clip_image002

/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */

/*

* Copyright (c) 2006,2007 INRIA

*

* This program is free software; you can redistribute it and/or modify

* it under the terms of the GNU General Public License version 2 as

* published by the Free Software Foundation;

*

* This program is distributed in the hope that it will be useful,

* but WITHOUT ANY WARRANTY; without even the implied warranty of

* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the

* GNU General Public License for more details.

*

* You should have received a copy of the GNU General Public License

* along with this program; if not, write to the Free Software

* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

*

* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>

*/

#include "ns3/tag.h"

#include "ns3/packet.h"

#include "ns3/uinteger.h"

#include <iostream>

using namespace ns3;

// define this class in a public header

//在公共报头中定义类

class MyTag : public Tag

{

public:

static TypeId GetTypeId (void);

virtual TypeId GetInstanceTypeId (void) const;

virtual uint32_t GetSerializedSize (void) const;

virtual void Serialize (TagBuffer i) const;

virtual void Deserialize (TagBuffer i);

virtual void Print (std::ostream &os) const;

// these are our accessors to our tag structure这些都用于访问标签

void SetSimpleValue (uint8_t value);

uint8_t GetSimpleValue (void) const;

private:

uint8_t m_simpleValue;

};

TypeId

MyTag::GetTypeId (void)

{

static TypeId tid = TypeId ("ns3::MyTag")

.SetParent<Tag> ()

.AddConstructor<MyTag> ()

.AddAttribute ("SimpleValue",

"A simple value",

EmptyAttributeValue (),

MakeUintegerAccessor (&MyTag::GetSimpleValue),

MakeUintegerChecker<uint8_t> ())

;

return tid;

}

TypeId

MyTag::GetInstanceTypeId (void) const

{

return GetTypeId ();

}

uint32_t

MyTag::GetSerializedSize (void) const

{

return 1;

}

void

MyTag::Serialize (TagBuffer i) const

{

i.WriteU8 (m_simpleValue);

}

void

MyTag::Deserialize (TagBuffer i)

{

m_simpleValue = http://www.mamicode.com/i.ReadU8 ();

}

void

MyTag::Print (std::ostream &os) const

{

os << "v=" << (uint32_t)m_simpleValue;

}

void

MyTag::SetSimpleValue (uint8_t value)

{

m_simpleValue = http://www.mamicode.com/value;

}

uint8_t

MyTag::GetSimpleValue (void) const

{

return m_simpleValue;

}

int main (int argc, char *argv[])

{

//创建一个标签

// create a tag.

MyTag tag;

tag.SetSimpleValue (0x56);

//把标签存储在分组中

// store the tag in a packet.

Ptr<Packet> p = Create<Packet> (100);

p->AddPacketTag (tag);

//创建一个分组的副本

// create a copy of the packet

Ptr<Packet> aCopy = p->Copy ();

//从分组的副本中读取标签

// read the tag from the packet copy

MyTag tagCopy;

p->PeekPacketTag (tagCopy);

//副本和原来是一样的

// the copy and the original are the same !

NS_ASSERT (tagCopy.GetSimpleValue () == tag.GetSimpleValue ());

aCopy->PrintPacketTags (std::cout);

std::cout << std::endl;

return 0;

}

clip_image004

② Internet模块

节点在被创建的时候仅仅是一个空壳,在为其继承各种功能模块之前它几乎没有任何作用。那么Internet协议栈也是要为节点添加的模块之一,因此ns-3提供了诸多项TCP/IPv4和IPv6相关的协议栈组件。这些模型可以手动,也可以通过Helper聚集在一起。对于Internet协议栈,使用InternetStackelper::Install(nodes)將其集成到Node创建的节点中。

一个Internet Stack Node包含如下组件:

Layer-3 protocols:在网络接口之上的为网际层IP,在这一层中包括:IPv4、IPv6和ARP等协议。类IPv4L3Protocol是实现网际层IP的类,但是这个类不是对外的公共接口,而是共接口类IPv4调用。

底层会调用receive函数。

IPv4L3Protocol对象被聚合到Node节点中,每个节点中仅有一个IPv4L3Protocol对象,高层的协议(比如TCP)要发送一个TCP数据分组给IPv4L3Protocol对象是通过调用函数GetObject<Ipv4L3Protocol>()来获取该节点的底层协议,

可以通过Config::SetDefault(“ns3::ArpCache::PendingQueueSize”,UintegerValue(MAX_BURST_SIZE/L2MTU*3));来设置arp缓冲区大小。

有Layer-4 portocols层,也就是传输层函数。比如创建一个UDP套接字。

Ptr<Udp> udpSocketFacotry =GetNode()->GetObject<Udp>();

Ptr<Socket> m_socket =socketFactory->CreateSocket();

M_scoket->Bind(m_local_address);

路由:可以阅读golbal centralized routing 部分学习如何为有线网络配置全局路由。阅读unicast routing部分学习单播路由协议以及multicast routing部分学习多播路由协议。

1) golbal centralized routing在很多时候被称为God路由,它实现的是在整个网络仿真过程中都使用最理想化的路由算法,即最短路径算法。可以通过Ipc4StaticRouting API设定指定的路由协议而不是使用优先级级别较低的全局路由。

可以通过Ipc4GlobalRoutingHelper::RecomputerRoutingTables();重新建立路由。

例如,在仿真进行到5s时建立路由表:

Simulator::Schedule(Seconds(5),&Ipc4GlobalRoutingHelper::RecomputerRoutingTables());

两种控制路由行为,第一个是Ipv4GlobalRouting::RandomEcmpRouting,如果设置为真,那么数据分组会随机选择具有相同代价的多个路由。相反,数据分组就会只有一个合适的路由使用。第二个是Ipv4GlobalRouting::RespondToInterfaceEvents,如果设置为真,系统会通过接口发现事件动态更新全局路由,相反,用户需要手动调用RecomputerRoutingTables()来更新。

2) Unicast routing

3) Multicast routing

TCP,实现在src/network目录中找到。有两个抽象类:TcpSocket,这个类定义在src/internet/model/tcp-socket.h中。还有一个TcpSocketFactory类,用来创建TCP套接字。

③ 网络设备模块

点对点PointToPoint模块

CSMA模块,其实就是以太网精髓模型化了一个简单的总线网络

WiFi模块

④ 应用层模块

可以在scr/network/model的application和application中找到相关代码。

有一系列模型:UdpClientServer,UdpEcho,Radvd,Ping6,PacketSink,OnOffApplication,BulkSendApplication。

⑤ 移动模块

Ns-3提供了3点:移动模型、初始化位置分布和辅助Helper类。

Ns-3大量不同的模型,它们都是继承自ns3::MobilityModel类。移动节点初始位置的分布是由类PoisitionAllocator负责,每个节点的初始位置在仿真进行前就由该类谁都哪个完成。同样ns-3还有和它对应的MobileHelper模型,该类把移动模型和位置分配整合在一起。可以在src/mobility/model/mobility-model.h中找到MobilityModel类的定义。

⑥ 能量模块

有两部分组成:能量资源和设备能量模型。,在src/examples/energy和examples/energy中找到。

⑦ 添加模块