蔡文郁, 劉曉玲
(杭州電子科技大學 電子信息學院,杭州 310018)
《計算機網絡系統》[1]是本科教學體系中的一個重要分支,其旨在讓學生掌握抽象的計算機網絡系統知識的同時,并能通過自己的操作和改進的協議進行網絡性能仿真結果的分析,如果只靠黑板教學是難以達到這一教學目標。網絡仿真[3]是通過計算機技術搭建網絡結構和實現網絡協議的模擬網絡行為,是一項重要的計算機網絡仿真技術。相比于搭建一個實驗室測試網絡平臺,網絡仿真技術可以使用相對較少的時間和較低的費用基本實現所需要研究的網絡模型,作為《計算機網絡系統》課程中一種重要的輔助實驗手段。NS-3[4]作為一種開源、免費的網絡仿真軟件,可以實現對大部分網絡協議的仿真,其具有開源性,學生可以在其提供的已有的模塊下進行改進,大大提升學生的學習興趣。本文將這種開源的網絡仿真軟件NS-3應用在計算機網絡課程的教學過程中,通過設計一些啟發式實驗案例,讓學生了解NS-3仿真軟件,讓學生對網絡通信協議有直觀深入的理解,進而提高教學效果。
網絡仿真(Network Simulator-3,NS-3)是一種旨在學術研究和教學需要的離散事件模擬器,其在可擴展性、移植性、開源性和完整性等方面的特征都優于現有的大多數網絡模擬器。NS-3可以構建各種網絡結構,可以仿真模擬各種協議并對其進行比較和改進。NS-3中的模塊支持兩種語言編寫,分別是C++和Python。NS-3的仿真結果有靜態和動態兩種形式,其中靜態結果有文本文件和圖表方式,動態圖包括離線動畫演示工具NetAnim和在線可視化模塊PyViz。NS-3組織結構[5]和模型間的依賴關系如圖1所示,依次為核心模塊(Core)、網絡模塊(Network)、互聯網模塊(Internet)、移動模塊(Mobility)、應用模塊(Applications)和Helper類。每個模塊都有自己的類和實現方法,各個模塊相互獨立和實現功能。NS-3這種分層次的模塊組織結構,類似于TCP/IP協議,使各層各負其責,在物理上、邏輯上相互獨立,便于研究者設計自己的網絡模型。

圖1 NS-3組織結構
NS-3網絡仿真平臺搭建包括8個步驟,如圖2所示。

圖2 NS-3仿真平臺搭建流程圖
此案例的網絡結構如圖3所示,多個無線客戶端節點需要訪問PC服務器節點,其中無線客戶端節點首先與無線AP節點連接,無線AP節點通過以太網連接PC服務器。該案例通過NS-3仿真演示實現有線網絡和無線網絡的混合通信,仿真過程的動畫演示使用PyViz輔助工具,讓學生掌握無線WiFi通信技術以及異型網絡的綜合使用能力。

圖3 網絡仿真場景
2.1.1仿真場景
仿真網絡結構如圖4所示,n5、n6是WiFi移動節點,n0是無線訪問節點(Access Point,AP),n1~n4是有線局域網,n0和n1是點到點的通信鏈路[10]。

