First.cc分析

4.2.5 Main Function
下面的腳本是:
int main (int argc, char *argv[])
{
下面兩行腳本是用來使兩個日誌組件生效的。它們被內建在Echo Client 和Echo Server 應用中:
LogComponentEnable("UdpEchoClientApplication", LOG_LEVEL_INFO);
LogComponentEnable("UdpEchoServerApplication", LOG_LEVEL_INFO);
注:打開echo服務端,以及echo客戶端日誌,可以看到具體的信息。
Received 1024 bytes from 10.1.1.1
Received 1024 bytes from 10.1.1.2
這兩行代碼將回顯clients和server的日誌級別設爲”INFO”級。這樣,當仿真發生數據包發送和接受時,對應的應用就會輸出相應的日誌消息
4.2.6拓撲生成器
4.2.6.1 使用NodeContainer類
在我們的腳本中的下面兩行將會創建ns-3節點對象,它們在仿真中代表計算機。
NodeContainer nodes;
nodes.Create (2);
節點代表一臺能夠加入諸如協議棧,應用以及外設卡等等的東西的計算機。上面的第一行只是聲明瞭一個名爲”nodes”的NodeContainer。第二行調用了nodes對象的Create()方法創建了兩個節點。在腳本中他們所代表的節點什麼都沒有做。構建拓撲的下一步是把我們的節點連接到一個網絡中。
4.2.6.2 使用PointToPointHelper類
我們使用拓撲生成器來完成創建,連接的底層工作。
在腳本中下面的三句話是:
PointToPointHelper pointToPoint;
pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));
其中第一行,
PointToPointHelper pointToPoint;
在棧中初始化了一個PointToPointHelper的對象PointToPoint。而緊接着的下一行,
pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
從上層的角度告訴PointToPointHelper對象當創建一個PointToPointNetDevice對象時使用“5Mbps"來作爲數據速率。
pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));
告訴PointToPointHelper使用"2ms"(2毫秒)作爲每一個被創建的點到點信道傳輸延時值。
4.2.6.3 使用NetDeviceContainer類
NetDeviceContainer devices;
devices = pointToPoint.Install (nodes);
會完成設備和信道的配置。PointToPointHelper的Install()方法以一個NodeContainer對象作爲一個參數。在Install()方法內,一個NetDeviceContainer被創建了。當調用了pointToPoint.Install(nodes)後,我們會有兩個節點,每一個節點安裝了點到點網絡設備,在它們之間是一個點到點信道。兩個設備會被配置在一個有2毫秒傳輸延時的信道上以5M比特每秒的速率傳輸數據。
4.2.6.4 使用InternetStackHelper類
我們現在已經配置了節點和設備,但是我們還沒有在節點上安裝任何協議棧。下面兩行代碼完成這個任務:
InternetStackHelper stack;
stack.Install (nodes);
類InternetStackHelper 是一個安裝PointToPointHelper 對象和點到點網絡設備的網絡協議棧的拓撲生成器類。其中Install()方法以一個NodeContainer 對象做爲一個參數,當它被執行後,它會爲每一個節點容器中的節點安裝一個網絡協議棧(TCP,UDP,IP等等)。
4.2.6.5 使用Ipv4AddressHelper類
下面我們需要爲節點上的設備設置IP地址。我們也提供了一個拓撲生成器來管理IP地址的分配。當執行實際的地址分配時唯一用戶可見的API是設置基IP地址和子網掩碼。
在我們的範例腳本文件first.cc的下兩行代碼
Ipv4AddressHelper address;
address.SetBase ("10.1.1.0", "255.255.255.0");
聲明瞭一個地址生成器對象,並且告訴它應該開始從10.1.1.0開始以子網掩碼爲255.255.255.0分配地址。地址分配默認是從1開始並單調的增長,所以在這個基礎上第一個分配的地址n0會是10.1.1.1,緊跟着是n1:10.1.1.2等等。底層ns-3系統事實上會記住所有分配的IP地址,如果你無意導致了相同IP地址的產生,這將是一個致命的錯誤(順便說一下,這是個很難調試正確的錯誤)。

