Ns2 一個常用的網路模擬器 台灣科技大學資管系資料庫實驗室 洪振洲.

Slides:



Advertisements
Similar presentations
1/67 美和科技大學 美和科技大學 社會工作系 社會工作系. 2/67 社工系基礎學程規劃 ( 四技 ) 一上一下二上二下三上 校訂必修校訂必修 英文 I 中文閱讀與寫作 I 計算機概論 I 體育 服務與學習教育 I 英文 II 中文閱讀與寫作 II 計算機概論 II 體育 服務與學習教育 II.
Advertisements

專業科目必修 管理學概論、化 妝品行銷與管理、 專題討論、藥妝 品學、流行設計、 專題講座、時尚 創意造型與實務 專業科目必修 化妝品法規、生 理學、化妝品原 料學、化妝品有 效性評估、時尚 化妝品調製與實 務、藝術指甲、 生物化學概論、 美容經絡學、校 外實習 專業科目必修 應用色彩學、化 妝品概論、時尚.
聖若翰天主教小學 聖若翰天主教小學歡迎各位家長蒞臨 自行分配中一學位家長會 自行分配中一學位家長會.
「健康飲食在校園」運動 2008小學校長高峰會 講題:健康飲食政策個案分享 講者:啟基學校-莫鳳儀校長 日期:二零零八年五月六日(星期二)
脊柱损伤固定搬运术 无锡市急救中心 林长春.
四資二甲 第三週作業 物件導向程式設計.
Ch 02 研究的過程.
五大段 创世记 至 出埃及 过红海 至 士师时代 列王时代至 两约之间 耶稣降生 至 复活 耶稣升天 至 再来 圣经大纲:第二集 概观.
務要火熱服事主.
作业现场违章分析.
NetGuru 創新 網路通訊實驗教學解決方案 PART I TCP/IP通訊協定深入剖析/以NetGuru實作
蒙福夫妻相处之道 经文:弗5:21-33.
Socket.
類別與物件 Class & Object.
學生:蔡耀峻、許裕邦 座號:23號、21號 指導老師:黃耿凌 老師
運輸與空間的交互作用 運輸發展的階段 一、分散的港口 二、侵入路線 三、發展支線 四、初步相互連結 五、完全相互連結 六、高度優越的幹線
Ch07 PHP程式基礎 網頁程式設計.
計算機網路實驗- 使用NS2模擬多媒體通訊與無線網路(實驗四)
6.5滑坡 一、概述 1.什么是滑坡? 是斜坡的土体或岩体在重力作用下失去原有的稳定状态,沿着斜坡内某些滑动面(滑动带)作整体向下滑动的现象。
破漏的囊袋.
Qtopia 编程部分要点分析 苗忠良.
Computer Network Lab 資碩一 黃麒瑋
走向C++之路 WindyWinter WindyWinter感谢诸位前来捧场。
基於OpenWSN之無線感測網路系統的實作
亂數函數(Random-Number Function)
Chap 18 類別與物件 夫有土者,有大物也。有大物者,不可以物。 物而不物,故能物物。 明乎物物者之非物也,豈獨治天下百姓而已哉!
Screen Layout & Background Image
Installation, advance wireless module and evaluation 2008/11/11
刘胥影 东南大学计算机学院 面向对象程序设计1 2011~2012第3学期 刘胥影 东南大学计算机学院.
系統與網路管理工具.
哈夫曼编码.
创建型设计模式.
授课老师:龚涛 信息科学与技术学院 2018年3月 教材: 《Visual C++程序员成长攻略》 《C++ Builder程序员成长攻略》
Stress Test Tool for SIP
程序设计期末复习 黎金宁
第三章 C++中的C 面向对象程序设计(C++).
2 C++ 的基本語法和使用環境 親自撰寫和執行程式是學好程式語言的不二法門。本章藉由兩個簡單的程式,介紹C++ 程式的基本結構和開發環境,讓初學者能逐漸建立使用C++ 的信心。
职责链模式.
Java语言程序设计 第五部分 Java异常处理.
NS2 – TCP/IP Simulation How-Wei Wu.
生鲜谈判.
Web Server 王宏瑾.
Westmont College 网络应用软件 第一讲 (客户-服务器 概念, 协议端口的使用, 套接字API)
聖本篤堂 主日三分鐘 天主教教理重温 (94) (此簡報由聖本篤堂培育組製作).
威爾斯親王醫院 住院病人意見調查 2014年4月至6月 7號床.
聖公會聖匠堂長者地區中心 長者支援服務隊 香港房屋協會 家維邨義工隊
安慰能力測試 我感到非常孤單 為何要這麼痛苦?做人毫無價值,活著根本沒有意思。 我拖累了你。 假如我不在,情況會如何呢?
NS2 (Network Simulator - version 2)
C#程序设计基础 $3 成员、变量和常量.
7-7 小三和弦/增三和弦/減三和弦.
Oop8 function函式.
分裂对象模型 C++ otcl.
Speaker : Chang Kai-Jia Date : 2010/04/26
2019/5/3 JAVA Socket(UDP).
Distance Vector vs Link State
圣依纳爵堂 主日三分钟 天主教教理重温 (95) (此简报由香港圣本笃堂培育组制作).
Chapter 10 Mobile IP TCP/IP Protocol Suite
IP Layer Basics, Firewall, VPN, and NAT
授课老师:龚涛 信息科学与技术学院 2016年3月 教材:《Visual C++程序员成长攻略》 《C++ Builder程序员成长攻略》
挑戰C++程式語言 ──第9章 函數.
#include <iostream.h>
Distance Vector vs Link State Routing Protocols
助教:廖啟盛 JAVA Socket(UDP) 助教:廖啟盛
基督是更美的祭物 希伯來書 9:1-10:18.
NS3 & NS2 (network simulator)
IP Layer Basics & Firewall
Homework 3.
明愛屯門馬登基金中學 中國語文及文化科 下一頁.
劉庠宏、林合治編著 國立高雄大學應用數學系 2005年3月1日
函式庫補充資料 1.
Presentation transcript:

