我只想在“ns-2”中将一个节点设置为睡眠状态,我已经在协议中搜索过,发现了很多关于睡眠的对象和函数,但我无法在其他协议中使用它们将节点设置为睡眠状态。
当我使用它们时,我得到了分段错误或浮点错误,我知道这些错误是什么意思,但我找不到解决它们的方法。
比如当我使用“SMAC”中的 sleep() 函数时。
我在谷歌上搜索过,一周后我仍然没有找到任何解决方案...!你们能帮我吗...?
答案1
几个月前我就找到了解决方案,但是我看到了我自己的问题,所以我说让我们来回答它,这样,像我这样经历了所有麻烦才找到答案的人就可以轻松地找到解决方法...
首先让我向您介绍 ns2 中的协议代码。在
ns2 中,使用 2 个主文件创建了一个协议(有些协议也只有一个文件,但我说的是大多数协议),其中一个文件的.cc
类型包含协议的名称(如 AODV.cc)用于定义,另一个文件的类型.h
用于声明,它还包含协议名称(如 AODV.h)。
可能还有其他文件,包括协议,但主要文件是protocolname.cc
。
我们需要改变/添加一些功能,以便protocolname.cc
我们可以模拟我们自己的协议。
例如:
我们需要在我们的协议中使用聚类:
AODV.h:
public:
AODV();
void CLUSTERING();
...
AODV.cc:
void AODV::CLUSTERING(){
if(current_){
while(numberofNodes){
// Selecting clusters
}
}
}
现在我们知道了 ns2 的机制是如何工作的。让我们开始了解睡眠节点。
首先,ns2 中有 4 个函数用于将节点设置为“关闭”、“打开”、“睡眠”和“空闲”。它们之间的区别并不大。
正如您所知,“关闭”函数会将节点关闭,但它仍会根据您的协议广播某些内容。
$ns_ at 7.0 "$node(2) off"
你可以像这样打开它:
$ns_ at 7.0 "$node(2) on"
基础是:
$simulator at $time "$Node_($number) off"
我不知道如何在 scene.tcl 中将节点设置为休眠,但您可以在协议代码中执行此操作。
现在,要将节点设置为休眠,我们可以做几件事……
- 从能量模型设置节点进入睡眠状态
- 根据无线物理原理设置节点休眠
首先,我们会尝试energymodel.cc
,如果不行,我们会使用另一个。
要将节点设置为睡眠状态,我们可以在函数energymodel.cc
中使用此代码:
void Mac802_11::recv
ns-2.35/mac/mac-802_11.cc
if(index_ == myNode){
EnergyModel *em = netif_->node()->energy_model();
if (em && em->sleep()) {
em->set_node_sleep(1);
//em->set_node_state(EnergyModel::INROUTE);
}
}
替换myNode
为要将其设置为关闭的接口的编号。
如果您不使用多接口对于您的模拟,接口的数量将等于节点的数量。
例如:
正常:
node ---- > interface ----> channel
多接口:
---- > interface[0] -----|
| ---------|
| v
node -------|---- > interface[1] --------- > channel
| ^
| ----------|
---- > interface[2] -----|
打开终端并cd
进入 ns2 目录,例如,如果您有ns-allinone-2.35
,cd
则/ns-allinone-2.35/ns-2.35/
进入make
并输入 inter。完成后,尝试模拟您的 scene.tcl。
现在,如果您的模拟开始并且您看到 nam 文件,当节点收到第一个数据包时,它们的形状必须从黑色圆圈到黑色圆圈蓝色六边形从那时起,
节点不得发送或接收任何数据包。
如果这种方式不起作用,现在是时候使用另一种选择了。
转到/ns-2.35/mac/
并打开 wireless-phy.cc。
你会看到在文件末尾它包含我们需要的 4 个函数。
我们可以简单地在 wireless-phy.cc 上使用这些函数,只需调用这些函数即可将节点设置为睡眠或关闭。但我们可能需要在另一个层中使用它们,比如在 mac 中。
要使用这些函数,只需mac-802_11.cc
在任何你想要的地方使用下面的代码mac-802_11.cc
并添加wireless-phy.cc
到你的 mac 标头中:
#include "wireless-phy.h" // at the header of mac-802_11.cc
/*
* Use the below code in any function you want in mac
*/
Phy *p;
p=netif_;
((WirelessPhy *)p)->node_sleep();
要使用这四个函数中的另一个,只需将函数名称更改->node_sleep();
为->node_wakeup();
。
答案2
WirelessPhy::command(int argc, const char*const* argv)
可以通过从 Tcl 脚本调用来“关闭”和“打开”节点WirelessPhy.cc
。为此,假设Node_(0)
,一旦在 Tcl 脚本中定义了节点,请执行以下操作:
set Netif_0 [$Node_(0) set netif_(0)]
请注意,变量netif_
是一个数组,因此我们用它netif_(0)
来获取第一个网络接口的句柄。如果节点配置了多个接口,则可以类似地用于第二和第三个网络接口netif_(1)
。netif(2)
一旦将句柄带入本地范围,我们就可以使用定义的任何命令WirelessPhy
,并可以用来$Netif_0 NodeOff
关闭节点以停用网络接口。