圖4 網絡仿真場景
2.1.2仿真腳本的關鍵代碼
//“include”函數來引入NS-3中已編譯模塊,如:點到點模塊(point-to-point)、移動模塊(mobility)等。
#include "ns3/point-to-point-module.h"
#include "ns3/mobility-module.h"
//此代碼中使用了NS-3提供的日志模塊功能,可根據Logging給出的信息點網絡環境進行程序調試。
NS_LOG_COMPONENT_DEFINE ("ThirdScriptExample");
//通過調用CommandLine命令為程序引入命令行模式,用戶通過命令行模式去設定參數來改變程序中參數值,
CommandLine cmd; cmd.Parse (argc,argv);
//創建2個節點用于連接點到點鏈路
NodeContainer p2pNodes; p2pNodes.Create (2);
//構建點對點連接,通過PointToPointHelper類設置網絡節點的點到點鏈路的網絡設備和信道屬性
PointToPointHelper pointToPoint;
pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));
//借用Install方法將設備安裝到節點中
NetDeviceContainer p2pDevices;
p2pDevices = pointToPoint.Install (p2pNodes);
//創建3個以太網網絡節點,并將點到點節點容器中的第一個節點加入到CSMA設備的節點容器
NodeContainer csmaNodes; csmaNodes.Add (p2pNodes.Get (1)); csmaNodes.Create (3);
//通過CsmaHelper類設置網絡節點的以太網的網絡設備和信道屬性,并用Install方法將設備安裝到節點中
CsmaHelper csma;
csma.SetChannelAttribute ("DataRate", StringValue
("100Mbps"));
csma.SetChannelAttribute ("Delay", TimeValue (NanoSeconds (6560)));
NetDeviceContainer csmaDevices; csmaDevices = csma.Install (csmaNodes);
//創建2個WiFi網絡節點,再將剩余的一個點到點鏈路節點作為接入點AP
NodeContainer WiFiStaNodes; WiFiStaNodes.Create (2); NodeContainer WiFiApNode = p2pNodes.Get (0);
//通過配置PHY和通道助手來構建無線設備和無線節點之間的互連通道
YansWiFiChannelHelper channel = YansWiFiChannelHelper::Default ();
YansWiFiPhyHelper phy = YansWiFiPhyHelper::Default ();
WiFiHelper WiFi;
WiFi.SetRemoteStationManager ("ns3::AarfWiFiManager");
WiFiMacHelper mac;
staDevices = WiFi.Install (phy, mac, WiFiStaNodes);
//配置AP節點
mac.SetType ("ns3::ApWiFiMac", "Ssid", SsidValue (ssid));
NetDeviceContainer apDevices;
apDevices = WiFi.Install (phy, mac, WiFiApNode);
//使用MobilityHelper類設置WiFi節點的初始位置和移動模型
MobilityHelper mobility;
mobility.SetPositionAllocator ("ns3::GridPositionAllocator",
"MinX", DoubleValue (-50.0), "MinY", DoubleValue (50.0),
"DeltaX", DoubleValue (5.0),"DeltaY", DoubleValue (-50.0),
"GridWidth", UintegerValue (1),"LayoutType", StringValue ("RowFirst"));
//WiFi節點的移動模型是隨機游走模型:RandomWalk2dMobilityModel
mobility.SetMobilityModel ("ns3::RandomWalk2dMobilityModel",
"Bounds", RectangleValue (Rectangle (-150, 150, -150, 150)));
//通過InternetStackHelper類安裝協議棧
InternetStackHelper stack; stack.Install (csmaNodes);stack.Install (WiFiApNode); stack.Install (WiFiStaNodes);
//配置IP地址,點到點鏈路節點在網段10.1.1.0/24,CSMA節點在網段10.1.2.0/24,WiFi節點在網段10.1.3.0/24
Ipv4AddressHelper address;
address.SetBase ("10.1.1.0", "255.255.255.0"); p2pInterfaces = address.Assign (p2pDevices);
address.SetBase ("10.1.2.0", "255.255.255.0"); csmaInterfaces = address.Assign (csmaDevices);
address.SetBase ("10.1.3.0", "255.255.255.0"); address.Assign (staDevices);address.Assign (apDevices);
//設置以太網節點3為echo服務端程序,同時設置服務器啟動時間。
UdpEchoServerHelper echoServer (9);
ApplicationContainer serverApps = echoServer.Install (csmaNodes.Get (3));
serverApps.Start (Seconds (1.0));
//設置WiFi網絡中的一個節點為客戶端,并配置相關屬性
UdpEchoClientHelper echoClient (csmaInterfaces.GetAddress (nCsma), 9);
echoClient.SetAttribute ("MaxPackets", UintegerValue (100));
ApplicationContainer clientApps = echoClient.Install (WiFiStaNodes.Get (nWiFi - 1));
//啟用互聯網絡路由作用與建立好的互連網絡
Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
//運行模擬、清空、退出程序
Simulator::Run (); Simulator::Destroy (); return 0;
2.1.3仿真實驗及結果分析
仿真結果分析:根據圖5(a)和(b)可以直觀生動的看出節點之間的數據流動。從圖6可以看出,在終端中輸入編譯代碼并執行腳本,從輸出的日志信息可以看出模擬通信場景運行到2 s時客戶端發送1 024 Byte給地址為10.1.2.4的服務器,客戶端和服務器處于不同的網段。之后服務器收到來自10.1.3.2客戶端的數據分組,同時發送相同字節給客戶端,而且客戶端成功接收。可以看到仿真結果與程序中設定的發送數據包的時間點和數據包發送的發送端和接收端完全一致。

(a) 初始仿真場景

(b) 混合通信場景
圖5 混合通信仿真場景

圖6 編譯結果
如圖7所示,節點之間采用點到點通信,且節點均處于靜止狀態,采用添加中繼節點的方式實現節點的數據連通。此案例主要用于演示點到點中繼通信的原理,提高學生中繼通信的感官認識,從而激發學生學習并掌握短距離無線組網技術的興趣。

圖7 網絡仿真場景
2.2.1仿真場景
本仿真場景中一共設置了10個節點,如圖8所示,其中n2~n11均位于不同的網段,n0和n1屬于中繼節點,并且設置節點n4和節點n9進行通信。

