ONE模拟器(Opportunistic Network Environment simulator)是一个机会网络模拟器,可以模拟机会网络中节点移动,节点路由,节点通信等功能,可在此基础上扩展实现网络攻击与安全防御,如入侵检测与信任管理等。可用于移动自组织网络、车辆自组织网络、无人机自组织网络等网络模拟仿真。模拟器基于Java语言,整体类比较多,以下是对代码的个人理解,包括代码调用链、重要参数以及部分类及其方法说明。
概要
- 节点移动:World.moveHosts()
- 通信链路连接与断开:SimpleBroadcastInterface.update()
- 事件生成:input.ExternalEvent.processEvent();
- 消息生成:时间、发给谁
- 消息转发,怎么转发:Router
- 图形化:DTNSimGUI.startGUI()
- 生成报告:Report类
代码调用链
core.DTNSim.main()
DTNSim.initSettings();
//读取配置文件
Settings.init();
Settings.addSettings();
//批处理
ui.DTNSimTextUI().start();//不用
//GUI
gui.DTNSimGUI.start();//调用的是父类ui.DTNSimUI的函数
ui.DTNSimUI.initModel();
//增加Report类
ui.DTNSimUI.addReport();
//移动模型预热
core.World.warmupMovementModel();
core.World.moveHosts();
core.DTNHost.move();
core.DTNHost.setNextWaypoint();
movement.MovementModel.getPath();//抽象函数,待扩充
gui.DTNSimGUI.runSim();
gui.DTNSimGUI.startGUI();//图形化不需要更改,没看
DTN2Manager.setup();//相关性不大,没看
world.update();
//循环处理间隔事件内所有事件
setNextEventQueue();
input.ExternalEvent.processEvent();//虚拟事件,需扩充
//移动节点
World.moveHosts();//和预热移动模型一样
//更新节点网络层和路由
World.updateHosts();
DTNHost.update();
//更新网络层(链路连接情况)
NetworkInterface.update();//抽象函数
//更新链路连接状态
interfaces.SimpleBroadcastInterface.update();
//断开旧连接
core.NetworkInterface.disconnect();
core.DTNHost.connectionDown();
routing.MessageRouter.changedConnection();//抽象函数
routing.ActiveRouter.changedConnection();//空函数,等待子类重写
//查找新连接
interfaces.SimpleBroadcastInterface.connect();
core.NetworkInterface.connect();
core.DTNHost.connectionUp();
routing.MessageRouter.changedConnection();//抽象函数
routing.ActiveRouter.changedConnection();//空函数,等待子类重写
//更新路由
MessageRouter.update();
core.Application.update();//抽象函数,待扩充
core.UpdateListener.updated();//接口,待扩充
ui.DTNSimUI.done();
gui.DTNSimGUI.update();//强制更新GUI
重要参数
仿真开始时间(批处理):core.DTNSim.main().startTime
仿真时间间隔(批处理):core.DTNSim.main().duration
默认配置文件:core.Settings.DEF_SETTINGS_FILE
路由:core.DTNHost.router
部分类及其方法说明
core.DTNSim
main()
- 确定是批处理模式还是GUI模式,批处理模式参数格式:-b(运行次数/开始运行:运行次数);GUI参数格式:运行索引
- 分别确定从哪里开始运行,运行多少次
- 根据输入参数初始化配置文件
- 批处理模式:调用Settings类对运行设置,调用TextUI
GUI模式:调用Settings类对运行设置,调用GUI
initSettings()
调用Settings.init()和Settings.addSettings()对配置文件初始化
registerForReset()
将需要重置的类放进resetList
core.Settings
- Settings类应该先初始化,否则该类只读取默认配置文件。
- 所有设置都是key-value对,value可以是单独的值,也可以是逗号分隔的多个值(comma separated value, CSV), CSV不能以“(”“)”作为开头结尾
init()
所有属性都得先用这个函数初始化。
- 从默认配置文件和自定义配置文件得到属性值
- 根据key得到需要的value,并将其转化为输出流
addSettings()
增加新的配置属性,参数为属性文件的路径
setRunIndex()
设置配置开始运行的索引值,只适用于有运行数组的情况下。参数为-1表示禁用该运行数组,参数为0到数组长度-1根据数组索引取值,参数大于等于数组长度,对数组长度模除取值。
getSetting()
将“Namespace+配置名”作为key,在属性中寻找对应的配置值value。命名空间先用namespace,找不到再用secondaryNamespace。
createObject()
使用不带任何参数的构造函数创建(并动态加载类)对象。调用loadObject()方法。
loadObject()
根据类名(包含包名)、构造函数参数、参数的类三个参数动态加载创建对象。调用getClass()根据类名(包含包名)得到类,再调用getConstructor()得到构造函数,然后得到构造器的一个实例返回。
getClass()
根据类名(包含包名)得到类
contains()
判断某一特定属性有没有被设置,且存在值。存在返回true,不存在返回false。
getDouble()
调用parseDouble()根据目标属性名得到double类型的属性值
parseDouble()
解析String类型的值(后缀可以是千k,兆M,千兆G)得到double类型的值。
参数是需要转化的值和该值所属的属性(用于输出异常信息)
setNameSpace()
设置namespace
restoreNameSpace()
还原为上一个namespace
ui.DTNSimUI
start()
调用initModel()和runSim()
initModel()
初始化模拟器模型
- 得到仿真场景设置值
- 增加report类:调用addReport(),根据report的类型(MessageListener、ConnectionListener、MovementListener、UpdateListener、ApplicationListener)增加对应的监听器
- 移动模型预热:在设置了移动模型预热时间的情况下,调用world.warmupMovementModel让节点在建立连接前移动一段时间,对节点位置进行初始化
gui.DTNSimGUI
runSim()
- 运行图形化界面
- DTN2Manager.setup(world);
- 如果运行暂停,则将线程暂停10毫秒并释放CPU资源,否则调用world.update()
- 调用done()结束进程
- 最后更新GUI
update()
更新GUI。
core.SimClock
getInstance()
没有参数,得到SimClock的一个实例并返回。
setTime()
根据输入的值设置clock的时间,值必须为-time
getTime()
没有参数,返回当前时间
advance()
根据输入的时间参数将当前时间提前
core.SimScenario
getWorld()
无参数,返回world对象
core.World
warmupMovementModel()
根据给定的时间对节点位置进行初始化,SimClock必须提前被设置为-time。
setNextEventQueue()
遍历所有的事件队列,寻找包含有下一事件的队列,找到后更新nextEventQueue和nextQueueEventTime。
update ()
- 调用input.ExternalEvent.processEvent()循环处理该段时间内的所有事件
- 调用moveHosts()移动节点
- 调用updateHosts()更新节点网络层和路由
- 调用接口core.UpdateListener.updated()更新所有的监听器
moveHosts()
调用DTNHost.move()方法移动所有节点,参数为节点移动时间,传给了move()方法。
setNextWaypoint()
设置下一步的目的地和速度,设置好了返回true,还需等待返回false。
updateHosts()
判断节点是否随机更新,然后调用DTNHost.update()更新节点网络层和路由情况。
core.DTNHost
move()
节点没有激活或者没到移动时间退出,没有目的地且调用setNextWaypoint()返回false退出。用移动时间乘以速度得到可能移动距离,如果移动距离大于该节点到下一个目的地的距离,则一直让该节点移动到下一个节点(位置坐标设为下一个目的地),直到没有下一个waypoint为止。如果移动距离小于到下一个目的地的距离,则按比例往那个方向移动相应的距离,并更改位置坐标。
update()
更新节点网络层和路由情况。节点没有激活,退出。调用NetworkInterface.update()更新节点网络层情况(节点连接情况),NetworkInterface.update()是一个抽象类,SimpleBroadcastInterface.update()对其进行了实现,调用MessageRouter.update()更新路由情况。
connectionDown()
调用routing.MessageRouter.changedConnection(),告诉路由节点的链路变化。
connectionUp()
调用routing.MessageRouter.changedConnection(),告诉路由节点的链路变化。
core.Coord
distance()
根据输入的坐标参数,计算出和当前坐标的直线距离
translate()
当前坐标加上参数坐标值(x加x,y加y)
core.NetworkInterface
update()
抽象类,SimpleBroadcastInterface.update()中实现,对连接状态进行了更新。
disconnect()
更改链路状态为false,通知监听器链路的变化,检查另一端网络接口能否移除链路,不能的话抛出异常。然后两端节点都调用DTNHost.connectionDown()断开链路。
connect()
将节点与另一个节点连接,调用该函数前需要检查是否满足建立连接的所有先决条件。
- 将新链路添加到链路的链表中
- 通知监听器
- 另一端网络接口也将该链路添加到链路表里
- 调用 core.DTNHost.connectionUp()激活链路
isScanning()
检查网络接口是否处于扫描模式。没懂扫描模式用来干嘛的
interfaces.SimpleBroadcastInterface
update()
调用NetworkInterface.disconnect()断开旧连接,再调用SimpleBroadcastInterface.connect()寻找新连接。
connect()
连接在当前节点通信范围内的激活的节点。先根据两端网络接口确定传输速度(二者中小的那个),然后new一个CBRConnection类型的链路,再调用NetworkInterface.connect()让两个节点连接。
routing.MessageRouter
update()
更新路由,每次仿真间隔至少更新一次。