Ns2 一個常用的網路模擬器 台灣科技大學資管系資料庫實驗室 洪振洲

Ns2 一個常用的網路模擬器 基本介紹與安裝

認識NS2 The NS-2 is a powerful tool for network simulation. There are many researchers use ns-2 to validate their algorithms and protocols for their network researches. NS-2 provides many supports for simulation of TCP, routing, and multicast protocol over wired and wireless network. It also provide topology generator to create topology from a number of nodes to thousand of nodes.

NS2 資源 官方網站 中文網頁 http://www.isi.edu/nsnam/ns/ 下載NS2 source, 最完整NS2手冊 http://netlab.cse.yzu.edu.tw/ns2/ 詳細Windows安裝 資源整理 http://140.116.72.80/~smallko/ns2/ns2.htm NS2 詳細的資源

安裝需求 作業系統: Linux Windows + cygwin (在windows 下模擬的Linux 環境) 檔案空間需求 約 1GB

下載NS2 由official site 下載 all-in-one 的版本 目前最新版本 2.29 由於Ns2 為網路社群共享,所以有各式各樣的修改版本. 我使用的是 2.1b8: 是為了實現AdHoc下面的Multi-cast 所改編的版本.

簡要安裝步驟 (I) Linux 下的安裝(可以參考 install_on_Suse.txt) 先create 安裝目錄,並給予適當權限 以下假設安裝在 /opt/ns2 必先安裝4個重要的library Tcl 8.3.2 Tk 8.3.2 Otcl 1.0a7 Tclcl 1.0b11

簡要安裝步驟 (II) 將library copy 到 /opt/ns2 之下 利用指令 “tar –zxvf 檔名” 解開 進入每一個子目錄中,依序執行 ./configure 與 make 兩個指令. 將ns2 的主檔copy 到 /opt/ns2之下, 並用 “tar –zxvf 檔名” 的指令解開 進入解開後的子目錄,打入 ./configure 的指令 先別執行 make, 我們要修改Makefile