圖8 網絡仿真場景
2.2.2仿真腳本的關鍵代碼
#include "ns3/netanim-module.h"
//構建網絡拓撲結構,如:設置節點0分別與節點1、2、3、4、5和6連接
pAnim->UpdateLinkDescription (0, 1, oss.str ());
pAnim->UpdateLinkDescription (0, 2, oss.str ());
pAnim->UpdateLinkDescription (0, 3, oss.str ());
pAnim->UpdateLinkDescription (0, 4, oss.str ());
pAnim->UpdateLinkDescription (0, 5, oss.str ());
pAnim->UpdateLinkDescription (0, 6, oss.str ());
// 設置 IP地址
d.AssignIpv4Addresses (Ipv4AddressHelper ("10.1.1.0", "255.255.255.0"),
Ipv4AddressHelper ("10.2.1.0", "255.255.255.0"),
Ipv4AddressHelper ("10.3.1.0", "255.255.255.0"));
// 生成XML文件
std::string animFile = "dynamic_linknode.xml" ;
pAnim = new AnimationInterface (animFile);
2.2.3仿真實驗及結果分析
仿真結果采用兩種可視化界面PyViz和NetAnim方式觀測,如圖9所示。仿真結束后使用NetAnim讀取程序執行過程中生成的XML文件,可離線演示網絡拓撲結構和節點間數據分組流動等動畫過程。
此仿真的場景是多跳無線網絡Ad Hoc[11],如圖10所示,其結構采用一種省略無線中介設備AP而搭建起來的對等網絡結構,只需要安裝無線網卡,就可以實現計算機之間的通信。對于多跳無線自組網絡來說,路由協議是非常重要的。其中主動路由協議和按需路由協議較為典型,因此仿真了DSR和DSDV兩種路由協議的建立路徑的過程和結果分析。此案例主要用于演示無線多跳網絡的工作原理以及不同路由協議的性能比較,提升學生參與網絡傳輸核心路由協議設計的學習熱情。
2.3.1仿真場景
本案例是基于Ad-Hoc網絡[12-14],設置了20個可隨機移動的節點,其中節點2(Node2)為數據發送端,節點0(Node0)為數據接收端。

(a) 點到點通信可視化界面

(b) 仿真拓撲結構圖

(c) 數據分組統計
(d) 節點9發送數據

(e) 途徑節點1和節點0

(f) 節點4發送數據
圖9 無線中繼通信演示

圖10 網絡仿真場景
2.3.2仿真腳本的關鍵代碼
//設置節點的移動模型為隨機路徑
adhocMobility.SetMobilityModel ("ns3::RandomWaypoint MobilityModel",
"Speed", StringValue (speedUniformRandomVariable Stream.str ()),
"Pause", StringValue (pauseConstantRandomVariable Stream.str ()),
"PositionAllocator", PointerValue (taPositionAlloc));
adhocMobility.Install (adhocNodes);
//通過DsdvHelper類引入DSDV路由協議,同理也可以引入DSR路由協議。
DsdvHelper dsdv; InternetStackHelper stack; stack.SetRoutingHelper (dsdv);
//設置節點0為數據接收端,節點2為數據發送端,且設置節點2在20 s時開始發送數據
ApplicationContainer apps_sink = sink.Install (adhocNodes.Get (0));
apps_sink.Start (Seconds (20.0));
OnOffHelper onoff1 ("ns3::UdpSocketFactory", Address (InetSocketAddress (allInterfaces.GetAddress (0), port)));
onoff1.SetAttribute ("OnTime", StringValue ("ns3::ConstantRandomVariable[Constant=1.0]"));
onoff1.SetAttribute ("OffTime", StringValue ("ns3::ConstantRandomVariable[Constant=0.0]"));
ApplicationContainer apps1 = onoff1.Install
(adhocNodes.Get (2));
2.3.3仿真實驗及結果分析
仿真結果如圖11所示。

(a) DSDV協議Node2節點泛洪廣播

(b) DSDV協議Node2找到的第1條路徑

(c) DSDV協議Node2找到的第2條路徑

(d) DSR協議泛洪廣播

(e) DSR協議Node2找到的第1條路徑

(f) DSR協議Node2找到的第2條路徑
從可視化動態仿真過程圖中,可以直觀地看出在同一種動態變化的網絡拓撲結構的仿真場景。DSR協議比DSDV協議尋找到兩節點通信路徑所花費的時間要少,這是因為在動態變化的網絡拓撲結構下,由于鄰居信息表需要實時更新,主動路由協議額外負荷較高。
本文將NS-3網絡仿真平臺引入到《計算機網絡系統》課程的教學中,通過在NS-3中構建設計的3種不同網絡通信協議啟發式案例,運用NS-3中多樣化的仿真方式,如Logging、動畫演示工具(NetAnim)和可視化模塊(PyViz)等,將網絡課程中抽象的理論知識形象直觀地呈現在學生面前,使學生對網絡知識點有了較為直觀的了解,進而激發學生探索網絡知識的欲望,起到事半功倍的效果。當學生熟練掌握NS-3的模塊內容和執行方式后,還可以繼續引導學生向更深層次的計算機網絡協議的核心實現與編程技術,為后續課程的學習奠定了一定基礎。