| Colorful SeaSon 的个人资料NS2 & SeaSon日志列表 | 帮助 |
|
8月26日 层次地址的设定在无线和有线网络的混合仿真中为了使数据包能在有线和无线网之间找到路由需要用 到hierarchical 地址,hierarchical 地址分三层结构: A.B.C. A:所处的网络地址 B:所处的子网地址 C:节点地址 2、设定网络的数量,即不同的A的数量 AddrParams set domain_num_ 5 设定网络数量为5,即上面图中从0~4 3、设定每个网络中子网的数量。要同下图的网络对应,即对应0的子网数量,1的子网数量... lappend cluster_num 2 1 1 2 2 即设定:
AddrParams set cluster_num_ $cluster_num
4、设定每个子网中节点的数量,也严格按照顺序 lappend eilastlevel 1 1 2 1 1 1 1 1 AddrParams set nodes_num_ $eilastlevel 顺序为对于不同的网络按照网络号由小到大,而相同的网络地址,按照子网号从小到大排序,然后按照排序结果顺序写出每个子网中节点的数量。如对应下图(单击看大图)的设定结果为
2月9日 公告 因为长时间不接触NS了,也没什么可写了,这里就停止更新了,等我以后接着做的时候,会将我的经验与大家分享。
为了大家方便,我把我的经验总结成了《NS29问之SeaSon解答》放在了我的共享信箱里面,有一些因为仓促未整理进去,我会在以后的工作中继续完善的:)
db.hit.edu.cn/~season
SeaSon 2006-2-9
注意:用下载工具下载的时候一定要保留备份,以方便他人继续下载,谢谢了
7月15日 tcldebug的安装完美版1.下载 tcl-debug( 地址 http://expect.nist.gov/tcl-debug/tcl-debug.tar.gz),以版本2.28为例,解压到ns-allinone-2.28目录下面。 2) 运行 wireless-test.tcl 运行脚本之后,如果你成功安装,将会出现以下信息提示: 如果还有错误信息,你就重复检查以上各个过程是否正确,好运! 注:以上为翻译ns mail-list内容,作者为:Tae-hyung Kim,最后对他表示深深的感谢! DSR源代码分析[转载]DSR in ns-2Source code : Not all flies in ./dsr/ directory are used by the ns-2. the routing agent is implemented as Agent/DSRAgent. Thus, the source codes include:
It is found that srh->addr and p.route are two different structures. srh() is always along with the packet. however, when DSR agent received a packet, it will SRPacket p(packet, srh); This generate a "p" which is frequently used by all other functions. remember p does not go along with the packet leaving dsr agent. Before the packet was sent out of the agent, another statement will be used to update "SRH" in sendOutPacketwithRoute p.route.fillSR(srh); Also, the tap() entry is also generate a p for its use. however, another entry point of agent "xmitFailed" use srh() directly. Special tcl interface. Unless other routing protocol, the ns-2.1b9a,has a special node type named as "SRNodeNew". From those routines in the ns-lib.tcl. We can see that speical. Also, there is a tcl file in mobiloty/dsr.tcl is also related. DSR Signaling Packets in Brief:
Entry Points for DSR agent:
Basic functions:
Basically, this function has three branches:
handleForwarding is dcallin "handleDefaultforwarding" for doing some simple operations for DSR rules. At last, the packet will be sent by sendOutPacketWithRoute
The longest route we can handle is defined in : define MAX_SR_LEN 16 // longest source route we can handle Possible Reason for xmit_failure below IP layer:
In the beginning of dsragent.cc, it define many bool selectors of some options like: About Flow State: It is also desirable to disable the flow state stuff. it make the dsr code messy. flow state is not an orginal idea. About Packet Salvagestatic const bool dsragent_enable_flowstate = false; it's unknown how to complete disable the packet retransmission in layer 3. Even you change three expressions in dsragent.cc.
The trace file still show that the routing agent send a undeliverable packet again. See xmitFail() function. I guess, it is necessary to disable "GOD" also.
7月14日 怎样使用gdb调试ns中c++代码参见NS29问或者可老师网站上的,gdb调试说明 1.安装:cygwin下面安装就行了,注意我测试的gdb-20020411-1和gdb-20010428-3都是图形界面,而版本gdb-20041228-3我发现是命令行的,所以推荐前两个版本,毕竟图形界面方便很多,如果你热衷于新的版本,那看到这里你就可以停止了:)下面以ns-allinone-2.27为例说明 注:现在直接从网上安装的版本好像没有那么老的版本,我是从网上找到一个本地安装版本“ Cygwin0528”(可以用baidu或者google搜一下),然后利用它安装gdb-20020411-1,注意你只需要安装这一个就行了,其他的所有都选择为keep(已经安装的)或者skip(未安装的),否则会出现问题的,一定要切记这点儿。 注意:以下步骤一个都不能少 c.在左上角红色标记的地方输入你要调适的程序。如:mflood.cc 然后输入Ctrl+N进入命令行窗口,如下图所示: 在上图中命令行窗口进入你的tcl脚本所在的目录: 6月15日 NS技巧18怎样从trace文件中获得从节点a发送到b的数据报经历的路径? 当然你也可以利用这种方法查找你数据报在什么地方丢了,方便你解决类似问题。 命令如下面所示: $ gawk ' $14=="[a:0" && $15~/b:0/ {print}' dasele.tr
其中$14,$15代表dasele.tr文件中的第14列和15列(以空格分开),如: s 69.530259667 _115_ AGT --- 326 Mrpqos 0 [0 0 0 0] ------- [115:0 23:0 32 0]中s是第一列,69.530259667时第二列... ...[115:0时第14列,以空格分开各列
举例: Candy@CandySeaSon /cygdrive/d/my_programs/ns2/test/mrpqos $ gawk ' $14=="[115:0" && $15~/23:0/ {print}' dasele.tr s 69.530259667 _115_ AGT --- 326 Mrpqos 0 [0 0 0 0] ------- [115:0 23:0 32 0] r 69.530259667 _115_ RTR --- 326 Mrpqos 0 [0 0 0 0] ------- [115:0 23:0 32 0] s 69.530259667 _115_ RTR --- 326 Mrpqos 20 [0 0 0 0] ------- [115:0 23:0 30 44]
r 69.535174494 _44_ RTR --- 326 Mrpqos 20 [13a 2c 73 800] ------- [115:0 23:0 3 0 44] f 69.535174494 _44_ RTR --- 326 Mrpqos 20 [13a 2c 73 800] ------- [115:0 23:0 2 9 90] r 69.537091728 _90_ RTR --- 326 Mrpqos 20 [13a 5a 2c 800] ------- [115:0 23:0 2 9 90] f 69.537091728 _90_ RTR --- 326 Mrpqos 20 [13a 5a 2c 800] ------- [115:0 23:0 2 8 23] r 69.538990075 _23_ AGT --- 326 Mrpqos 20 [13a 17 5a 800] ------- [115:0 23:0 2 8 23]
从上面的代码可知道从节点115到节电23的路径是:115-〉44-〉90-〉23。 6月9日 我的实验中间结果这是我实验中间一过程的图形,这部分功能将网络中的节点动态的划分为若干个域,每一个域有一个相当于服务器的代理统一管理,节点如果移动到一个域中便自动注册到相应的服务器上。其中不同颜色和形状代表属于不同的域,节点上面的标号为其服务器代理的编号,是动态变化的。服务器代理的颜色是黑色的。
6月3日 NS2分析17setdest的参数说明 <original 1999 CMU version (version 1)> OR 还有就是如果你要生成的节点较多,你就要有足够的耐性,因为昨天我生成了一个scen-150n-0p-3m-20M-400t-1000-1000的场景用了足足3个半小时,而且cpu利用率始终是100%,我的电脑配置迅驰1.5G,768M,几乎什么别的都干不了,郁闷 6月2日 NS分析16模拟过程中突然退出的一种解决办法 我在我的程序调试过程中曾经遇到过程序运行过程中异常退出的问题,就是什么提示也没有就突然结束了,后来经过分析我的问题是recv函数中,对于接收到的有些类型的数据包没有进行任何处理导致的,如果你要是遇到这样的问题,可以具体分析一下是不是所有类型的数据包你都考虑到了,或许会能解决你的问题:) 如果你按照上面的方法你的问题没有得到解决,也很正常,毕竟我的是一种特殊的情况:(也希望把你的问题的解决方法告诉我,谢谢 NS分析15路由层怎样上传数据的 参见aodv.cc 1.在aodv.h中声明 PortClassifier *dmux_; 2.if (ch->ptype() != PT_AODV && ch->direction() == hdr_cmn::UP && ((u_int32_t)ih->daddr() == IP_BROADCAST) || ((u_int32_t)ih->daddr() == here_.addr_)) { dmux_->recv(p,0); //传递给分类器 return; 3. 分类器处理数据包 void Classifier::recv(Packet* p, Handler*h) { NsObject* node = find(p);//查找节点的是否存在 if (node == NULL) { /* * XXX this should be "dropped" somehow. Right now, * these events aren't traced. */ Packet::free(p); return; } node->recv(p,h);//让节点接受 4.节点接受后 . void NsObject::recv(Packet *p, const char*) { Packet::free(p); } NS技巧14怎么调用无线节点的路由协议(如AODV)中的command()里面的函数
例如,我的路由协议myrtagent的command()里面有 seta方法如下面红色字体所示。则在tcl脚本中可以用一下方式调用这个方法; [$node_(0) agent 255] seta 10 [$node_(0) agent 255]表示获得node_(0)的255端口的代理(协议) 然后再调用这个代理的seta函数。 Flood::command(int argc, const char*const* argv) { Tcl& tcl = Tcl::instance(); if(argc == 2) { if(strncasecmp(argv[1], "id", 2) == 0) { cout<<"The ip addr is "<<argv[4]<<endl; tcl.resultf("mflood:%d", index_); return TCL_OK; } else if (strcmp(argv[1], "geta") == 0){ cout<<"haha geta :"<<a<<endl; return TCL_OK; } else if (strcmp(argv[1], "uptarget") == 0) { if (uptarget_ != 0) tcl.result(uptarget_->name()); return (TCL_OK); } } else if(argc == 3) { if(strcmp(argv[1], "index_") == 0) { index_ = atoi(argv[2]); return TCL_OK; } else if(strcmp(argv[1], "log-target") == 0 || strcmp(argv[1], "tracetarget") == 0) { logtarget = (Trace*) TclObject::lookup(argv[2]); if(logtarget == 0) return TCL_ERROR; return TCL_OK; } else if (strcmp(argv[1], "seta") == 0){ a=atoi(argv[2]); return TCL_OK; } else if (strcmp(argv[1], "uptarget") == 0) { if (*argv[2] == '0') { target_ = 0; return (TCL_OK); } uptarget_ = (NsObject*)TclObject::lookup(argv[2]); if (uptarget_ == 0) { tcl.resultf("no such object %s", argv[2]); return (TCL_ERROR); } return (TCL_OK); } else if (strcasecmp (argv[1], "port-dmux") == 0) { TclObject *obj; port_dmux_ = (NsObject *) obj; return TCL_OK; } } return Agent::command(argc, argv); } NS技巧13九.怎样使用ns自己的链表 1.头文件 #include<lib/bsd-list.h> 2.初始化 1). 在节点中添加,包括了指向前驱和后继的节点。 #define LIST_ENTRY(type) struct { type *le_next; /* next element */ type **le_prev; /* address of previous next element */ } 2).定义一个链表,链表的类型为type,表头为lh_first #define LIST_HEAD(name, type) struct name { type *lh_first; /* first element */ } 3)初始化链表 #define LIST_INIT(head) { (head)->lh_first = NULL; } 4)插入节点 #define LIST_INSERT_AFTER(listelm, elm, field) { if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) (listelm)->field.le_next->field.le_prev = &(elm)->field.le_next; (listelm)->field.le_next = (elm); (elm)->field.le_prev = &(listelm)->field.le_next; }
#define LIST_INSERT_BEFORE(listelm, elm, field) { (elm)->field.le_prev = (listelm)->field.le_prev; (elm)->field.le_next = (listelm); *(listelm)->field.le_prev = (elm); (listelm)->field.le_prev = &(elm)->field.le_next; }
#define LIST_INSERT_HEAD(head, elm, field) { if (((elm)->field.le_next = (head)->lh_first) != NULL) (head)->lh_first->field.le_prev = &(elm)->field.le_next;\ (head)->lh_first = (elm); (elm)->field.le_prev = &(head)->lh_first; } 5)删除节点 #define LIST_REMOVE(elm, field) { \ if ((elm)->field.le_next != NULL) \ (elm)->field.le_next->field.le_prev = \ (elm)->field.le_prev; \ *(elm)->field.le_prev = (elm)->field.le_next; \ } 6)一个例子 (1)定义节点类型 class MFlood_RTEntry { friend class MFlood_RTable; friend class MFlood;
public: MFlood_RTEntry(); MFlood_RTEntry(nsaddr_t src,u_int32_t seq); bool isNewSeq(u_int32_t seq); // old -> false, new->true void addSeq(u_int32_t seq); // add a seqno to seqno array(rt_seqnos)
protected: LIST_ENTRY(MFlood_RTEntry) rt_link;
nsaddr_t src_; // u_int32_t seq_;
u_int32_t rt_seqnos[REM_SEQ_COUNT]; //seqno array u_int32_t max_seqno; //max seqno u_int32_t min_seqno; //max seqno u_int16_t seq_it; // seqno's iterator }; (2)建立一个链表节点类型为MFlood_RTEntry的链表 rthead LIST_HEAD(, MFlood_RTEntry) rthead; (3)初始化链表rhead为NULL LIST_INIT(&rthead) (4) 怎样使用 MFlood_RTEntry* MFlood_Rtable::rt_lookup(nsaddr_t id) { Mflood_RTEntry *rt = rthead.lh_first;//获取链表表头 for(; rt; rt = rt->rt_link.le_next) { if(rt->src_ == id) break; } return rt; } (5)删除节点 void MFlood_RTable::rt_delete(nsaddr_t id) { MFlood_RTEntry *rt = rt_lookup(id); if(rt) { LIST_REMOVE(rt, rt_link); delete rt; } } (6)插入节点 rt = new MFlood_RTEntry(ih->saddr(), fh->seq_); LIST_INSERT_HEAD(&rtable_.rthead,rt,rt_link);
NS技巧12tr文件中的CBK错误最根求源(路由层协议以aodv为例) tr文件中的纪录: D 122.040067803 _4_ RTR CBK 257 Mrpqos 20 [13a 21 4 800] ------- [4:0 0:0 30 33] D 122.073627803 _4_ RTR CBK 258 Mrpqos 20 [13a 20 4 800] ------- [4:0 27:0 30 32] 1.追根求源,问题所在分析 经过查找CBK在aodv.cc的下列函数中使用,下面 printf("%%%%drop typen\n");语句是为了判断错误的类型。 AODV::rt_ll_failed(Packet *p) { struct hdr_cmn *ch = HDR_CMN(p); struct hdr_ip *ih = HDR_IP(p); aodv_rt_entry *rt; nsaddr_t broken_nbr = ch->next_hop_;
#ifndef AODV_LINK_LAYER_DETECTION printf("%%%%drop type1\n"); drop(p, DROP_RTR_MAC_CALLBACK); #else
/* * Non-data packets and Broadcast Packets can be dropped. */ //因为我的数据包不含有实际数据所以在下面DARA_PACKET()函数的判断中被丢弃了 //所以关键就是修改者个函数,具体修改参见 2.修改DATA_PACKET(ch->ptype()) if(! DATA_PACKET(ch->ptype()) || (u_int32_t) ih->daddr() == IP_BROADCAST) { printf("%%%%drop type2\n %d",ch->ptype());//测试丢包具体原因所在。 drop(p, DROP_RTR_MAC_CALLBACK); return; } log_link_broke(p); if((rt = rtable.rt_lookup(ih->daddr())) == 0) { printf("%%%%drop type3\n"); drop(p, DROP_RTR_MAC_CALLBACK); return; } log_link_del(ch->next_hop_);
#ifdef AODV_LOCAL_REPAIR /* if the broken link is closer to the dest than source, attempt a local repair. Otherwise, bring down the route. */
if (ch->num_forwards() > rt->rt_hops) { local_rt_repair(rt, p); // local repair // retrieve all the packets in the ifq using this link, // queue the packets for which local repair is done, return; } else #endif // LOCAL REPAIR
{ printf("%%%%drop type4\n"); drop(p, DROP_RTR_MAC_CALLBACK); // Do the same thing for other packets in the interface queue using the // broken link -Mahesh while((p = ifqueue->filter(broken_nbr))) { printf("%%%%drop type5\n"); drop(p, DROP_RTR_MAC_CALLBACK); } nb_delete(broken_nbr); }
#endif // LINK LAYER DETECTION }
2.修改DATA_PACKET(ch->ptype())
#define DATA_PACKET(type) ( (type) == PT_TCP || \ (type) == PT_TELNET || \ (type) == PT_CBR || \ (type) == PT_AUDIO || \ (type) == PT_VIDEO || \ (type) == PT_ACK || \ (type) == PT_SCTP || \ (type) == PT_SCTP_APP1 || \ //解决问题的关键所在!!!! (type) == PT_MRPQOS \ ) 3.通过上述方法就解决了我的丢包问题,你的可能不一样,但可以通过类似的方法找出问题的原因,并加以解决。
5月26日 NS技巧11转发数据包都需要设置什么? 我们需要改变一下参数 ch->addr_type()=NS_AF_INET; ch->direction()=hdr_cmn::DOWN; send(p); NS-tcl奇怪问题谁对谁错?你能看出他们的区别吗? set hda 10 1./错误代码??就是编译通不过的代码 if {$hda==0} { $node_ color red } elseif {$hda==1} { $node_ color blue } elseif {$hda==2} { $node_ color yellow } elseif {$hda==3} { $node_ color brown } elseif {$hda==4} { $node_ color tan } else{ $node_ color gold } 2./////////////////////下面是正确代码 if {$hda == 0} { $node_ color red } elseif {$hda == 1} { $node_ color blue } elseif {$hda == 2} { $node_ color yellow } elseif {$hda == 3} { $node_ color brown } elseif {$hda == 4} { $node_ color tan } else { $node_ color gold } NS技巧10怎样在c++中获得节点地址(ID)?
Tcl& tcl = Tcl::instance(); tcl.evalc("$node set id"); const char* addr = tcl.result(); int node_id = atoi(addr)); 节点的id便保存到了node_id中. NS技巧9怎样改变无线网络中802.11的能量状态?
# Power vs. Range
# Assume AT&T's Wavelan PCMCIA card -- Chalermek
# Pt_ = 8.5872e-4; // For 40m transmission range.
# Pt_ = 7.214e-3; // For 100m transmission range.
# Pt_ = 0.2818; // For 250m transmission range.
# Pt_ = pow(10, 2.45) * 1e-3; // 24.5 dbm, ~ 281.8mw
Phy/WirelessPhy set Pt_ 8.5872e-4 NS技巧8一.怎么样广播数据 根据AODV中recv()函数的代码,我们可以知道,只需要将IP包头的目的地址设为广播地址即可,ih->daddr() != IP_BROADCAST void AODV::recv(Packet *p, Handler*) { //访问通用以及IP包头 struct hdr_cmn *ch = HDR_CMN(p); struct hdr_ip *ih = HDR_IP(p);
assert(initialized()); //assert(p->incoming == 0); // XXXXX NOTE: use of incoming flag has been depracated; In order to track direction of pkt flow, direction_ in hdr_cmn is used instead. see packet.h for details.
if(ch->ptype() == PT_AODV) { ih->ttl_ -= 1; recvAODV(p); return; }
/* * Must be a packet I'm originating... */ if((ih->saddr() == index) && (ch->num_forwards() == 0)) { /* * Add the IP Header */ ch->size() += IP_HDR_LEN; // Added by Parag Dadhania && John Novatnack to handle broadcasting if ( (u_int32_t)ih->daddr() != IP_BROADCAST) ih->ttl_ = NETWORK_DIAMETER; } /* * I received a packet that I sent. Probably * a routing loop. */ else if(ih->saddr() == index) { drop(p, DROP_RTR_ROUTE_LOOP); return; } /* * Packet I'm forwarding... */ else { /* * Check the TTL. If it is zero, then discard. */ if(--ih->ttl_ == 0) { drop(p, DROP_RTR_TTL); return; } } // Added by Parag Dadhania && John Novatnack to handle broadcasting if ( (u_int32_t)ih->daddr() != IP_BROADCAST) rt_resolve(p); else forward((aodv_rt_entry*) 0, p, NO_DELAY); } |
|||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|