簡要安裝步驟 (III) 利用文字編輯器修改ns2 解開後目錄中的 “Makefile”, 找到一行叫 “all :$(NS) all-recursive”把其中的 all-recursive 拿掉 執行 make 如果沒有錯誤訊息,就是安裝成功了

Ns2 一個常用的網路模擬器 Overview of NS2

What should we do?

C++ 與 TCL NS2 中的元件是由C++ 撰寫而成 劇本檔語言是 TCL 對於研究新protocol 的研究者,著重於如何用C++撰寫元件(agent) 對於研究複雜系統效能者,著重於如何用TCL描述系統

Use C++ to write your first NS2 agent.

AgentEcho 簡單的模擬 adhoc network 下面的echo 功能. 我們預計在”AdhocEcho”中實現的功能 所有echo 的邏輯都將寫在 名為”AdhocEcho” 的Agent 之中 我們預計在”AdhocEcho”中實現的功能 創造並列印節點基本資料 可以送出/回應 自訂的echo packet 利用時鐘來建立"Time-out” 機制

在開始之前 建立專案子目錄: 步驟一覽 在NS2 主目錄之下的“AdHocEcho”子目錄 STEP 1. 建立 C++ 中AdHocEcho所需的 Head STEP 2. 建立 AdhocEcho Agent 所需的基本架構 STEP 3. 建立 Tcl srcipt來測試初步結果. STEP 4. 修改C++ 檔案,使有 request/response 的能力 STEP 5. 修改C++ 檔案,使其有偵測Time-out 的能力

Echo Protocol 簡述 Type = 0 (Request) FromNode A FromTime T ReplyNode 若A 在 T 時間 執行Echo 封包內容: Type = 0 (Request) FromNode A FromTime T ReplyNode ??? ReplyTime A

Echo Protocol 簡述 Type = 1 (Reply) FromNode A FromTime T ReplyNode B 若B 在 T2 時間 收到來自A 的Echo_request B B 將只回應 A 封包內容: A Type = 1 (Reply) FromNode A FromTime T ReplyNode B ReplyTime T2

Step 1-Step 3 建立最簡單的echo agent,並加以測試 Ns2 一個常用的網路模擬器 Step 1-Step 3 建立最簡單的echo agent,並加以測試

STEP 1. 建立 C++ 中Agent所需的 Head AdhocEcho.h (I) // 講義第二頁,程式一 自訂的packet 表頭 struct hdr_ahe { // 表頭結構的定義 int FromNode; double FromTime; int ReplyNode; double ReplyTime; int Type; // Type=0: request, Type=1: reply int size_; int& size() { return size_; } static int offset_; inline static int& offset() { return offset_; } inline static hdr_ahe* access(const Packet* p) { return (hdr_ahe*) p->access(offset_); } }; 自訂表頭

STEP 1. 建立 C++ 中Agent所需的 Head AdhocEcho.h (II) // 講義第二頁,程式二 自訂的agent class 的定義 class AgentECHO : public Agent { public: AgentECHO(); // 建構子 virtual void recv(Packet *, Handler *); // 封包入口 protected: virtual int command(int argc, const char*const* argv); // 與TCL 溝通的界面 private: int my_addr; //用來儲存自己的 address, 與溝通用的port. int data_port; };

STEP 2. 以 C++程式碼實現 AgentEcho.cc 的細節(I) #include "AdhocEcho.h“ #include “ip.h“ // 用來處理ip 表頭的訊息 #include “packet.h“// 處理封包必備標頭檔 int hdr_ahe::offset_; // 為了正確處理自訂packet 標頭而宣告 // 自訂標頭檔的 wrapper class, 宣告十分制式,目的是為了讓使用者能在TCL中存取自訂packet 標頭, 用處很少 static class AHEHeaderClass : public PacketHeaderClass { public: AHEHeaderClass() :PacketHeaderClass("PacketHeader/AHECHOHEAD",sizeof(hdr_ahe)) { bind_offset( &hdr_ahe::offset_ ); } } class_ahe_hdr;

