分组头的管理

1、在NS的模拟网络中,分组(Packet)是 对象间交互的基本单元。分组是一系列分组头和一个可选的数据空间组成。分组头的结构在Simulator对象创建时就被初始化了,同时每个分组头相对于分组的起始地址的偏移量也被记录下来。在缺省情况下,大多数NS内建的分组头都是使能的(包括common头、IP头、TCP头、RTP头、trace头等等)。这意味着在缺省的情况下无论某个分组头是否会被使用,它都会被初始化。在通常情况下,分组只含有一系列的分组头,而指向数据空间的指针为null。

用户可以为新的协议定义自己的分组头,也可以通过增加域的方式扩展现有的分组头,添加新分组头的方法,概括来说就是在C++中定义包含所需的域的structure,再定义一个static类来提供到otcl的连接,然后修改一些模拟的初始化代码来指定新分组头在分组中的字节偏移量。

2、协议和分组头

一般情况下,我们需要为新协议定义该协议自己的分组头,这样做可以保证新协议的使用不会影响已经存在的分组头。例如RTP头包含一个序列号字段和一个源标识字段,下面代码定义了RTP协议的分组头见~/ns/apps/rtp.(cc,h):

在rtp.h中

struct hdr_rtp {

u_int32_t srcid_;    //源标识字段

int seqno_;      //序列号字段

//rtp flags indicating significant event(begining of talkspurt)

u_int16_t flags_;

static int offset_;     //rtp头在NS分组中的字节偏移量,访问p分组的RTP头,hdr_rtp::access(p)。类PackHeaderManger负责把offset_和分组中这个头的位置绑定起来。

inline static int& offset() { return offset_; }

inline static hdr_rtp* access(const Packet* p) {

return (hdr_rtp*) p->access(offset_);

}

/* per-field member functions */

u_int32_t& srcid() { return (srcid_); }

int& seqno() { return (seqno_); }

u_int16_t& flags() { return (flags_); }

};

hdr_rtp主要作用是计算字段的字节偏移量,在结构中也提供了成员变量函数用来提供外部访问内部变量的接口。

在rtp.cc中

class RTPHeaderClass : public PacketHeaderClass {

public:

//调用PacketHeaderClass的构造函数,会使RTP头的大小被存储,被PackHeaderManger对象使用

RTPHeaderClass() : PacketHeaderClass("PacketHeader/RTP",

sizeof(hdr_rtp)) {

bind_offset(&hdr_rtp::offset_);//PackHeaderManger知道这个头的偏移量存储在那里

}

} class_rtphdr  // class_rtphdr是 RTPHeaderClass类的静态对象,提供了到otcl的连接

void RTPAgent::sendpkt()

{

Packet* p = allocpkt();   //构造一个需要发送的新分组,allocpkt()处理所有网络层分组头的字段的赋值工作。

lastpkttime_ = Scheduler::instance().clock();

makepkt(p);

target_->recv(p, (Handler*)0);

}

void RTPAgent::makepkt(Packet* p)

{

hdr_rtp *rh = hdr_rtp::access(p); //返回用于存储头信息的缓冲区的第一个字节的地址,被强制转换为相应的头的指针。

/* Fill in srcid_ and seqno */

rh->seqno() = seqno_++;

rh->srcid() = session_ ? session_->srcid() : 0;

}

3、添加新分组头

假如我们要增加一个叫newhdr的新分组头,需要:

(1)       在C++中创建一个新的structure来定义所需要的字段,按照命名惯例,这个structure应该叫hdr_newhdr,定义offset_字段和访问该字段的方法。

(2)       定义所需要的访问其他字段的成员函数。

(3)       创建一个static类来完成otcl连接(PcketHeader/Newdhr),在它的构造函数里面进行bind_offset()。

(4)       编辑~ns/tcl/lib/ns-packet.tcl来激活新的分组头。

如果需要查找分组头的名字,可以查看文件~ns/tcl/lib/ns-packet.tcl或者在NS中执行下面代码:

Foreach cl [PacketHeader info subclass] {

Puts $cl

}

1、  与分组头相关的类

(1)       Packet类:NS中所有的分组都是Packet类的对象,它是Event类的子类,因此分组可以像事件那样被调度。

