一.缺省路由
1.4.1版本的ONE模拟器自带11种路由模块,模块定义了在整个仿真过程中如何收发和处理消息.包括
这些提供了大多数重要的 路由协议的原型 其中有单消息拷贝的,n消息拷贝的和消息无限拷贝的协议.另外还有基于统计的改进路由协议模型.routing包的结构如图
在one中添加自己的路由模块需要继承MessageRouter这个类,它定义了大量不同的消息相关事件和资源管理的回调函数,这些函数可以被模拟引擎调用.ActiveRouter是MessageRouter的子类,它提供了邻居节点传送消息以及处理成功传输和中断传输等情况的功能,同时还提供了FIFO和随机的缓存管理方式.开发人员所建立的路由模块,需要重写覆盖或扩展MessageRouter和ActiveRouter这两个模块的方法函数.其中创建自己新类的最简单方法就是覆写父类的update方法,其他如消息传输和交换方法可以全部继承于ActiveRouter类.
二.代码分析
MessageRouter.java:
路由模块的超类,所有添加的路由模块必需直接或间接的继承于这个类,
在这个类中定义了缓存大小,TTL,消息发送队列模式和一些定义消息状
态的变量.此外这个类还有一个构造函数public MessageRouter(
Settings s) {},通过传送Setting这个变量进行路由属性的设置.
public void update(){},这个方法是用来更新整个模拟器消息传输的
状态,需要在每个循环调用一次. protected Message getMessage(
String id) {},这个方法是通过传递ID号可以返回对应的报文.整个类中,基
本可以通过方法的名称和注释判断方法的作用,其大部分为对消息操作的
方法和返回路由信息,如消息的创建.
ActiveRouter.java:
这个类继承于MessageRouter这个类,是所有活动路由的超类,提供
一些查看消息状态和查看现有连接等信息的方法.该类有两个构造函数,可
以传递ActiveRouter,Settings两类参数进行路由对象的创建.除了继承于
MessageRouter的变量自已又定义了DELETE_DELIVERED_S,
boolean deleteDelivered(标记是否为传输最终结点用以删除),
String RESPONSE_PREFIX(回复信息的前缀修饰符),
int TTL_CHECK_INTERVAL(TTL检查时间间隔),double lastTtlCheck
(最后检查TTL的时间).
该类包含一些方法,如改变连接状态,请求传输消息,创建一个消息,接
收消息(重写),已传递消息(重写),开始传递消息,确定是否可以传递消息,
检查是否可以接收等方法.
DirectDeliverRouter.java:
这个路由类直接继承于ActiveRouter,没有定义多于的变量.重写了
update()这个方法.该方法如下:
public void update() {
super.update(); //调用父类方法
//判断是否可以传输,包括主机是否忙,是否能缓存,是否有可用连接
if (isTransferring() || !canStartTransfer()) {
return; // can't start a new transfer
}
// Try only the messages that can be delivered to final recipient
// exchangeDeliverableMessages() ,这个方法用于和目的主机交互消息
if (exchangeDeliverableMessages() != null) {
return; // started a transfer
}
}
EpidemicRouter.java:
该类继承于ActiveRouter,没定义多于变量,直接调用基类的构造函数,
重写了update()方法,该方法如下:
public void update() {
super.update(); //调用基类构造函数
//判断是否具备传输条件,包括主机是否忙,是否能缓存,是否有可用连接
if (isTransferring() || !canStartTransfer()) {
return; // transferring, don't try other connections yet
}
// Try first the messages that can be delivered to final recipient
//判断是否可以直接传输到目的结点
if (exchangeDeliverableMessages() != null) {
return; // started a transfer, don't try others (yet)
}
// then try any/all message to any/all connection
//尝试所有连接进行所有消息的传递,比DirectDeliverRouter多了这个方法.
this.tryAllMessagesToAllConnections();
}//这里需要强调一点,主机每次用可用连接只进行一组消息的传递,传递成功则返
//回,等待下一次update()方法的调用.
FirstContactRouter.java:
主机本地只有消息的单副本,一但有可用连接便进行传输且不接收已
经传递过的消息.该类继承于ActiveRouter,重写了
protected int checkReceiving(Message m){}了这个方法,用于判断是否
经过本节点,否则丢弃本消息.重写了update()方法,与EpidemicRouter
的update()方法一致. protected void transferDone(Connection con){}
这个方法用以清除已成功传递的消息,腾出缓存空间.
SprayAndWaitRouter.java
该算法将数据包的转发过程分为Wait 和Spray两个阶段,在不同阶
段采用不同的路由策略.该算法具有W,K,M 参数,恰当的参数设置可控
制Spray阶段的泛洪程度. Direct Delivery和Epidemic 算法分别代表了
两种极端情况,一种是不泛洪,另一种是无限制的泛洪.Spray and Wait
算法是按照一定策略有限度泛洪,从泛洪程度角度讲是介于Epidemic
和Direct Delivery中间的一种算法.
本路由算法有两个重要参数protected int initialNrofCopies,
protected boolean isBinary,用于初始副本数和判断是否采用Binary模式
. public int receiveMessage(Message m, DTNHost from) {},这个方法尝
试从其它结点接收消息.比较前面提到的算法,多了这个主动接收的方法.
此外还有public Message messageTransferred(String id, DTNHost
from) {},实现消息副本的减半; public boolean createNewMessage() {};
等多种方法.其update()方法中发送剩余消息的过程,为发送剩余消息副
本的过程(需要深入理解”散发-等待路由算法”).另外一个重要的方法是
protected void transferDone(Connection con) {},实现更新本地消息副
的数量.
总的概括来说,本路由的算法过程大概如:信源节点将产生的每个报文的
拷贝数初始化为L. 当 节点相遇并通信时,将自身报文拷贝数的一半转
发给相遇的中继节点即任何节点 A( 信源节点或中继节点) 中某个报
文的拷贝数为N ,如果遇到另一个没有该报文的节点 B,节 点会将此
报文拷贝一份给节点B ,并赋予的报文拷贝数N/2,同时节点A上的该报
文的拷贝数减为原来的一半.对于类似的算法完全可以借助这段代码的方
法去写.
EpidemicOracleRouter.java
EpidemicOracleRouter是改进的传染病路由算法,当一个消息投递到
目的结点,其它结点将会移除此消息. 在代码中,首先定义了一个代表所有
路由器的变量private static List<EpidemicOracleRouter> allRouters .
static {//定义的静态方法,具体作用我也不是太清楚.
DTNSim.registerForReset(EpidemicOracleRouter.class.getCanonicalName());
reset(); }
使用本算法进行模拟,首先应调用构造函数把本结点的路由加入到
allRouters 中来.方法如下:
protected EpidemicOracleRouter(EpidemicOracleRouter r) {
super(r);
allRouters.add(this); }
public void changedConnection(Connection con) {}//当有连接建立时,
进行消息传输.(这里的传输规则是什么,是否符合传染病算法??,接收本
地没有的消息),此外本算法还有
private void sendMessageToConnected(Message m) {}(利用连接发送
消息), public boolean createNewMessage(Message m) {}(新建消息.)
public Message messageTransferred(String id, DTNHost from) {},这个
方法首先判断是否为目的结点,如果是则删除所有路由上的该消息,否则进
行消息的投递. protected int checkReceiving(Message m) {},用于判断
主机是否想接收消息. protected void transferDone(Connection con) {}
,可以在这个方法里添加消息传输后的需要处理的事件(这个方法实际没有
被调用).
概括来说,这个算法update()这个方法没有实际用途,而是当有一个新
的连接或生成一个新的消息和接收到一个新消息时,传输便会发生,随
及传输将被初始化.当一个消息传递到目的结点时,其它结点的副本将会
一并删除.
总结:
分析模拟器自带代码的目的是为了能够更好的了解模拟器路由代码的
编写方式, 本人能力有限难免有错误,此文对于编写自己的路由算法有一定
的参考作用.如里路由算法与已提及的比较类似,大可以移植原有代码,提高
代码编写的效率.交流学习可以邮箱sunke706@163.com .
博文为本人所写,转载请证明出处 ONE路由协议模块分析与应用
,谢谢!!
,谢谢!!