消息转发过程(上)

转载自 吕博的博客

网址为 http://blog.sina.com.cn/s/blog_48ded66a01018sho.html


TheONE全称为The Opportunistic Network Environment simulator,是一款Java平台的容迟网络仿真软件,本文采用一条纵线分析了TheONE中消息转发的流程。


1. 消息转发的入口

    跟踪发包流程最主要的是找到入口,ONE与NS2最大的区别在于:NS2是离散事件驱动的,而ONE采用的是周期更新即Update,如果把网络中的事件比喻成出门坐车,那么NS2像是打车,招手即停,而ONE是坐公交,公交车每隔一段时间来一班,这个时间间隔就是Update的周期,在default_setting.txt中定义为0.1秒(Scenario.updateInterval=0.1)。于是最先要找到的就是update函数。ONE核心的功能可以看作由两大部分组成,一是移动,二是消息转发,简而言之,前者根据移动模型确定下一时段各节点的位置坐标,后者根据接口和路由来决定节点是否应该收到一个消息。本文讨论的是消息转发流程,因此忽略节点移动部分,直接找到消息转发的入口。

    DTNHost是ONE中最基本的类,它定义了一个节点(后文将节点与Host等同)的基本属性和基本功能,在DTNHost.java中的update()函数负责更新网络接口和路由。

 public void update(boolean simulateConnections) {      
       if (!isActive()) {   //如果节点处于非激活状态,则不会执行后面的语句
           return;       //可以将非激活状态想象成一个自私节点或者没电的传感器
       }
       if (simulateConnections) {
           for (NetworkInterface i : net) {
              i.update();       //更新所有的接口
           }
       }
       this.router.update();    //更新路由
}

   

可以看出在update()中先更新了接口,后更新了路由,原因是路由的工作需要建立在接口的基础之上。本文也先说接口,后说路由。

2. 维护有效的连接

    首先要解释ONE中的一个最基本的概念――连接(Connection/Connect)。由于ONE并不侧重于底层信道的仿真,因此空中接口的概念已经淡化了,取而代之的是“连接”。简单的理解,当两个节点在彼此通信范围之内,连接就认为是建立的,ONE习惯中用UP表示,反之用DOWN。ONE中提供了一系列函数用于维护所有节点之间的连接。详细情况可以读一下connection.java。

    一个最基本的连接包括了:

    protected DTNHost toNode;                 //连接的目的节点
    protected NetworkInterface toInterface;   //连接的目的接口
    protected DTNHost fromNode;               //链接的源节点
    protected NetworkInterface fromInterface; //链接的源接口
    protected DTNHost msgFromNode;            //消息的源节点
    private boolean isUp;                     //最重要的是连接的当前状态
    protectedMessage msgOnFly;               

























                           
//连接正在传输的消息实际上,仿真中通常使用的是CBRConnection类,这个类继承自Connection ,扩展了:
    private int speed;                     //CBR流的传输速度
    private double transferDoneTime;       //传输完成的时间 

    回到update的问题上,更新接口执行的是网络接口的更新函数,在NetworkInterface类中update()是一个空函数,实际上更新的是它子类中的update()函数。在实际仿真中,经常采用SimpleBroadcastInterface作为接口类型(实际上ONE也没给我们太多的选择),因此SimpleBroadcastInterface.java中的更新函数是维护连接的关键。

public void update() {
       // First break the old ones
       optimizer.updateLocation(this);
       for (int i=0; i<</span>this.connections.size(); ) {      //遍历所有连接
           Connection con = this.connections.get(i);
           NetworkInterface anotherInterface = con.getOtherInterface(this);
           // all connections should be up at this stage
           assert con.isUp() : "Connection " + con + " was down!";
 
           if (!isWithinRange(anotherInterface)) {       //删除已经断开的连接
              disconnect(con,anotherInterface);
              connections.remove(i);
           }
           else {
              i++;
           }
       }
       // Then find new possible connections
       Collection interfaces =
           optimizer.getNearInterfaces(this);
       for (NetworkInterface i : interfaces) {       //建立新的连接
           connect(i);
       }
    }

    这个函数的思想很简单,首先检索所有已经建立好的连接,将其中已经断开的连接删除,再找到新的可以建立的连接。这路重点需要看的是两个函数:

    isWithinRange()目的是判断两个接口所在的节点是否在彼此的通信范围之内,这个函数是路由与移动模型交互的地方,在仿真脚本中设置的接口传输距离、移动模型都会最这个函数的返回值产生影响。

    connect()函数是建立连接的函数,在SimpleBroadcastInterface类中,建立连接并不简单,需要满足一系列条件才能建立,这些条件主要是:确保接口处于扫描状态、确保节点处于活跃状态、确保两接口所在节点彼此能通信、确保两接口不是已经连接的、确保两接口不是同一接口:

public void connect(NetworkInterface anotherInterface) {
           if (isScanning()
                  && anotherInterface.getHost().isActive()
                  && isWithinRange(anotherInterface)
                  && !isConnected(anotherInterface)
                  && (this != anotherInterface)) }


    满足这些条件的两个接口能够成功建立连接,连接建立的过程包括:将连接con添加到本节点和对方节点的connections中、将本节点和对方节点con的状态设置为UP、通知Listener连接con已经建立。在ONE中,多种Listener用于统计网络性能,生成Reports,刚开始看代码的时候,可以将所有与Listener有关的语句都忽略。

protected void connect(Connection con, NetworkInterface anotherInterface) {
       this.connections.add(con);
       notifyConnectionListeners(CON_UP, anotherInterface.getHost());
 
       // set up bidirectional connection
       anotherInterface.getConnections().add(con);
 
       // inform routers about the connection
       this.host.connectionUp(con);
       anotherInterface.getHost().connectionUp(con);
    }

    连接维护的实际过程要比上面所说的稍复杂,但核心思想很简单:节点周期检查自己与周围节点的位置,与满足传输条件的节点的对应接口建立连接。需要补充的是,连接的建立实际上是以接口为单位的,不是与节点为单位的,因为一个节点可以有多个接口,而不同种类接口的传输距离不同。


你可能感兴趣的:(one,the)