[TOC]
ONE程序代码简析
Routing
所有的路由的实现都基于了MessageRouter
这个基本的抽象类,所以我们首先关注这个抽象类
MessageRouter
这是一个抽象类,使用了public abstract class 来进行声明。其主要定义了如下变量,主要包括了buffer size , TTL 和传输队列,包括传输和接收的信息反馈等。
1 | //message buffer size |
然后定义了如下的一些主要函数(方法):
MessageRouter(Setting s)
根据配置文件default_setting.txt
进行读取并创建相应的mesage router。
init(DTNHost,List)
初始化一个router , 设定这个router 在具体的哪个host 当中 和当该router 发送消息时所有需要被通知的message listener 。
update()
当进行更新的时候,其实际上是向上层传递(应用层),然后让相应需要更新的应用层进行更新。
sendMessage(String , DTNHost)
在这里比较需要进行关注的点在于,要发送的信息不能是当前信息,而需要对其进行拷贝:m2 = m.replicate()
,然后再进行发送。包括在receiveMessage中也会进行相应的拷贝,要注意这一含义,否则则有可能进行了深拷贝,那么message进行修改的时候就会导致相应的错误。
messageTransferred()
通过判断当前接收到的message是否是到达目的地,来决定是否要进行转发,同时会调用到上层的application 来决定其是否需要drop掉它。
sortByQueueMode
1 | "unchecked") /* ugly way to make this generic */ (value = |
这里根据两种不同的方式 Q_MODE_RANDOM 和Q_MODE_FIFO 来进行的排序。同样的 compare 也是依据这两种不同模式来分别进行比较的。
ActiveRouter
主动路由的超类(实际上是被动路由),继承自MessageRouter。
update()
关于更新,主要分为了这样几步,首先是调用了MessageRouter 实现的update函数,然后查找所有的sendingConnections
,然后检测该connection
是否已经传输过信息,根据此决定是否是否已经传输完成(transferDone),如果当前的connection
已经关闭,那么就abort掉,如果有需要进行remove的,那么根据相应的信息进行移除,最后将已经过期的信息从当前的buffer中移除。
1 |
|
PassiveRouter
PassiveRouter , 实际上是我们所讲的主动路由,即不发送任何消息除非在需要的时候,即只有在需要发送message的时候才进行路由表的查找。这对于一些外部事件是比较有效的一种路由方式,同样地,其继承于MessageRouter
。其没有增加任何相应的变量。
DirectDeliveryRouter
继承自ActiveRouter ,是一种具体的被动路由,路由器只会向最终的router 发送相应的message,而不是采用广播的方式进行。 这里只是对update进行了相应的补充,即如果正在传输或者当前路由无法传输,不需要更新;然后去检测是否能到最终的接收方,并根据此进行判断。
EpidemicOracleRouter
同样继承自ActiveRouter,这个router 利用相应的数据库保存了message是何时被传输的,并且何时被所有节点移除的。(所有使用该路由的节点)。所有信息都是立即发出。
其增加了一个新的变量List<EpidemicOracleRouter> allRouters
,来记录所有使用该路由的节点。
注意此处:
1 | public EpidemicOracleRouter(Settings s) { |
利用setting 进行初始化的时候没有调用allRouters.add(this)
,因为利用setting 进行初始化的时候实际上可以视作建立的是一个template,只用于后面的其它路由的建立。
1 | public Message messageTransferred(String id, DTNHost from) { |
这个函数的实现,主要是多加了这样一个部分,即当到达的时候-> (m.getTo() == this.getHost()),那么就删掉所有不是该路由自身或者传递过来的路由的其它路由的相应该信息,否则就传递给connection。
EpidemicRouter
每次只有单个的传输连接,并且会抛弃之前的buffer中的内容。
1 | public void update() { |
可以看到,其首先会尝试传输给最终需要接收的节点,如果无法直接传输到,那么就会传给所有相应的connections,相当于是一个广播的方式。
FirstContactRouter
这个router 只用message 的一个copy 来进行传输,一直到第一个可用的contact。
1 | protected int checkReceiving(Message m, DTNHost from) { |
由于是first contact ,所以只接收一次相关的message,而不是每次都接收。
LifeRouter
Router module mimicking the game-of-life behavior, 也就是模拟game-of-life 的方式来进行route。
新增加了两个变量:
1 | public static final String NM_COUNT_S = "nmcount"; |
nmcount
指的是neighboring message count , count_range
是一个最小值和最大值,并且用逗号分开。
实现了一个新的函数:getPeerMessageCount(Message m)
1 | private int getPeerMessageCount(Message m) { |
计算有多少个connected peers 拥有这个Message
对于update 函数而言,其为:
1 | public void update() { |
跟前一个而言,其最大的不同在于需要检查是否需要drop 相应的message,即看当前的message 是否超过了设定的范围,如果超过了相应的范围,就会有:messagesToDelete
MaxPropRouter
这是一种基于车联网的路由方式,是一种能够disruption-tolerant 的网络。同样继承自ActiveRouter,这个协议的扩展是通过添加一个参数$\alpha$来进行实现的。对于一个新的connection, 它的传递的可能性为 $\frac{\alpha \times p}{1+\alpha}$。
新增变量
1 | // setting 文件中的名字空间 (name) |
新增的变量,主要是为了实现相应的传播可能性的计算,以及所传输的相应信息,包括传送到的具体位置,以及传输的平均bytes(每次传输机会)。
对于此,有一些相应的补充,即为了实现MaxPropRouter
而实现的两个相应类,具体在routing.maxprop
的package之中,具体为下:
MeetingProbabilitySet
这个类主要是为了存储和对meeting probabilities
的进行操作。
其中一个最重要的函数为updateMeetingProbFor()
,其具体作用是更新meeting probability 对于一个给定的node index。
可以看到,对于第一个,其可能性为1 ,如果某个结点node 进行了更新,那么其会增加,但是为了保证所有的可能性之和为1,所以会除以$\alpha + 1$,最后做了一个异常的处理,即超出相应的范围。
1 | public void updateMeetingProbFor(Integer index) { |
MaxPropDijkstra
这个类,实际上就很简单,其实就是利用相应的信息,使用dijkstra算法去找到最短的路径。其中,一个重要的函数时relax(Integer)
函数,其作用就是relax 一个结点的所有邻居,即更新最短路径:
1 | private void relax(Integer node) { |
可以看到,首先需要得到当前的neighbors,然后去检查是否其已经被访问过,否则进行相应的distance 的更新,然后去判断是否当前是最短路径,如果是,那么进行修改。实际上就是一个Dijkstra算法的具体情况下的实现。
MaxPropRouterWithEstimation
这个路由协议和MaxPropRouter最大的不同在于其通过参数估计(估计alpha)来找到一个合适的值,基于时间量程的定义(timescale definition),对于整个其它方面,其和MaxPropRouter具有相同的含义
其一个最重要的函数时updateParam()
updateParam()
1 | protected void updateParam() |
在这一段中,其主要的重点在于while循环中,即while(ee!=eer)
,总体而言,即通过对于meanENC 和 alphadiff 等参数来估计,最终设定所得到的alpha
。
ProphetRouter
实现的是PRoPHET 路由算法,同样基于的是ActiveRouter。
新增变量
1 | public static final double P_INIT = 0.75; |
总体而言,其主要增加了这样几个不同的量,即secondsInTimeUnit
以及 $\beta \quad \gamma$,以及最后增加的一个Map,和一个记录最后一次更新的时间。
updateDeliveryPredFor()
1 | private void updateDeliveryPredFor(DTNHost host) { |
可以看到,这是对于delivery preictions 的相应更新实际上是: $P(a,b) = P(a,b)_{old} + (1-P(a,b)_{old}) \times P_INT$
updateTransitivePreds()
关于transitive ,其具体是这样一种方式,即(A->B->C) 的传输,对于其相应的predictions的计算,具体为:$P(a,c) = P(a,c)_{old} + (1 - P(a,c)_{old}) P(a,b) P(b,c) * \beta$
1 | private void updateTransitivePreds(DTNHost host) { |
可以看到,对于delivery 和 transitive的更新和相应的衰减(age),基于了两个相应的参数,即$\beta 和 \gamma$,以及$P_INT$
ProphetRouterWithEstimation
这个版本和上面所给出的ProphetRouter 的不同在于其尝试通过估计来得到一个好的值。 其具体实现函数为updateParam()
,具体内容可以参考源码,可以通过其更新pinit
,gamma
。
ProphetV2Router
关于这一个路由协议,可以具体参看:http://tools.ietf.org/html/draft-irtf-dtnrg-prophet-09