STEP 2. 以 C++程式碼實現 AgentEcho.cc 的細節(II) // 十分重要的 Wrapper class for our agent.講義第三頁 – 程式五 static class AHEClass : public TclClass { public: // Agent/ADECHO 是在TCL 中 create 這個 agent 時所需要的名字 AHEClass() : TclClass("Agent/ADECHO") {} // 這個class 實際上僅是創造一個agent class 並回傳. TclObject* create(int, const char*const*) { return ( new AgentECHO() ); } } class_ahe_agent;

STEP 2. 以 C++程式碼實現 AgentEcho.cc 的細節(III) AgentECHO::AgentECHO() : Agent(PT_AECHO) { } 1. 目前沒有需要初始化的部份,因此建構子沒有內容 2. “PT_AECHO” 表示AgentECHO agent 所使用的packet類別設為”PT_AECHO”. 利用此packet 類別,Agent可以決定對應的處理. 並且系統trace 輸出也將跟據此類別決定輸出的方式. packet類別可以為任意值,但必須在”../packet.h” 中稍加修改. (可參考講義第4頁)

STEP 2. 以 C++程式碼實現 AgentEcho.cc 的細節(IV) AgentECHO預設必須要實現的函式: command command是由tcl 對此agent class 下指令時,與c++程式溝通的介面. 目前我們讓使用者在劇本中可以對此agent 下三種指令, 分別為: AgentName myaddr Int1 AgentName myport Int2 AgentName ShowName 指令(1)與(2)是用來告知c++程式中,agnet的addr與溝通用的port. 指令(3) 則是要求該agent 列印出addr 與port, 可以當作debug 訊息.

STEP 2. 以 C++程式碼實現 AgentEcho.cc 的細節(V) command 副函式接收到的訊息使用argc 表示參數個數, argv陣列實際紀錄所收到的字串內容.我們可以把上列指令(1)想像成 AgentName myaddr Int1 argc=3 : argv[0] argv[1] argv[2] 判斷所輸入的指令的方式 1. 比對argc 數目 2. 比對 argv[1] 的值

