FAQ (常見問題)

A.問題描述:

當安裝好ns以後,並且有設定.bashrc,但在cygwin的視窗輸入ns,卻出現ns command not found的錯誤訊息。

 

問題回答:

1.      請先確定設定好.bashrc後,是否有重新再打開一次cygwin的視窗。

2.      若是有重新打開cygwin的視窗,但還是有這樣的錯誤訊息,則可以直接把ns-allinone-2.x/ns-2.x/ns.exens-allinone-2.x/nam-1.x/nam.exe拷貝到ns-allinone-2.x/bin的目錄下即可,但是這種方法的缺點是,只要每次有重新編譯NS,就要拷貝新的ns.exebin,若是沒有拷貝就會用到舊的版本。因此筆者比較建議的方法是拷貝ns.exe跟要仿真的TCL同一目錄下。例如現在使用的版本是ns-2.28,而要模擬的檔案為test.tcl,所在的目錄在ABC下,則筆者建議的方法為

$cd ABC

$cp ~/ns-allinone-2.28/ns-2.28/ns.exe .

$./ns.exe test.tcl

 

另一解法 (大同大學 無線通訊研究室  戈承榮提供)

請將/etc/skel/下的 .bash_profile .bashrc .inputrc三個檔案 CP /home/"username"-->開啟Cygwin的地方
再修改 .bashrc 即可

 

B.問題描述:

cygwin下同時安裝多個版本的ns?

 

問題回答:

        以安裝ns-2.29ns-2.30為範例。

[安裝ns-2.29]

1. 解壓縮。

 

2. 安裝 (其中smallko是作者的帳戶名稱,smallko-nb是作者的電腦名稱)

 

3. 安裝完成。

 

4. 測試是否有安裝成功。(若是有出現%,則表示安裝成功)

 

[安裝ns-2.30]

1. 解壓縮。

 

2. 安裝

 

3. 安裝完成。

 

4. 測試是否有安裝成功。

 

[使用不同的版本ns去執行模擬]

1.      修改ns.exe檔名,以區別不同版本的ns(ns-2.30下的ns.exe改成ns230.exe;把ns-2.29下的ns.exe改成ns229.exe)

 

2.      拷貝想要使用的ns版本,到要模擬tcl的同一目錄下。(: ns版本為ns-2.30;模擬的tclns-allinone-2.29/ns-2.29/ns-tutorial/examples/example2.tcl) (請先使用文字編輯軟體在exec nam out.nam &之前加上一個#,使之成為# exec nam out.nam &)

若是沒有錯誤的訊息,就表示執行成功。

 

[注意]

請記得在使用ns230.exens229.exe,執行命令都需要加上 ./ 

 

C.問題描述:

什麼是patch,如何使用patch?

 

問題回答:

假設原本的程式碼有誤,或者有一個新功能需要加到原本程式內,最簡單的想法就是直接去修改原本的程式碼,但是若對於一個比較複雜的系統來說,若是要找到需要修改的地方,這對初學者是有點吃力的,因此若是能只要下一個指令,就可以把需要修改的地方一次處理完畢,這會省事不少,而這樣的工作就可以使用patch來達成。

        舉個例子來說明,底下是一個簡單計算a+b的程式(ori.c),現在假設我們需要修改ab的值,並同時可以去計算a-b (new.c),則方法就是直接修改ori.c的程式碼,方法二就是使用diff的方法先產生一個patch檔案,然後把這個patch檔發佈給所需要的人,需要的人拿到此patch檔案只要執行一個指令,就可以把本身的ori.c修改成new.c的樣子。

 

(ori.c)

#include <stdio.h>

 

int main()

{

  int a=5;

  int b=10;

  int sum;

  sum=a+b;

  printf("a+b=%d\n", sum);

  return 0;

}     

 

(new.c)

#include <stdio.h>

 

int main()

{

  int a=10;

  int b=5;

  int sum;

  int diff;

  sum=a+b;

  diff=a-b;

  printf("a+b=%d\n", sum);

  printf("a-b=%d\n", diff);

  return 0;

}

 

使用diff-u 原本檔案 修改後檔案  > patch

$diff -u ori.c new.c > mypatch

--- ori.c    2006-11-29 11:51:46.765625000 +0800

+++ new.c        2006-11-29 11:52:21.656250000 +0800

@@ -2,10 +2,13 @@

 

 int main()

 {

-  int a=5;

-  int b=10;

+  int a=10;

+  int b=5;

   int sum;

+  int diff;

   sum=a+b;

+  diff=a-b;

   printf("a+b=%d\n", sum);

+  printf("a-b=%d\n", diff);

   return 0;

-}    

+}

(上面的-是移除原本程式中的那行程式碼,+是新增後面那行程式碼)

 

所以當使用者執行patch ori.c mypatch,則ori.c的內容就會變成跟new.c是一樣的。

 

步驟

底下我們來練習從網路上下載一個patch檔,用來更新和修正ns-2.29核心程式,修改和更新的內容則請參考網頁說明。