下面一行代碼,
Ipv4InterfaceContainer interfaces = address.Assign (devices);
完成了真正的地址配置。在ns-3中我們使用 Ipv4Interface對象將一個IP地址同一個設備關聯起來。正如我們有時候需要一個被生成器創建的網絡設備列表一樣,我們有時候需要一個 Ipv4Interface對象的列表。Ipv4InterfaceContainer提供了這樣的功能。
現在我們有了一個安裝了協議棧,配置了IP地址類的點到點的網絡。這時我們所要做的事情是運用它來產生數據通信。
4.2.7 Applications類
另一個ns-3系統的核心抽象是Application類。在這個腳本中我們用兩個特定的ns-3核心 Application類:UdpEchoServerApplication和UdpEchoClientApplication。正如我們先前聲明過的一樣,我們使用生成器對象來幫助配置和管理潛在的對象。在這裏,我們用UdpEchoServerHelper 和UdpEchoClientHelper對象使我們的工作更加容易點。
4.2.7.1 UdpEchoServerHelper類
下面在first.cc腳本中的代碼被用來在我們之前創建的節點上設置一個UDP 回顯服務應用。
UdpEchoServerHelper echoServer (9);
注:服務端設置端口號
ApplicationContainer serverApps = echoServer.Install (nodes.Get (1));
注:將服務安裝在n1上
serverApps.Start (Seconds (1.0));
serverApps.Stop (Seconds (10.0));
上面一片代碼中的第一行聲明瞭UdpEchoServerHelper。我們並沒有隨機選擇,而是把這個端口號作爲生成器構造函數的一個參數。UdpEchoServerHelper對象有一個Install方法。實際上是這個方法的執行,才初始化回顯服務器的應用,並將應用連接到一個節點上去。以nodes.Get(1)的結果作爲輸入,並把它作爲一個未命名的NodeContainer的構造函數的參數,最終這個未命名的NodeContainer被送入Install方法中去。我們現在會看到echoServer.Install將會在管理節點的NodeContainer容器索引號爲1的機節點上安裝一個UdpEchoServerApplication。
應用對象需要一個時間參數來“開始”產生數據通信並且可能在一個可選的時間點“停止”。我們提供了開始和停止的兩個參數。這些時間點是用ApplicationContainer的方法Start和Stop來設置的。
下面兩行,
serverApps.Start (Seconds (1.0));
serverApps.Stop (Seconds (10.0));
會使echo服務應用在1s時開始(生效)並在10s時停止(失效)。既然我們已經聲明瞭一個模擬事件(就是應用的停止事件)在10s時被執行,模擬至少會持續10s。
4.2.7.2 UdpEchoClientHelper類
echo客戶端應用的設置與回顯服務器端類似。也有一個UdpEchoClientHelper來管理UdpEchoClientApplication。
UdpEchoClientHelper echoClient (interfaces.GetAddress (1), 9);
注:interfaces.GetAddress (1),爲服務器端地址即n1,9爲端口號
echoClient.SetAttribute ("MaxPackets", UintegerValue (1));
注:設置發包的數量
echoClient.SetAttribute ("Interval", TimeValue (Seconds (1.)));
注:設置發包的時間間隔
echoClient.SetAttribute ("PacketSize", UintegerValue (1024));
注:設置數據包的大小
ApplicationContainer clientApps = echoClient.Install (nodes.Get (0));
注:將客戶端安裝在n0上面
客戶端一般要設置5個屬性
clientApps.Start (Seconds (2.0));
clientApps.Stop (Seconds (10.0));
然而,對於echo客戶端,我們需要設置五個不同的屬性。首先兩個屬性是在UdpEchoClientHelper的構建過程中被設置的。按照生成器的構造函數的格式,我們把”RemoteAdress”和”RemotePort”屬性傳遞給了生成器(實際上是作爲生成器構造函數的兩個必須參數傳遞的)。
回憶一下我們使用Ipv4InterfaceContainer來追蹤我們配置給設備的IP地址。在上面的第一行代碼中,我們創建了一個生成器並告訴它設置客戶端的遠端地址爲服務器節點的IP地址。我們同樣告訴它準備發送第二個數據包到端口9。那個“MaxPackets”屬性告訴客戶端我們所允許它在模擬期間所能發送的最大數據包個數。“Interval”屬性告訴客戶端在兩個數據包之間要等待多長時間,而“PacketSize”屬性告訴客戶端它的數據包應該承載多少數據。本例中,我們讓客戶端發送一個1024字節的數據包。
正如echo服務端一樣,我們告訴echo客戶端何時來開始和停止,但是這裏我們使客戶端在服務端生效1s後纔開始(在模擬器中時間2s的時候)。

4.2.8 Simulator類
下面我們所需要做的就是運行模擬器,這是用全局函數Simulator::Run.來做到的
Simulator::Run ();

實際上我們是在模擬器中1.0秒,2.0秒,和10.0時預設了時間的發生。當Simulator::Run被調用時,系統會開始遍歷預設事件的列表並執行。首先它會在1.0s時運行事件,這個事件會使echo服務端應用生效(這個事件會預設更多的其他事件)。接下來仿真器會運行在t=2.0秒時的事件,即讓echo客戶端應用開始。
其實,我們只發送了一個數據包(回憶一MaxPackets屬性被設置爲一),在此之後,那個被單獨的客戶端應答請求所引發的連鎖反應會停止,並且模擬器會進入空閒狀態。當這發生時,生下來的事件就是服務端和客戶端的Stop事件。當這些事件被執行後,就沒有將來的事件來執行了,函數Simulator::Run會返回。整個模擬過程就結束了。

下面剩下的事情就是清理了。這個通過調用全局函數Simulator::Destroy來完成。
Simulator::Destroy ();
return 0;
}
./waf --run scratch/first
你應該能看到一些輸出:
Waf: Entering directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Leaving directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'build' finished successfully (0.418s)
Sent 1024 bytes to 10.1.1.2
Received 1024 bytes from 10.1.1.1
Received 1024 bytes from 10.1.1.2
這裏你看到編譯系統覈查來確定文件被編譯了,接着運行了它。你看到在echo日誌構件顯示了它已經發送了1024字節到在10.1.1.2的echo服務端。還可以看到回顯服務器端的日誌構件顯示他從10.1.1.1接收到了1024字節。接下來echo服務端應答了數據包,你能看到echo客戶端記錄了它已經接收到了從服務端發送過來的回顯數據包。
注:客戶端10.1.1.1會在2s的時候發送一個數據包給服務端10.1.1.2,
服務端10.1.1.2會收到來自客戶端10.1.1.1的數據包
服務端10.1.1.2會將收到來自客戶端10.1.1.1的數據包返回給客戶端10.1.1.1
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章