热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Dtnsim2学习笔记

1、DTNMED平均等待时间计算公式下面这段代码是在dtnsim2中的packageprotocolStack.globalKnowledge;下的contactschedule

1、DTN MED平均等待时间计算公式

下面这段代码是在dtnsim2中的packageprotocolStack.globalKnowledge;下的contactschedule中,有一个计算MED时间的函数

/** Computes the MED metric assuming that time begins at startTime. */
public double getMEDWeight(double simTime)
{
if (nextUpTime != null)
{
throw new RuntimeException("ContactSchedule is not closed");
}
double downSquaredSum = 0;
double lastTime = 0;
for (UpTime up : times)
{
if (up.getTimeUp() != 0)
{
assert up.getTimeUp() > lastTime;
double downTime = up.getTimeUp() - lastTime;
assert downTime > 0;
downSquaredSum += downTime * downTime;
}
lastTime = up.getTimeDown();//仅仅统计down的时间长度
}
// Add the very last down time
double downTime = simTime - lastTime;
if (downTime > 0)
{
downSquaredSum += downTime * downTime;
}
double ret = (double) (downSquaredSum / (2 * simTime)) + contact.getLatency();
return ret;
}

在example-simple-readme中有下面情景

This scenario has four nodes: A, B, C, D. Band C are permanently connected to

D. A <-> B has a down interval of 40,and an up interval of 20 (MED = 13.3).

A <-> C has adown interval of 20, and an up interval of 5 (MED = 8).

对于AB之间的链路调度如下:

0      40  60     100 120

start  up  down   up  down

 

通过手动计算可以知道0-40期间平均等待时间为40/2=20,而40-60期间平均等待时间是0,所以整个60s的周期中平均等待时间为:20*(40/60)&#43;0*(20/60)=13.3

上面函数中downSquaredSum统计了链路中断持续时间的平方,最后又除以2倍的simTime,让人有点摸不着头脑,其实是这样的:(downtime/2) * (downtime/simtime)

即在中断时间的平均等待时间乘以中断时间占整个时间的百分比。在MEED的硕士论文中提到了如何计算。

2、如何运行dtnsim2

在console界面下进入到E:\Network\ONE\Eclipseprj\dtnsim2的examples/simple目录下,运行如下命令行:

java -ea -cp ../../bin/lib simulator.Main-verbose 1 simple_MED

verbose冗长的、啰嗦的,Setthe amount of logging output that should be generated

bubuko.com,布布扣

其中ea不知道什么意思,cp表示查找类的路径,后面的-verbose设置输出调试信息的数量,最后的simple_MED表示要读取的配置文件,如下所示:

bubuko.com,布布扣

上述文件设定了带宽、延迟,什么时刻做什么工作,设置node类型、schedule文件、运行文件,最后设置了输出统计数据

 

其中的simple_Times文件如下:

bubuko.com,布布扣

运行完后,即可在该目录下生成simple_stats统计输出文件:

Algo;  Buffer_Size;  Message_Size; Bandwidth; Latency;   Total_Msgs;   Delivered_Msgs;    Deliv_Ratio;  Avg_Time

MED;   2000;  50; 10; 2;  2;  2;  100.00%;   26.50


如果是在Eclipse下运行的话,当前的路径是如下目录

E:\Network\ONE\Eclipseprj\dtnsim2

在设置argument参数时应该设置为:-verbose 1 examples/simple/simple_MED

3、程序解读

程序运行流程,simulator包下有一个Main,会读取运行参数:

if (args[i].charAt(0) != ‘-‘)
{
// Until first linewith specified time, all lines in input
// will beinterpreted immediately.
(new InputReader(net, args[i])).runInput(-1);
}

上面这个把simple_MED文件中@0之前的配置读取完毕

 

runInput函数会对simple_MED文件进行解析,一句话一句话进行解析,语句分为注释#时间@和命令

publicvoid runInput(double curTime)

比如default_cOntactbandwidth= 10 latency = 2

这句话是对contact进行参数配置,是一个命令

会一步一步的测试各种命令:

l  测试是否是本地命令,看是否有interpreter,下是否有run_file
cs = checkLocalCmds(line,curTime);

l  下一步测试cs =line.execCommand();在InputLine类中

 

1) 测试网络层的命令,network.parseLocalCommand();有network_element,traffic,stats,simulator,network_graph等

2) 测试节点层的命令,parseNodeCommand();有default_node等

3) 测试contact连接的命令,parseContactCommand();,在findContactsForCommand()下有default_contact

 

在contact,stat类下都有commandparser方法,用于解析配置文件中的命令

 

 