1. 連接到http://www.telematica.polito.it/fiore/index.html#papers

 

2. 下載ns-2.29 wireless update patch

3. 儲存到ns-allinone-2.29的目錄下。(以筆者的電腦為例,則是存放在c:\cygwin\home\smallko\ns-allinone-2.29)

 

4. 打開cygwin。的視窗,進入到ns-allinone-2.29的目錄下,並解開壓縮檔。(解完壓縮檔後會產生readme.txt (說明檔)ns-2.29_wireless_update_patch (patch),和一個tcl資料夾 (資料夾內有測試檔test.tcl)

 

5. 使用patch

 

6. 重新編譯。

 

7. 測試。

模擬結束後若是有出現如上圖所示,則表示有安裝patch成功。若是出現如下圖所示,則表示安裝patch失敗。

 

D.問題描述:

直接從網頁copyTCL的程式碼時,但為何在執行過程會有類似如下錯誤?

 

問題回答:

從網頁直接copy程式碼,然後存到檔案中時,會讓原本每行程式碼間多一行空白,:

網頁的內容:

$ns_ node-config -adhocRouting $val(rp) \

                         -llType $val(ll) \

                         -macType $val(mac) \

                         …………………

拷貝到檔案中:

$ns_ node-config -adhocRouting $val(rp) \

 

                         -llType $val(ll) \

 

                         -macType $val(mac) \

 

                         …………………

因此這個空白就會讓程式執行時發生錯誤請移除空白再執行就可以了

 

E.問題描述:

當我重新Make NS時,為何會出現類似下圖的錯誤?

 

問題回答:

遇到這樣的問題時,請先使用文書編輯軟體打開Makefile檔案。以下面的例子說明,請檢查在第251行的最後面,也就是 \ 之後是否有空白(space),若是有請移除,移除後再重新Make

 

250 …………………………………………

251  tora/tora.o tora/tora_api.o tora/tora_dest.o \

252  tora/tora_io.o tora/tora_logs.o tora/tora_neighbor.o \

253……………………………………………

 

F.問題描述:

      如何觀察無線節點的佇列長度

 

問題回答:

1.      修改queue/priqueue.h

#include "trace.h"

 

class PriQueue : public DropTail {

public:

        PriQueue();

 

        int     command(int argc, const char*const* argv);

        void    recv(Packet *p, Handler *h);

 

        void    recvHighPriority(Packet *, Handler *);

        // insert packet at front of queue

 

        void filter(PacketFilter filter, void * data);

        // apply filter to each packet in queue,

        // - if filter returns 0 leave packet in queue

        // - if filter returns 1 remove packet from queue

 

        Packet* filter(nsaddr_t id);

 

             void    Terminate(void);

 

             //added by smallko

         Tcl_Channel tchan_;        /* place to write trace records */

         TracedInt curq_;      /* current qlen seen by arrivals */

         void trace(TracedVar*); /* routine to write trace records */

………………………………………………………….…………………….

 

2.      修改queue/ priqueue.cc

PriQueue::PriQueue() : DropTail()

{

        bind("curq_",&curq_);

        tchan_=0;

        bind("Prefer_Routing_Protocols", &Prefer_Routing_Protocols);

                LIST_INSERT_HEAD(&prhead, this, link);

}

 

int PriQueue::command(int argc, const char*const* argv)
{
  if (argc == 2 && strcasecmp(argv[1], "reset") == 0) {
        Terminate();
      //FALL-THROUGH to give parents a chance to reset
   }
  else if(argc == 3 &&strcmp(argv[1], "attach") == 0) {
       int mode;
       const char* id = argv[2];
       Tcl& tcl = Tcl::instance();
       tchan_ = Tcl_GetChannel(tcl.interp(), (char*)id, &mode);
       if (tchan_ == 0) {
              tcl.resultf("trace: can't attach %s for writing", id);
              return (TCL_ERROR);
       }
       return (TCL_OK);
    }
  return DropTail::command(argc, argv);
}

 

void PriQueue::recv(Packet *p, Handler *h)

{

    struct hdr_cmn *ch = HDR_CMN(p);

      curq_ = q_->length();

   

        if(Prefer_Routing_Protocols) {

    ……………………………

}

 

void PriQueue::trace(TracedVar* v)

{

        char wrk[500], *p;

 

        if (((p = strstr(v->name(), "curq")) == NULL) ) {

                fprintf(stderr, "PriQueue:unknown trace var %s\n", v->name());

                return;

        }

 

        if (tchan_) {

                int n;

                double t = Scheduler::instance().clock();

               

                if (strstr(v->name(), "curq") != NULL) {

                        sprintf(wrk, "Q %g %d", t, int(*((TracedInt*) v)));

                }

               

                n = strlen(wrk);

                wrk[n] = '\n';

                wrk[n+1] = 0;

                (void)Tcl_Write(tchan_, wrk, n+1);

        }

        return;

}

 

3.      修改tcl/lib/ns-default.tcl

加入 Queue/DropTail/PriQueue set curq_ 0

 

4.      重新編譯

make clean ; make depend ; make

 

(以上的步驟在安裝篇所提供的ns已經把程式碼加上不需要再修改相對應的程式碼了)

 

5.      範例測試

(測試檔案名稱為 :test-queuelen.tcl)

set ns [new Simulator]

 

#number of nodes

set num_mobile_nodes 3

 

# Parameter for wireless nodes

set opt(chan)           Channel/WirelessChannel    ;# channel type

set opt(prop)           Propagation/TwoRayGround   ;# radio-propagation model

set opt(netif)          Phy/WirelessPhy            ;# network interface type

set opt(mac)            Mac/802_11                 ;# MAC type

set opt(ifq)            Queue/DropTail/PriQueue    ;# interface queue type

set opt(ifqlen)         50

set opt(ll)             LL                         ;# link layer type

set opt(ant)            Antenna/OmniAntenna        ;# antenna model

set opt(ifqlen)         50                        ;# max packet in ifq

set opt(adhocRouting)   DumbAgent                       ;# routing protocol

set opt(x)          670  ;# X dimension of the topography

set opt(y)          670          ;# Y dimension of the topography

 

#smallko add the following two lines

Mac/802_11 set dataRate_  1Mb

Mac/802_11 set basicRate_  1Mb

 

set ntr [open out_rc_3.tr w]

$ns trace-all $ntr

 

set chan    [new $opt(chan)]

set topo    [new Topography]

 

$topo load_flatgrid $opt(x) $opt(y)

 

# Create God

create-god $num_mobile_nodes

 

# config node

$ns node-config -adhocRouting $opt(adhocRouting) \

                 -llType $opt(ll) \

                 -macType $opt(mac) \

                 -ifqType $opt(ifq) \

                 -ifqLen $opt(ifqlen) \

                 -antType $opt(ant) \

                 -propType $opt(prop)    \

                 -phyType $opt(netif) \

                 -channel $chan      \

                 -topoInstance $topo \

                 -wiredRouting OFF \

                 -agentTrace ON \

                 -routerTrace OFF \

                 -macTrace OFF    \

                 -movementTrace OFF

 

# creating mobile nodes

Mac/802_11 set RTSThreshold_ 3000

for {set i 0} {$i < $num_mobile_nodes} {incr i} {

    set wl_node_($i) [$ns node]        

    $wl_node_($i) random-motion 0               ;# disable random motion

    puts "wireless node $i created ..."

    $wl_node_($i) set X_ [expr $i * 10.0]

    $wl_node_($i) set Y_ [expr $i * 10.0]

    $wl_node_($i) set Z_ 0.0

}

 

#設定所要觀察節點的interface queue

set wl_ifq [$wl_node_(0) set ifq_(0)]

#設定觀察結果所要存放的檔案名稱

set queuechan [open qlen.tr w]

#設定要觀察的變數為目前佇列長度curq_

$wl_ifq trace curq_

$wl_ifq attach $queuechan

 

for {set i 0} {$i < $num_mobile_nodes} {incr i} {

    set src_udp_($i) [new Agent/UDP]

    $src_udp_($i) set class_ $i

    set dst_udp_($i) [new Agent/Null]

    $ns attach-agent $wl_node_($i) $src_udp_($i)

    $ns attach-agent $wl_node_([expr ($i+1)%($num_mobile_nodes)]) $dst_udp_($i)

    set app_($i) [new Application/Traffic/CBR]

    $app_($i) set packetSize_ 1025

    $app_($i) set interval_ 0.005

    $app_($i) attach-agent $src_udp_($i)

    $ns connect $src_udp_($i) $dst_udp_($i)

    $ns set fid_ $i

    $ns at $i "$app_($i) start"

}

 

# Define node initial position in nam

for {set i 0} {$i < $num_mobile_nodes} {incr i} {

    $ns initial_node_pos $wl_node_($i) 20

   }

 

# Tell nodes when the simulation ends

for {set i 0} {$i < $num_mobile_nodes } {incr i} {

    $ns at 10.0 "$wl_node_($i) reset";

}

 

for {set i 0} {$i < $num_mobile_nodes} {incr i} {

    $ns at 5.0 "$app_($i) stop"

}

 

$ns at 11.0 "puts \"NS EXITING...\" ; $ns halt"

 

proc stop {} {

    global ns ntr queuechan

    close $ntr

    close $queuechan

}

 

# run the simulation

$ns run

 

模擬方式

$ns test-queuelen.tcl

 

模擬結束後就會產生一個qlen.tr

 

進入圖形介面

$startxwin.bat

$gnuplot

gnuplot> plot qlen.trusing 2:3 with linespoints

gnuplot> set xlabel time (sec)

gnuplot> set ylabel length (pkt)

gnuplot> set key off

gnuplot> replot

gnuplot> set terminal gif

gnuplot> set output qlen.gif

gnuplot> replot

 

結果就如下圖所示。