ns-3的tutorial和安裝完ns-3后,目錄example下給的例子柱彻,都是預(yù)先設(shè)定好channel的bandwidth和delay另玖,但如果想做一個(gè)基于trace driven的simulation,要每隔一段時(shí)間動(dòng)態(tài)改變channel的bandwidth或delay概而,那應(yīng)該怎么辦倍权?
這篇博客以ns-3目錄example/tcp/下的tcp-variants-comparison.cc作為例子掷豺,修改后的源文件在我的github中可以看到,這里給出github地址github薄声。
靜態(tài)設(shè)置bandwidth和delay
...
int main (int args, char *argv[])
...
std::string bandwidth = "2Mbps"
std::string delay = "0.01ms"
...
PointToPointHelper UnReLink;
UnReLink.SetDeviceAttribute ("Datarate", StringValue (bandwidth));
UnReLink.SetChannelAttribute ("Delay", StringValue (delay));
...
動(dòng)態(tài)調(diào)整bandwidth和delay
動(dòng)態(tài)調(diào)整bandwidth和delay当船,首先需要制作bandwidth trace,這個(gè)trace怎么做默辨,我想就不要說(shuō)了吧德频,就算你問(wèn)我我也不會(huì)說(shuō)的。
寫(xiě)B(tài)andwidthTrace()函數(shù)
這里是在downlink上添加trace缩幸,我這里叫downlink.txt文件
讀文件
#include <fstream>
using namespace std;
...
void BandwidthTrace (void);
void ScheduleBw (void);
string bandwidth = "2Mbps";
uint32_t m_timer_value = 100;
...
ifstream bwfile ("downlink.txt");
PointToPoint UnReLink;
...
如果你問(wèn)我ifstream是什么鬼壹置,我不會(huì)告訴你這是個(gè)什么鬼的,我只會(huì)提醒你表谊,使用時(shí)記得包含頭文件"fstream"钞护。
還有為什么要在這里用這條表達(dá)式"PointToPoint UnReLink",后面會(huì)說(shuō)的爆办。
寫(xiě)函數(shù)BandwidthTrace()這里先給出一種的錯(cuò)誤的做法难咕,我以前就是這么干的,哎距辆,浪費(fèi)生命坝嗟琛!
void
BandwidthTrace (void)
{
//讀trace文件跨算,bwfile為文件指針爆土,getline函數(shù)每次讀一行
getline (bwfile, bandwidth);
//像在主函數(shù)中一樣設(shè)置bandwidth
UnReLink.SetDeviceAttribute ("Datarate", StringValue (bandwidth));
//判斷文件是否為空
if (!bwfile.eof ())
{
//trace文件不為空,就調(diào)用ScheduleBw函數(shù)诸蚕,這個(gè)函數(shù)在后面做介紹
ScheduleBw ();
}
else
{
cout <<"end of file!" <<endl;
}
}
//ScheduleBw()函數(shù)起一個(gè)定時(shí)器的作用
void
ScheduleBw (void)
{
//這條語(yǔ)句的意思是說(shuō)步势,每隔m_timer_value就調(diào)用函數(shù)BandwidthTrace(),而在函數(shù)
//Bandwidth()中又會(huì)調(diào)用ScheduleBw()函數(shù),明白什么意思了吧挫望。
Simulator::Schedule (MilliSeconds (m_timer_value), BandwidthTrace);
}
現(xiàn)在問(wèn)題來(lái)了,錯(cuò)誤在哪狂窑?
問(wèn)題在這里:
UnReLink.SetDeviceAttribute ("Datarate", StringValue (bandwidth));
這條語(yǔ)句只會(huì)被執(zhí)行一次媳板,在后面再次調(diào)用時(shí),雖然不會(huì)報(bào)錯(cuò)泉哈,但也不會(huì)改變?nèi)魏螙|西蛉幸,那么破讨,如果想要?jiǎng)討B(tài)改變attribute,可以使用這種方式:
Config::Set("NodeList/[i]/DeviceList/[i]/$ns3::PointToPointNet/DataRate",StringValue(attribute));
NodeList/[i]表示第i個(gè)節(jié)點(diǎn)奕纫,DeviceList/[i]表示第i個(gè)節(jié)點(diǎn)的第i個(gè)設(shè)備提陶。
所以BandwidthTrace()函數(shù)的寫(xiě)法應(yīng)該這樣:
void
BandwidthTrace (void)
{
//讀trace文件,bwfile為文件指針匹层,getline函數(shù)每次讀一行
getline (bwfile, bandwidth);
Config::Set("/NodeList/1/DeviceList/1/$ns3::PointToPointNetDevice/DataRate", StringValue(bandwidth));
if (!bwfile.eof())
{
ScheduleBw();
}
else
{
cout <<"end of file!" <<endl;
}
}