运行到如下函数fire处时,将开始执行网络仿真,其实是开始执行@0后的语句命令或配置。

需要执行receiver.receiveEvent(this);,其中receiver定义为EventReceiver,而EventReceiver为一个接口类,找不到其接口实现函数?

public class Event
{
protected long seq = 0;
protected double time = 0;
protectedEventReceiver receiver = null;
public void fire(Simulator net)
{
if (receiver == null)
return;
receiver.receiveEvent(this);
}
 

经过调试发现执行的是publicclass InputReader
implements EventReceiver

public void receiveEvent(Eventevent)
{
runInput(event.getTime());
}

在runInput中会simple_MED文件内容,并按照其内容进一步读取其它文件,或执行相关命令。

  

消息发送

在ProtocolStackNode类下有sendNewMessage方法

4、路径计算相关

路由模块的routeForMsg(ProtocolStackMessage msg)方法会调用topology.getRoute(msg);

接着,会调用GKnowledgeTopologyHandler类下的getRoute(msg);

接着,会调用此函数进行计算的初始化lastRouting = new NetworkDijkstra(networkGraph(), parent,network.getCurrentTime(), forMsg);

接着,会调用lastRouting.routeTo((ProtocolStackNode)forMsg.getDestNode());进行真正的路由计算

 

NetworkGraph,一个抽象类,定义了一些Dijkstra可能会用到的方法:获取邻节点、得到代价

DijkstraGraph,一个接口类,与NetworkGraph差不多

NetworkDijkstra,直接调用的父类Dijkstra的构造函数,这个主要是对Dijkstra计算进行一下初始化

    routeTo(NodeTypeendPoint)该函数负责计算到endPoint的路径

       该函数又调用了computeShortestPath(endPoint);,此函数是Dijkstra计算所在地

 

 

下面的这种HashMap,索引是节点,索引&#20540;是源节点到该节点的路径的信息,一种哈希映射

private HashMaprouteInfoMap = new HashMap();

 

下面这个GKnowledgeTopologyHandler继承了抽象类TopologyHandler

GKnowledgeTopologyHandler extendsTopologyHandler

GKnowledgeTopologyHandler类下有getRoute方法,此方法会新建NetworkDijkstra类,并调用routeTo方法

 

在下面RouteRoutingHandler类下有routeForMsg(ProtocolStackMessage msg)方法,此方法调用了route = topology.getRoute(msg);

 

 

ProtocolStackNode的方法sendNewMessage

    创建一个新的消息:msg = new ProtocolStackMessage(。。destNode, dataLength);

    然后,接收新消息:ret = acceptNewMessage(msg);

    然后进入RouteRoutingHandler类下的acceptNewOwnMessage方法,新消息、自己产生

然后是addMessage(msg),在这里会判断本地节点还有没有足够的buffer,如果有,那么加入buffer,至此,新消息已经产生

 

调用父母parent节点ProtocolStackNode的方法notifyNewMessage,在这里会遍历所有的eventHandlers的新消息到达通知,

通过这些又触发路由模块RouteRoutingHandler的notifyNewMessage,在路由模块的新消息到达函数里会执行routeForMsg(msg);

ProtocolStackNode::notifyNewMessage(ProtocolStackMessage msg)
{
for (EventHandler handler : eventHandlers)
{
handler.notifyNewMessage(msg);
}
}
public boolean addMessage(ProtocolStackMessage msg)
{
// We are willing to store any message, as long as we have space in
// the buffer:
if (!parent.canAllocateCapacity(msg, this))
{
return false;
}
parent.allocateCapacity(msg, this);
if (orderPolicy == ORDER_CREATION_TIME)
{
}
else
{
buffer.add(msg);
}
msgIDs.put(msg.getId(), msg);
bufSize += msg.getLength();
msg.setEventHandlerID(eventHandlerID());
parent.notifyNewMessage(msg);
return true;
}

ContactSchedule类下有getMEDWeight,getEDWeight,getFirstGoodUpTime

 

在BasicContact类下,

    在读取simple_Times文件后,发现有up命令后,会调用parseCommandPart,

接着会在Contact UP后,会调用processEvent(CONTACT_UP, null);