class Packet : public Event {

private:

unsigned char* bits_;      // 指向的字符数组中存储着所有的分组头(BOB),包含BOB的第一个字节的地址,BOB是被激活的各个分组头中定义的所有structure连接一起形成的。BOB在模拟过程保持固定的大小,大小记录在Packet::hdrlen­_中,hdrlen­_的值在模拟配置阶段由PackHeaderManger类设置,

AppData* data_;              // variable size buffer for ‘data‘  不常使用

static void init(Packet*);     // initialize pkt hdr

bool fflag_;

protected:

static Packet* free_;        // packet free list,存储着已经回收的曾经使用过的分组,在产生新的分组时,会优先选择使用这些回收的分组所占用的空间。

int    ref_count_;      // free the pkt until count to 0

public:

Packet* next_;                   // for queues and the free list

static int hdrlen_;

Packet() : bits_(0), data_(0), ref_count_(0), next_(0) { }

inline unsigned char* bits() { return (bits_); }

inline Packet* copy() const;

inline Packet* refcopy() { ++ref_count_; return this; }

inline int& ref_count() { return (ref_count_); }

static inline Packet* alloc();

static inline Packet* alloc(int);

inline void allocdata(int);

// dirty hack for diffusion data

inline void initdata() { data_  = 0;}

static inline void free(Packet*);

inline unsigned char* access(int off) const {

if (off < 0)

abort();

return (&bits_[off]);

}

// This is used for backward compatibility, i.e., assuming user data

// is PacketData and return its pointer.

inline unsigned char* accessdata() const {

if (data_ == 0)

return 0;

assert(data_->type() == PACKET_DATA);

return (((PacketData*)data_)->data());

}

u_int8_t        incoming;

}

(2)       p_info类:保存了所有分组类型的名字的文本表示。

这个类相当于“胶水”,用来绑定各个分组类型值和它们的名字,当定义了一个新的分组类型后,它的数字代码应该添加到枚举类型packet_t中,需要注意的是,PT_NTPE必须是这个枚举类型的最后一个元素,同时这个分组类型的名字应该添加到p_info类的构造函数中。

(3)       PacketHeaderClass类:任何人一个分组头都是以它为基类,它提供的内部状态变量

可以在分组中定位某个特定的分组。设置hdrlen_和offset_变量,hdrlen_是在构造函数被设置,而offset_是通过调用bind_offset()来设置的。

(4)       PackHeaderManger类:管理各个分组头,在模拟配置阶段,可以从otcl中调用它来激活所有内嵌分组头的一部分。在BOB中分配给它们唯一的偏移量。

Packet.tcl中

PacketHeaderManager set hdrlen_ 0

PacketHeaderManager set tab_(Common) 1   //common头总是使能的

proc add-packet-header args {

foreach cl $args {

PacketHeaderManager set tab_(PacketHeader/$cl) 1

}

}

set protolist {     //包含了所有需要激活的分组头的名字

# Common:

Common

Flags

IP    # IP

…..

}

foreach prot $allhdrs {

add-packet-header $prot   //要激活的分组头加入到Otcl类数组tab_中,在tab_中所有被激活的分组头值为1.

}

Simulator instproc create_packetformat { } {  //在模拟的配置阶段被调用

PacketHeaderManager instvar tab_

set pm [new PacketHeaderManager]    //创建PacketHeaderManager类对象

foreach cl [PacketHeader info subclass] {

if [info exists tab_($cl)] {

set off [$pm allochdr $cl]

$cl offset $off

}

}

$self set packetManager_ $pm

}

PacketHeaderManager instproc allochdr cl {  //给出分组头的位置

set size [$cl set hdrlen_]

$self instvar hdrlen_

set NS_ALIGN 8

# round up to nearest NS_ALIGN bytes

# (needed on sparc/solaris)

set incr [expr ($size + ($NS_ALIGN-1)) & ~($NS_ALIGN-1)]

set base $hdrlen_

incr hdrlen_ $incr

return $base

}

(5)       hdr_cmn结构

模拟中的每个 分组都包含一个common头,hdr_cmn结构定义了用于跟踪分组流向、度量时间以及长度等常用指标的字段。

