NS2路由协议和数据转发
来源:互联网 发布:ubuntu进桌面后无unity 编辑:程序博客网 时间:2024/06/06 08:59
今天刚在netforum上看到一个帖子,讨论的是NS2路由协议和数据转发,转载下:
我再写一次,看能不能发上来!在ns manual中有一章是介绍classifier的,这个classifier就是一个节点的入口,功能就是利用路由表,根据一定的规则将收到的数据包进行转发,单播路由中默认的分类器是DestHashClassifier,就是根据数据包的目的地址来转发。可以看出来,这个里面和路由协议是没有关系的。但是又不是真的没有关系,路由表就是路由协议形成的。路由协议其实也是在每个节点上有一个路由agent,任何节点上的agent都是有端口的,所以这个时候可以把路由agent看作是tcp层的(事实上也是),各个路由agent之间进行通信,通信的方式和我们的tcp层的agent的通信方式是一样的。所以这个agent肯定看不到本节点上其他agent的数据,所以想在路由协议里处理节点的数据包(非路由包)是不可能的事情。
void Classifier::recv(Packet* p, Handler*)
{
NsObject* node;
int cl = classify(p);
if (cl < 0 || cl >= nslot_ || (node = slot_[cl]) == 0) {
Tcl::instance().evalf("%s no-slot %d", name(), cl);
Packet::free(p);
return;
}
node->recv(p);
}
看见没有,这个是classifier的recv函数,就是接受到一个包后,根据一定的规则(classify)来查询路由表(一个表项就是一个slot),然后再用相应的节点的recv函数接收(就是把数据转发出去了)。
这也就是说明了一个问题,如果想要做一个能处理数据报的上层overlay,那么就不能做成agent的形式,因为agent之间是不透明,overlay agent是无法看到tcp or udp agent所产生的数据报,也就无从进行处理,这就很有意思了,应该怎么做呢……
08/25
也不见得就一定是不行,难道真的不能让一个agent接收其他agent的数据吗?
不管怎么说要先明白一个节点接收和处理数据包的流程,NS Manual第五章描述了节点和转发的一些细节。有个图很有意思。
讲述了数据包进入节点的流程:
首先对数据包进行处理的模块是entry,entry本身只是一个标签变量而非是像classifier一样的实例变量。entry的作用,很多资料写的不尽不实,manual的说法是,entry返回的是当前节点的入口地址。对于单播节点而言,这个变量是一个用来检查目的地址高位字段的分类器。
Tcl对象之一:地址分类器(address classifier),用来判断分组的目标地址,/ns-2.27/classifier/classifier-addr.{h/cc};
Tcl对象之二:端口分类器(port classifier),用来判断分组的目标Agent,/ns-2.27/classifier/classifier-port.{ h/cc}。
个人的观点是,当一个节点收到packet时,先由Addr_classifier来判断目的地址,如果packet的dst_addr不是本节点的address,则查询路由表,将packet转发到相应的link上,如果dst_addr与本节点address相同,则将packet交由port_classifier判断packet所用的端口,然后转交给使用相应端口的agent。
如果实际的处理流程是这样的话,那就很麻烦了,那就意味,如果使用agent来设计overlay system,那么这个overlay agent是无法接收到packet的,因为packet的dst_addr是end的address,而不是安装了overlay system的中间节点的address,那么这个中间节点收到packet之后,他会将packet转发到相应的link上而不是交给上层的agent,所以overlay agent是收不到packet的。
08/26
有一个想法,既然packet在到达后会由Addr_Classifier来进行分类并进行对应的处理,那么能不能修改Addr_Classifier文件,判断如果packet到达的当前节点是overlay的节点,则把packet递交给Port_Classifier,然后交给overlay agent进行处理,最后再发送出去呢?
如果idea是可行的,那么还有两个问题要解决:
1. NS2本身并没有提供查询packet所到达的节点的address或者id的功能,如何添加这个功能?这个也许有帮助(如何测试呢?)
我有一点明白他是怎么获得当前节点地址的了,但是仍然不确信这个方法是否正确,或者能否及时的获得当前节点的id。这个方法其实是通过调用trace的一些特点来变相的来获取当前节点的id。NS2的trace本身会跟踪所有节点上的所有事件,当然其中包括了接收和发送packet,根据下面几个贴的说法:
Trace文件记录的是每个结点的哪个层(路由层、代理层等)发送或接收包的历史记录。也就是说,每当一个结点要发送或接收到一个包时,Trace文件就会为其生成一条对应的记录。
Manual上是这么说的,“内部状态src_ 和dst_用来标识跟踪输出,他和包头中相应域的名字各自独立。recv()仅仅使用源,目的和特殊的跟踪类型字符来格式化一个跟踪入口。dump()函数把格式化了的跟踪入口写到域channel_相关联的I/O句柄。format函数实际规定了跟踪的文件格式。”
2. 如何编写agent,还有制定packet递交的端口?
09/02
我以在tcp 中添加为例
在tcp.h中添加void trace_var(char * var_name, double var);
在tcp.cc中添加
void TcpAgent::trace_var(char * var_name, double var)
{
char wrk[500];
if (channel_) {
int n;
sprintf(wrk, "%g x x x x %s %g",Scheduler::instance().clock(),var_name, var);
n = strlen(wrk);
wrk[n] = '/n';
wrk[n+1] = 0;
(void)Tcl_Write(channel_, wrk, n+1);
}
}
当你想在某个地方跟踪变量的变化是trace_var(”aaa“,cwnd_);
然后在tcl文件中tcp_ attach-trace [set ftracetcp$id_]
就ok了
有关ns2的事件跟踪
ns2中限制Trace文件的输出
调用了的。
你可能不是很清楚调用的机制。
举个例子Myagent Mycommand(假如这是个tcl脚本里的语句)
解释器先在tcl脚本定义的类Myagent中找Mycommand这个成员函数,如果找到就执行。
如果没有找到,解释器就直接将命令变为Myagent cmd Mycommand,cmd这个函数就会调用c++中的command函数,然后将cmd Mycommand作为参数传递进去。就像上面楼主的例子中那样调用了(为什么从argv[1]开始算?argv[0]为“cmd”)
- NS2路由协议和数据转发
- 在NS2中添加路由协议
- 在NS2中添加路由协议
- 在NS2中添加路由协议
- 在NS2中添加路由协议
- 路由协议:学习小结-本机路由与转发路由
- 转发和路由的区别
- ICN路由和转发流程
- ns2.30下添加mflood-mflood路由协议
- 基于NS2的组播路由协议实现及仿真
- 基于NS2的网络路由协议仿真(AODV、COPE+AODV)
- 在NS2中添加路由协议(转)
- 如何在NS2中增加新的路由协议
- NS2上实现一个简单的路由协议
- NS2.35下添加新的无线路由协议要点
- 数据报转发(多网络路由)
- 【网络安全】Linux数据路由转发配置
- IP协议和路由
- 《编程之美》:整数的二进制表示中1的个数
- 今天开始我的异国求职路
- 微软,Google面试题 (22) —— 跳台阶
- java中相对路径,绝对路径问题总结
- Windows API串口编程参考
- NS2路由协议和数据转发
- winform datagridview 绑定
- JS获取URL参数
- 抽象基类 及 纯虚函数
- 继承 之 动态内存分配
- 继承 之 友元函数
- 继承 之 能否被继承
- WinForm开发,窗体显示和窗体传值
- Linux Shell编程学习