STEP 2. 以 C++程式碼實現 AgentEcho.cc 的細節(VI) int AgentECHO::command(int argc, const char*const* argv) { if (argc == 2) { //AgentName ShowName if (strcmp(argv[1], "ShowName") == 0) { printf(" Hello World -- I am %d port=%d!!\n" ,my_addr,data_port); return (TCL_OK); } else if(argc==3){ // AgentName myaddr Int1 if (strcasecmp(argv[1], "myaddr") == 0) { my_addr= atoi(argv[2]); if (strcasecmp(argv[1], "myport") == 0) {// AgentName myport Int2 data_port= atoi(argv[2]); return Agent::command(argc, argv);

STEP 2. 以 C++程式碼實現 AgentEcho.cc 的細節(VII) 編輯Ns2目錄下的 Makefile, 將AdhocEcho/AdhocEcho.o 加到適當位置去. OBJ_CC = \ …… aodv/aodv_logs.o aodv/aodv.o \ AdhocEcho/AdhocEcho.o \ simulator.o \ 完成後,執行make depend, make. 若無錯誤,就完成了

STEP 3. 建立簡單TCL script 來測試AgentEcho 我們要執行實驗的指令: ./ns scripts/run.tcl -x 1200 -y 800 -stop 20 -tr TRACES/out.tr -mg AdhocEcho/sna_1 -sc movement_scenarios/scen-1200x800-30-500-10-1 -nn 30 -rp AdhocEcho 使用ns 主程式執行 scripts/run.tcl 的設定檔file. -x, -y 用來描述實驗範圍的大小為 1200x800 m2. -stop 設定此實驗模擬20 secs, -tr 則是指定log 檔的位址.

STEP 3. 建立簡單TCL script 來測試AgentEcho (I) ./ns scripts/run.tcl -x 1200 -y 800 -stop 20 -tr TRACES/out.tr -mg AdhocEcho/sna_1 -sc movement_scenarios/scen-1200x800-30-500-10-1 -nn 30 -rp AdhocEcho -mg 指定了本程式的劇本為AdhocEcho/sna_1, -sc 指定了節點的移動路徑設定檔file 為movement_scenarios/scen-1200x800-30-500-10-1。 -nn 指定了模擬實驗中的節點總數為50, -rp 則指定模擬的protocol 為adhocEcho(根據這個敘述,ns2將尋找並載入adhocEcho/adhocEcho.tcl .

STEP 3. 建立簡單TCL script 來測試AgentEcho (II) – 4個重要的scripts 1: srcipts/run.tcl: 用來建立adhoc nodes的設定檔, 此設定檔將自動建立 -nn 個節點. 此檔案無須修改,並在 srcipts 子目錄下面可以找到. 2: AdHocEcho.tcl: 用來描述建立一個adhoc node較底層的設定, 此檔案較為難懂,建議copy我的file,並稍加修改其內容即可(下面介紹要修改的部份), 注意此file名稱必須與資料夾名稱相同.

STEP 3. 建立簡單TCL script 來測試AgentEcho (III) – 4個重要的script 3: scen-1200x800-30-500-10-1: adhoc nodes 移動的路徑設定, 用setdest的程式來產生 4: sna_1: 實驗的劇本設定.用來指定實驗節點的互動方式. 由於大部分的運作邏輯利用c++ 實現在 AdEchoAgent的邏輯之中,所以此劇本大致上只是進行簡單的設定,起動與結束的動作.

STEP 3. 建立簡單TCL script 來測試AgentEcho (IV) 在AdHocEcho.tcl中,所需修改的程式部份為 create-client的副程式 ODMRPNode instproc create-client {} { $self instvar dmux_ mcast_dmux_ global RouterTrace AgentTrace opt #set s_agent [new Agent/IRODV1] set s_agent [new Agent/ADECHO] // 只需改這裡,改成我們的agent set id_ [$self id] set port $opt(uni_data_port) $s_agent myaddr $id_ $s_agent myport $port … return $s_agent }

STEP 3. 建立簡單TCL script 來測試AgentEcho (V) sna_1 的內容: 節點之間的互動 for {set i 0} {$i < $opt(nn)} {incr i} { set ag_($i) [$node_($i) create-client] // 呼叫我們剛剛修改的副程式,將agent 架構在node 上 $ns_ at 2.000 "$ag_($i) ShowName" // 要求 ns 在 2 sec 時,對每一個agent 下 ShowName的指令 } 試試看. 看一下效果如何.

補充: setdest 的用法 用 setdest 產生random walk 的移動 Setdest 的參數 在compile 時,會自動compile 出setdest 這個utility Setdest 的參數 usage: ./setdest -n <nodes> : 要移動的節點數 -p <pause time> : 移動間的休息時間 -s <max speed> : 移動速度 m/s -t <simulation time> : 模擬時間 -x <max X> -y <max Y> : 模擬範圍 X, Y

Ns2 一個常用的網路模擬器 Step4. 加入傳送與接收封包的功能

STEP 4. request/response 的能力 目標新功能 EchoAgent 可以接受來自ns 的 send 指令. 在收到send 指令之後, Echo Agent 將廣播一個Echo封包給其鄰居, 所有收到Echo封包的人將回送一個reply 封包.

目標分析 上面的需求可以分成: 在command 副函式中加入send指令的描述, 當Ns2 執行 send 指令時, echo_send 的副函式將被執行. 實現echo_send 的副函式,其內容為廣播一個echo-request 封包 改寫 recv 函式, 當確認收到echo 封包時, 呼叫 echo_recv 函式來回應 實現echo_recv 的副函式,其內容為當收到echo-request 時, 送出一個echo-reply 封包, 當收到echo-reply時,列印相關訊息

傳送Request (Send 的能力) 我們在command 副函式中,加入send 指令的描述 AgentECHO::command 副函式的內容將改成: int AgentECHO::command(int argc, const char*const* argv) // 程式九 { Tcl& tcl = Tcl::instance(); if (argc == 2) { if (strcmp(argv[1], "send") == 0) { echo_send(); return (TCL_OK); } …..

傳送Request (Send 的能力) (II) 當echo_send 被呼叫時,agent 將準備一個echo-request 的封包,廣播給所有的鄰居。 void AgentECHO::echo_send() // 程式十 Packet *pkt = allocpkt(); // Create New Packet hdr_cmn *ch = hdr_cmn::access(pkt); hdr_ip *iph=hdr_ip::access(pkt); hdr_ahe *aheh=hdr_ahe::access(pkt); iph->saddr()=my_addr; iph->sport()=data_port; iph->daddr()=IP_BROADCAST; iph->dport()=data_port; ch->ptype()=PT_AECHO; aheh->Type=0; // Request Packet aheh->FromNode=my_addr; aheh->FromTime=Scheduler::instance().clock(); target_->recv(pkt, (Handler*)0); } IP Information Fill AdHocEcho’s Header Send Packet.

接收封包 (Recv 的能力) (II) 當一個agent收到封包時,該封包將會被送到recv副函式 。 為了簡化recv的內容,我們多半只在recv中作分類的動作,然後就將不同的封包交給不同的副函式去處理。 void AgentECHO::recv(Packet* pkt, Handler *){// 程式 11 hdr_cmn *ch = hdr_cmn::access(pkt); if(ch->ptype()==PT_AECHO){ // 如果是AdHocEcho 封包,就交給echo_recv() echo_recv(pkt); } Packet::free(pkt);

echo_recv 詳細內容 void AgentECHO::echo_recv(Packet* pkt) // 程式 12 { hdr_ip *iph=hdr_ip::access(pkt); hdr_ahe *aheh=hdr_ahe::access(pkt); if(!aheh->Type){ // Recv Request Packet Packet *npkt = allocpkt(); // 產生Reply用的封包 hdr_ip *niph=hdr_ip::access(npkt); hdr_ahe *naheh=hdr_ahe::access(npkt); hdr_cmn *nch = hdr_cmn::access(npkt); niph->saddr()=my_addr; niph->sport()=data_port; niph->daddr()=iph->saddr(); niph->dport()=data_port; naheh->Type=1; // 設定為Reply用的封包 naheh->FromNode=aheh->FromNode; // 填入訊息 naheh->FromTime=aheh->FromTime; naheh->ReplyNode=my_addr; naheh->ReplyTime=Scheduler::instance().clock(); target_->recv(npkt, (Handler*)0); }else{ // 列印訊息 } echo_recv 詳細內容

試試看: Send/Request 的功能 我們重新make程式,並在sna_1 的最後加入: $ns_ at 12.0001 "$ag_(20) send" 執行實驗指令

Ns2 一個常用的網路模擬器 偵測 Time-out 的能力

STEP 5. 處理Time-out的能力 所謂的Timeout,就是說在一定的時間之內,某一個agent沒有收到該有的回應,因此該agent必須作一些動作來彌補這個意外。 如何知道,已經timeout ? 透過”鬧鐘”class 來達成

想像的劇本 我們要模擬的狀況: A送出一個requeste給B,而期望在1 sec 內收到B的回應,若無回應,則認為已經time-out。 則我們在NS2中要作的是,就是當A送出一個封包時,順便啟動一個會在1sec之後觸發的鬧鐘, 若在1sec內收到回應,則在收到的瞬間,關掉鬧鐘。 否則在1sec 結束後,鬧鐘將會觸發,A也將認為本次的連線是以timeout的情形結束。

目標分析 上面的需求可以分成: 創造一個”鬧鐘”的物件。 當agent 送出request封包時,也馬上設定/啟動鬧鐘 當收到回應封包時,便嘗試著關鬧鐘 一但鬧鐘響,便表示timeout已經發生

創造一個”鬧鐘”的物件 我們必須修改AdhocEcho.h,不僅是定義”鬧鐘”的class,並且要建立鬧鐘與我們的agent的互動。我們將我們鬧鐘物件稱為Echo_Timeout,

創造一個”鬧鐘”的物件(I) AdhocEcho.h,定義”鬧鐘”class -- Echo_Timeout 並且要建立鬧鐘與我們的agent的互動。 // 程式13 的上半部 class Echo_Timeout; // ”鬧鐘”class 的宣告 class AgentECHO : public Agent { friend class Echo_Timeout; // 設為friend class 可呼叫private method public: AgentECHO(); virtual void recv(Packet *, Handler *); void Recv_callback(Event* e); protected: virtual int command(int argc, const char*const* argv); ….. }

創造一個”鬧鐘”的物件(II) // 程式13 的下半部 private: int my_addr; int data_port; …… Echo_Timeout* EchoT; // agent 內部宣告一個時鐘 void echo_p2p_send(int dest); // 測試 time-out 的函式 Event *p2pSendEvent; // 為了取消鬧鐘設定的變數 void Recv_callback(Event *); // 與鬧鐘互動的函式 }; class Echo_Timeout : public Handler { // 鬧鐘class 的完整內容 public: Echo_Timeout(AgentECHO *a_) { a = a_; } // 鬧鐘觸發時會執行 handle 副函式 // handle 副函式會執行agent中的Recv_callback副函式 virtual void handle(Event *e) { a->Recv_callback(e); } AgentECHO *a; #endif // ns_ns_irreq_h

AdHocEcho Agent 的Time-out處理 為了創造EchoT的object(鬧鐘),我們在AgentEcho 的建構子中,加入了兩行敘述 AgentECHO::AgentECHO() : Agent(PT_AECHO) // 程式 14 { EchoT= new Echo_Timeout(this); p2pSendEvent=0; }

鬧鐘的使用與測試 為了測試這個時鐘,我們在command新增了 p2psend 的指令 此指令將要求一個輸入,表示要echo 的點,當此command 被執行時,agent 的echo_p2p_send副函式將被執行。 int AgentECHO::command(int argc, const char*const* argv) // 程式 15 { Tcl& tcl = Tcl::instance(); if (argc == 2) { ... } else if(argc==3){ … if (strcasecmp(argv[1], "p2pSend") == 0) { echo_p2p_send(atoi(argv[2])); return (TCL_OK); return Agent::command(argc, argv);

echo_p2p_send 詳細內容 void AgentECHO::echo_p2p_send(int dest) // 程式 16 { Packet *pkt = allocpkt(); hdr_cmn *ch = hdr_cmn::access(pkt); hdr_ip *iph=hdr_ip::access(pkt); hdr_ahe *aheh=hdr_ahe::access(pkt); fprintf(stderr,"%.5f at Node %d sned p2p << Request >> Packet.\n",Scheduler::instance().c iph->saddr()=my_addr; iph->sport()=data_port; iph->daddr()=dest; // 第一個不同 點,送給單一echo對象 iph->dport()=data_port; ch->ptype()=PT_AECHO; aheh->Type=0; aheh->FromNode=my_addr; aheh->FromTime=Scheduler::instance().clock(); target_->recv(pkt, (Handler*)0); p2pSendEvent= new Event(); // 第二個不同點,啟動鬧鐘 Scheduler::instance().schedule(EchoT, p2pSendEvent, 1);

鬧鐘的觸發 當鬧鈴啟動時,主程式中的Recv_callback(Event *) 副函式將自動被執行。 在此,我們只希望他列印一個Timeout 的訊息,因此,我們的Recv_callback(Event *) 副函式的內容如下: void AgentECHO::Recv_callback(Event* e){// 程式 17 fprintf(stderr,"%.5f at Node %d Timeout\n", Scheduler::instance().clock(),addr()); p2pSendEvent =0; }

把鬧鐘關掉 當我們收到正確資料時,我們要把鬧鐘關掉,因此,我們在echo_recv 的副函式中做了以下的更改。 void AgentECHO::echo_recv(Packet* pkt){ // 程式 18 { hdr_ip *iph=hdr_ip::access(pkt); hdr_ahe *aheh=hdr_ahe::access(pkt); if(!aheh->Type){ ….. // 收到request, 回應reply封包 }else{ // 收到reply封包,關掉鬧鐘,印出訊息 if(p2pSendEvent){ Scheduler::instance().cancel(p2pSendEvent); p2pSendEvent=0; } . // 列印訊息

試試看: TimeOut 的功能 我們重新make程式,並在sna_1 的最後加入: $ns_ at 12.0001 "$ag_(20) p2psend 10“ 執行實驗指令試試看