struct hdr_cmn {

enum dir_t { DOWN= -1, NONE= 0, UP= 1 };

packet_t ptype_;     // packet type (see above)

int    size_;                 // simulated packet size

//size_经常被用来计算沿着一条网络链路递交分组所需要的时间,值是应用数据的长度和IP层、运输层、应用层分组长度之和。

int    uid_;                   // unique id

int    error_;               // error flag

int     errbitcnt_;     // # of corrupted bits jahn

int     fecsize_;

double      ts_;           //测量在交换节点处的排队延迟

int    iface_;               // 完成多播分发树计算,它指出分组是那个link上收到的

dir_t          direction_;        // direction: 0=none, 1=up, -1=down

// source routing

char src_rt_valid;

double ts_arr_; // Required by Marker of JOBS

http://www.cnblogs.com/xyl-share-happy/archive/2012/05/30/2526791.html

时间: 2024-09-05 09:29:40

分组头的管理的相关文章

Github注册过程以及对管理软件的了解

二.目前流行的源程序管理软件和项目管理软件主要有以下一些: 1.Visual Source Safe 优点:如果开发工具是VS.NET,用VSS较合适,方便,安装配置和使用都简单,版本控制简单,打label后,要还原到这个版本较简单 缺点:基局域网,效率低,VSS自身安全性较差,只支持widows平台下 2.Concurrent Version System 优点:一度成为主流,不必担心数据流失,对中文路径名支持的较好,本地文件与库的对应可以多对多 缺点:不支持文件改名且只允许存储文件,管理员很

蓝牙核心技术概述(三): 蓝牙协议规范(无线电频率、基带链路控制、领汇管理)

关键词:蓝牙核心技术协议无线电频率基带链路控制链路管理作者:xubin341719(欢迎转载.请注明作者,请尊重版权.谢谢!)欢迎指正错误.共同学习.共同进步! !下载链接:Bluetooth PROFILE SPECIFICATIONS (基本涵盖全部蓝牙协议).buletooth core 2.1-4.0 SPECIFICATION(三蓝牙版本号的核心协议v2.1\v3.0\v4.0).蓝牙核心技术与应用 马建仓 版(蓝牙协议相关刚開始学习的人必读,开发人员參考) 蓝牙核心技术概述(一):蓝

C#开发微信门户及应用(5)--用户分组信息管理

在上个月的对C#开发微信门户及应用做了介绍,写过了几篇的随笔进行分享,由于时间关系,间隔了一段时间没有继续写这个系列的博客了,并不是对这个方面停止了研究,而是继续深入探索这方面的技术,为了更好的应用起来,专心做好底层的技术开发.本篇继续上一篇的介绍,主要介绍分组管理方面的开发应用,这篇的内容和上一篇,作为一个完整的用户信息和分组信息管理的组合. 1.用户分组管理内容 用户分组的引入,主要是方便管理关注者列表,以及方便向不同的组别发送消息的操作的,一个公众账号,最多支持创建500个分组. 用户分组

C#开发微信门户及应用(10)--在管理系统中同步微信用户分组信息

在前面几篇文章中,逐步从原有微信的API封装的基础上过渡到微信应用平台管理系统里面,逐步介绍管理系统中的微信数据的界面设计,以及相关的处理操作过程的逻辑和代码,希望从更高一个层次,向大家介绍微信的应用开发过程.本篇主要介绍在管理系统中,如何实现微信用户分组信息的同步操作. 其实微信能够风风火火的原因,主要就是因为有用户信息,所以同步并管理好微信账号的关注用户数据是非常重要的.有了微信用户的数据,你可以和你任何应用系统对接,实现系统-手机客户端的数据整合,还可以对用户进行营销管理,如发送用户感兴趣

windows_learn 002 用户管理和组策略

内容总览 域用户与组的管理 用户和组 用户登录名 添加用户工具 在活动目录中使用组 为何使用组? 全局组 Global Group Rules 域本地组 Domain Local Group Rules 通用组 Universal Group Rules 在域中使用组的策略 使用组的方针 组策略规划及部署 组策略规划及创建 组策略对象的工具 域用户与组的管理 概述 管理域用户账户 添加多个用户账户 域组账户 组的使用准则 用户和组 每个用户账号创建一个唯一的登录名 使用批处理创建多个用户 将用户

saltstack将minion客户端分组批量处理

现在我有6台主机,要将他们进行分组,这样管理起来比较方便 比如redhat.centos.各自分组. ddcluster1,hddcluster2,hddcluster3,hddcluster4,salt-master,salt-minion01 修改master的配置文件中的nodegroups vim /etc/salt/master #nodegroups: #  group1: '[email protected],bar.domain.com,baz.domain.com or bl*

gridcontrol自定义分组表头显示

gridcontrol分组后可以显示分组列名.值 以及汇总项,但是想再显示其他列的值就需要使用自定义分组头了,如下所示: private void bandedGridView2_CustomDrawGroupRow(object sender, DevExpress.XtraGrid.Views.Base.RowObjectCustomDrawEventArgs e) { GridGroupRowInfo GridGroupRowInfo = e.Info as GridGroupRowInf

【腾讯GAD暑期训练营游戏程序班】游戏场景管理作业说明文档

场景管理作业说明文档                              用了八叉树的算法,测出三层时最快,区域范围内物体数量为21块,控制台打印出的结果如图所示: 场景物体:游戏中,所有具有空间属性的物体游戏场景:<围棋>二维表<进击的围棋><围棋世界>基于空间分组的场景管理的进一步优化进一步分组四叉树视锥范围剔除非可见区域当前必要场景区域 动态加载谷歌 可感知即存在 不可感知即不存在 场景加载

C#-MVC开发微信应用(7)--在管理系统中同步微信用户分组信息

在前面几篇文章中,逐步从原有微信的API封装的基础上过渡到微信应用平台管理系统里面,逐步介绍管理系统中的微信数据的界面设计,以及相关的处理操作过程的逻辑和代码.希望从一个更高的层次介绍微信的开发. 在<C#-MVC开发微信应用(6)--用户分组信息管理>具体介绍了微信用户分组接口的实现方法,本篇将介绍,如何在我的平台软件上进行管理我们微信上的用户分组. 其实微信能够风风火火的原因,主要就是因为有用户信息,所以同步并管理好微信账号的关注用户数据是非常重要的.有了微信用户的数据,你可以和你任何应用