        接着会调用srcNode.contactIdle(this);

public CommandStatus parseCommandPart(ArrayList part, String path)
{
String param = part.get(0);
CommandStatus ok = new CommandStatus(CommandStatus.COMMAND_OK);
// Parameters without arguments:
if (param.equals("up"))
{
contactUp();
return ok;
}

获取第一个合适的连接机会,分两部分,是否合适的标准是能否满足msg的发送时间,为什么不考虑传播时间latency和接收时间呢???发出去了,但对面的节点关闭接收机,消息还是无法收到啊???

1、 当前时间在contact内,判断剩余时间长度是否满足msg的发送时间

2、 当前时间在contact内,但长度不够,或当前时间在contact外,判断时间长度是否满足msg的发送时间

public UpTime getFirstGoodUpTime(double afterTime, Message forMsg)
{
// Get the time it will take to send this message over the contact
double transferTime = 0;
if (forMsg != null)
transferTime = contact.getTransferTime(forMsg);
// Find the first uptime that we care about
int index = Collections.binarySearch(times, new UpTime(afterTime));
// If the element wasn‘t found, switch the index to the positive
// insertion point
if (index <0)
{
index = -index - 1;
assert index >= 0;
}
if (index > 0 && times.get(index - 1).getTimeDown() > afterTime)
{
// We are in the middle of an interval
double timeRemaining = times.get(index - 1).getTimeDown() - afterTime;
// 这里仅仅是看是否有足够时间发送,没有管接收和传播延时
if (timeRemaining >= transferTime)
{
// There is enough time remaining in this interval: Return
// an iterator at this point
return times.get(index - 1);
}
}
if (index == times.size())
{
// There are no more times!
assert afterTime >= times.get(times.size() - 1).getTimeDown() : "AfterTime: " + afterTime + "; lastTime: "
+ times.get(times.size() - 1).getTimeDown();
return null;
}
assert times.get(index).getTimeUp() >= afterTime;
while (index {
UpTime interval = times.get(index);
double up = interval.getTimeUp();
assert up >= afterTime;
double down = interval.getTimeDown();
if (down - up >= transferTime)
{
return interval;
}
// This interval was not long enough for this message
index += 1;
}
return null;
}

5、总结

Dtnsim2中只有MEEDMEDED的代码,没有EDLQEDAQLP的代码。


Dtnsim2学习笔记,布布扣,bubuko.com


推荐阅读
  • 题目描述:小K不幸被LL邪教洗脑,洗脑程度之深使他决定彻底脱离这个邪教。在最终离开前,他计划再进行一次亚瑟王游戏。作为最后一战,他希望这次游戏能够尽善尽美。众所周知,亚瑟王游戏的结果很大程度上取决于运气,但通过合理的策略和算法优化,可以提高获胜的概率。本文将详细解析洛谷P3239 [HNOI2015] 亚瑟王问题,并提供具体的算法实现方法,帮助读者更好地理解和应用相关技术。 ... [详细]
  • JVM参数设置与命令行工具详解
    JVM参数配置与命令行工具的深入解析旨在优化系统性能,通过合理设置JVM参数,确保在高吞吐量的前提下,有效减少垃圾回收(GC)的频率,进而降低系统停顿时间,提升服务的稳定性和响应速度。此外,本文还将详细介绍常用的JVM命令行工具,帮助开发者更好地监控和调优JVM运行状态。 ... [详细]
  • 1. 给定一个包含 n 个整数的数组 a 和一个整数 x,需要判断数组中是否存在两个不同的元素,它们的和恰好等于 x。2. 反转数对问题:对于一个包含 n 个不同元素的数组 A[1...n],如果存在 i < j 且 A[i] > A[j],则称 (i, j) 为一个反转数对。本文将详细探讨这两种与归并排序相关的算法题目,并提供高效的解决方案。 ... [详细]
  • Go语言中的高效排序与搜索算法解析
    在探讨Go语言中高效的排序与搜索算法时,本文深入分析了Go语言提供的内置排序功能及其优化策略。通过实例代码,详细讲解了如何利用Go语言的标准库实现快速、高效的排序和搜索操作,为开发者提供了实用的编程指导。 ... [详细]
  • 高效排序算法是提升数据处理速度的重要技术。通过优化排序算法,可以显著提高数据处理的效率和性能。本文介绍了几种常见的高效排序算法,如快速排序、归并排序和堆排序,并通过实例代码展示了它们的具体实现。实验结果表明,这些算法在大规模数据集上的表现尤为突出,能够有效减少数据处理时间,提升系统整体性能。 ... [详细]
  • 在执行 Vim/VM 命令时遇到错误提示:检测到名为
    在使用 Docker 时,通过 Vim 编辑 Dockerfile 文件时遇到了错误提示:“检测到名为 .dockerfile.swp 的交换文件”。这一问题通常是因为上次编辑该文件时意外中断,导致系统生成了临时的交换文件。为了解决这个问题,可以手动删除该交换文件或使用 Vim 的恢复功能来恢复未保存的更改。 ... [详细]
  • 当前,众多初创企业对全栈工程师的需求日益增长,但市场中却存在大量所谓的“伪全栈工程师”,尤其是那些仅掌握了Node.js技能的前端开发人员。本文旨在深入探讨全栈工程师在现代技术生态中的真实角色与价值,澄清对这一角色的误解,并强调真正的全栈工程师应具备全面的技术栈和综合解决问题的能力。 ... [详细]
  • 在Spring框架中,基于Schema的异常通知与环绕通知的实现方法具有重要的实践价值。首先,对于异常通知,需要创建一个实现ThrowsAdvice接口的通知类。尽管ThrowsAdvice接口本身不包含任何方法,但开发者需自定义方法来处理异常情况。此外,环绕通知则通过实现MethodInterceptor接口来实现,允许在方法调用前后执行特定逻辑,从而增强功能或进行必要的控制。这两种通知机制的结合使用,能够有效提升应用程序的健壮性和灵活性。 ... [详细]
  • 在使用关系型数据库时,通常需要通过用户名和密码进行身份验证才能访问数据。然而,MongoDB默认情况下并不强制要求这种身份验证机制,使得用户无需凭据即可访问并执行各种操作。虽然这一设计简化了初学者的上手过程,但也带来了显著的安全风险。为了提升MongoDB的连接安全性,本文将探讨多种策略与实践,包括启用身份验证、配置网络访问控制、加密通信以及定期审计安全设置,以确保数据库的安全性和数据的完整性。 ... [详细]
  • 在 Linux 系统中,`/proc` 目录实现了一种特殊的文件系统,称为 proc 文件系统。与传统的文件系统不同,proc 文件系统主要用于提供内核和进程信息的动态视图,通过文件和目录的形式呈现。这些信息包括系统状态、进程细节以及各种内核参数,为系统管理员和开发者提供了强大的诊断和调试工具。此外,proc 文件系统还支持实时读取和修改某些内核参数,增强了系统的灵活性和可配置性。 ... [详细]
  • SQLmap自动化注入工具命令详解(第28-29天 实战演练)
    SQL注入工具如SQLMap等在网络安全测试中广泛应用。SQLMap是一款开源的自动化SQL注入工具,支持12种不同的数据库,具体支持的数据库类型可在其插件目录中查看。作为当前最强大的注入工具之一,SQLMap在实际应用中具有极高的效率和准确性。 ... [详细]
  • POJ 1696: 空间蚂蚁算法优化与分析
    针对 POJ 1696 的空间蚂蚁算法进行了深入的优化与分析。本研究通过改进算法的时间复杂度和空间复杂度,显著提升了算法的效率。实验结果表明,优化后的算法在处理大规模数据时表现优异,能够有效减少计算时间和内存消耗。此外,我们还对算法的收敛性和稳定性进行了详细探讨,为实际应用提供了可靠的理论支持。 ... [详细]
  • 本文详细介绍了 MiniGUI 中静态控件(CTRL_STATIC)的使用方法及其不同风格的应用。具体而言,采用 SS_SIMPLE 风格的静态控件仅支持单行文本显示,不具备自动换行功能,且文本始终为左对齐。而 SS_LEFT、SS_CENTER 和 SS_RIGHT 风格则分别实现了文本的左对齐、居中和右对齐布局,提供了更多的排版灵活性。此外,文章还探讨了这些控件在实际开发中的应用场景和最佳实践。 ... [详细]
  • Vuex 实战进阶:构建高效笔记本应用(第二篇)
    在上一篇文章中,我们初步探讨了 Vuex 在该项目中的应用。本文将深入解析整个项目的架构设计。首先回顾 `main.js` 的内容,然后重点分析 `App.vue` 文件,其中引入了 `Toolbar.vue` 和 `NodeList.vue` 组件,详细说明它们在应用中的作用和交互方式。通过这些组件的协同工作,我们将展示如何构建一个高效且响应迅速的笔记本应用。 ... [详细]
  • 深入探讨Photoshop的高级应用与技巧
    本文深入探讨了Photoshop的高级应用与技巧,不仅涵盖了常用的快捷键,如矩形选框工具(M)、移动工具(V)、套索工具(L)、魔棒工具(W)、裁剪工具(C)等,还介绍了更多专业功能,如图层蒙版、混合模式和智能对象的使用方法,帮助用户提升图像处理的效率和质量。 ... [详细]
author-avatar
赵博钧石博
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有