/**
* <P>
* Overlay grid of the world where each interface is put on a cell depending
* of its location. This is used in cell-based optimization of connecting
* the interfaces.</P>
*
* <P>The idea in short:<BR>
* Instead of checking for every interface if some of the other interfaces are close
* enough (this approach obviously doesn‘t scale) we check only interfaces that
* are "close enough" to be possibly connected. Being close enough is
* determined by keeping track of the approximate location of the interfaces
* by storing them in overlay grid‘s cells and updating the cell information
* every time the interfaces move. If two interfaces are in the same cell or in
* neighboring cells, they have a chance of being close enough for
* connection. Then only that subset of interfaces is checked for possible
* connectivity.
* </P>
* <P>
* <strong>Note:</strong> this class does NOT support negative
* coordinates. Also, it makes sense to normalize the coordinates to start
* from zero to conserve memory.
*/
public class ConnectivityGrid extends ConnectivityOptimizer {
上面是TheOne中对连接网格的介绍,节点运动对应坐标改变,坐标改变需要更新连接关系,对于某一个节点来说,如果没有连接网格的支持,需要遍历所有的节点来判断两者是否满足传输range的要求,来决定能否建立connection,这显然不可扩展scale,因为随着网络的增大,这种检测将变得不可行。
所以采用一种网格,将节点对应到网格内,这样每次检测某个节点能否和其它节点建立连接,只需要检测本网格和邻居网络的节点即可。
有点类似Opnet的rxgroup。
/**
* Notifies all the connection listeners about a change in connections.
* @param type Type of the change (e.g. {@link #CON_DOWN} )
* @param otherHost The other host on the other end of the connection.
*/
private void notifyConnectionListeners(int type, DTNHost otherHost) {
if (this.cListeners == null) {
return;
}
for (ConnectionListener cl : this.cListeners) {
switch (type) {
case CON_UP:
cl.hostsConnected(this.host, otherHost);
break;
case CON_DOWN:
cl.hostsDisconnected(this.host, otherHost);
break;
default:
assert false : type; // invalid type code
}
}
}上面的代码是在NetworkInterface下,能够通知所有的连接监听成员当前连接的变化情况。# The Tram groups Group4.groupID = t Group4.bufferSize = 50M Group4.movementModel = MapRouteMovement Group4.routeFile = data/tram3.wkt Group4.routeType = 1 Group4.waitTime = 10, 30 Group4.speed = 7, 10 Group4.nrofHosts = 2 Group4.nrofInterfaces = 2 Group4.interface1 = btInterface Group4.interface2 = highspeedInterface
一个节点可能有多个接口,比如上面默认配置文件中的Tram有连个interface,一个蓝牙,一个高速接口
整个运行流程:
GUI运行runSim,运行world.update,其中运行updateHosts,其中运行更新网络接口连接和路由模块,相当于是由节点的运动来驱动整个连接数据的更新和路由的运行。
DTNSim.java中调用:
new DTNSimGUI().start();
public void start() {
initModel();
runSim();
} /**
* Initializes the simulator model.
*/
private void initModel() {
Settings settings = null;
try {
settings = new Settings();
this.scen = SimScenario.getInstance(); /**
* Returns the SimScenario instance and creates one if it doesn‘t exist yet
*/
public static SimScenario getInstance() {
if (myinstance == null) {
myinstance = new SimScenario();
}
return myinstance;
}/**
* Creates a scenario based on Settings object.
*/
protected SimScenario() {
Settings s = new Settings(SCENARIO_NS);
nrofGroups = s.getInt(NROF_GROUPS_S);
this.name = s.valueFillString(s.getSetting(NAME_S));
this.endTime = s.getDouble(END_TIME_S);
this.updateInterval = s.getDouble(UP_INT_S);
this.simulateConnections = s.getBoolean(SIM_CON_S);
ensurePositiveValue(nrofGroups, NROF_GROUPS_S);
ensurePositiveValue(endTime, END_TIME_S);
ensurePositiveValue(updateInterval, UP_INT_S);
this.simMap = null;
this.maxHostRange = 1;
this.connectionListeners = new ArrayList<ConnectionListener>();
this.messageListeners = new ArrayList<MessageListener>();
this.movementListeners = new ArrayList<MovementListener>();
this.updateListeners = new ArrayList<UpdateListener>();
this.appListeners = new ArrayList<ApplicationListener>();
this.eqHandler = new EventQueueHandler();
/* TODO: check size from movement models */
s.setNameSpace(MovementModel.MOVEMENT_MODEL_NS);
int [] worldSize = s.getCsvInts(MovementModel.WORLD_SIZE, 2);
this.worldSizeX = worldSize[0];
this.worldSizeY = worldSize[1];
createHosts();
this.world = new World(hosts, worldSizeX, worldSizeY, updateInterval,
updateListeners, simulateConnections,
eqHandler.getEventQueues());
}runSim函数:
protected void runSim() {
double simTime = SimClock.getTime();
double endTime = scen.getEndTime();
startGUI();
// Startup DTN2Manager
// XXX: Would be nice if this wasn‘t needed..
DTN2Manager.setup(world);
while (simTime < endTime && !simCancelled){
if (guiControls.isPaused()) {
wait(10); // release CPU resources when paused
}
else {
try {
world.update();
} catch (AssertionError e) {
// handles both assertion errors and SimErrors
processAssertionError(e);
}
simTime = SimClock.getTime();
}
this.update(false);
}/**
* Update (move, connect, disconnect etc.) all hosts in the world.
* Runs all external events that are due between the time when
* this method is called and after one update interval.
*/
public void update () {
double runUntil = SimClock.getTime() + this.updateInterval;
setNextEventQueue();
/* process all events that are due until next interval update */
while (this.nextQueueEventTime <= runUntil) {
simClock.setTime(this.nextQueueEventTime);
ExternalEvent ee = this.nextEventQueue.nextEvent();
ee.processEvent(this);
updateHosts(); // update all hosts after every event
setNextEventQueue();
}
moveHosts(this.updateInterval);
simClock.setTime(runUntil);
updateHosts();
/* inform all update listeners */
for (UpdateListener ul : this.updateListeners) {
ul.updated(this.hosts);
}
}/**
* Updates all hosts (calls update for every one of them). If update
* order randomizing is on (updateOrder array is defined), the calls
* are made in random order.
*/
private void updateHosts() {
if (this.updateOrder == null) { // randomizing is off
for (int i=0, n = hosts.size();i < n; i++) {
if (this.isCancelled) {
break;
}
hosts.get(i).update(simulateConnections);
}
}/**
* Updates node‘s network layer and router.
* @param simulateConnections Should network layer be updated too
*/
public void update(boolean simulateConnections) {
if (!isActive()) {
return;
}
if (simulateConnections) {
for (NetworkInterface i : net) {
i.update();
}
}
this.router.update();
} /**
* Updates router.
* This method should be called (at least once) on every simulation
* interval to update the status of transfer(s).
*/
public void update(){
for (Collection<Application> apps : this.applications.values()) {
for (Application app : apps) {
app.update(this.host);
}
}
}
for (NetworkInterface i : net) { i.update();
NetworkInterface 会更新,比如这个是SimpleBroadcastInterfaceextends NetworkInterface,首先会断掉超出距离的连接,然后会找新的连接,这里用到了连接网格优化器:optimizer.getNearInterfaces(this); 通过这个函数返回所有可能建立连接的网络接口
/**
* Updates the state of current connections (ie tears down connections
* that are out of range).
*/
public void update() {
// First break the old ones
optimizer.updateLocation(this);
for (int i=0; i<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<NetworkInterface> interfaces =
optimizer.getNearInterfaces(this);
for (NetworkInterface i : interfaces) {
connect(i);
}
}/**
* Tries to connect this host to another host. The other host must be
* active and within range of this host for the connection to succeed.
* @param anotherInterface The interface to connect to
*/
public void connect(NetworkInterface anotherInterface) {
if (isScanning()
&& anotherInterface.getHost().isActive()
&& isWithinRange(anotherInterface)
&& !isConnected(anotherInterface)
&& (this != anotherInterface)) {
// new contact within range
// connection speed is the lower one of the two speeds
int conSpeed = anotherInterface.getTransmitSpeed();
if (conSpeed > this.transmitSpeed) {
conSpeed = this.transmitSpeed;
}
Connection con = new CBRConnection(this.host, this,
anotherInterface.getHost(), anotherInterface, conSpeed);
connect(con,anotherInterface);
}
}最后调用基类NetworkInterface的connect函数:connect(con,anotherInterface); 因为参数不同,可以用相同的函数名/**
* Connects this host to another host. The derived class should check
* that all pre-requisites for making a connection are satisfied before
* actually connecting.
* @param con The new connection object
* @param anotherInterface The interface to connect to
*/
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结构图,来源:http://www.cnblogs.com/dreamfactory/archive/2012/07/27/2612215.html
原文:http://blog.csdn.net/yanhc519/article/details/18272691