2008年8月30日 星期六

NS2 - Wireless

wireless model主要是由MobileNode所組成,MobileNode由Node這個類別繼承而來,因此MobileNode除了有基本的Node能力,還有移動和無線傳送接收的能力。目前ad-hoc routing protocol有支援四種Destination Sequence Distance Vector (DSDV)、 Dynamic Source Routing (DSR) 、 Temporally Ordered Routing Algorithm (TORA)以及 Ad-hoc On-demand Distance Vector (AODV)。

在建立Mobile Node之前,我們必須定義Mobile Node所活動的topology大小。

set topo [ new Topography ]
$topo load_flatgrid $opt(x) $opt(y)

 

接著我們要建立一個God instance,這是用來建立一個矩陣,用以儲存topology的連線資訊。 create-god $opt(nn)

舊的API建立Mobile Node根據使用的routing protocol,而新的 API則是藉由$ns node-config這個instproc來設定,接著就使用產生一般的node的方式產生Mobile Node。



$ns node-config -adhocRouting $opt(adhocRouting) 
                -llType $opt(ll) 
                -macType $opt(mac) 
                -ifqType $opt(ifq) 
                -ifqLen $opt(ifqlen) 
                -antType $opt(ant) 
                -propInstance [new $opt(prop)] 
                -phyType $opt(netif) 
                -channel [new $opt(chan)] 
                -topoInstance $topo 
                -wiredRouting OFF 
                -agentTrace ON 
                -routerTrace OFF 
                -macTrace OFF

for { set i 0 } { $i < $opt(nn) } { incr i } {
  set node($i) [ $ns node ]
  $node($i) random-motion 0 ;# disable random motion
}

雖然Mobile Node被設計成可以在三維空間中移動(X,Y,Z),但是Z尚未被使用,因此我們假設只在平面上移動,也就是Z永遠等於0。我們藉由設定X,Y,Z來初始Mobile Node的初始位置,並且使用setdest來移動Mobile Node,也可以使用$node start來做random的移動,不過不建議使用此方式,如果要做random的scenario可以使用CMU提供的tool -- setdest (放在~ns/indep-utils/cmu-scen-gen/中)。

$node set X_ <x1>
$node set Y_ <x2>
$node set Z_ 0
$ns at <time> $node setdest <x2> <y2> <speed> ;# 在時間time秒, 以速度speed往(x2,y2)移動
example1.tcl # ======================================================================
# Default Script Options
# ======================================================================
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/Simple                                ;# MAC type
set opt(ifq) Queue/DropTail/PriQueue                   ;# interface queue type
set opt(ll) LL                                         ;# link layer type
set opt(ant) Antenna/OmniAntenna                       ;# antenna(天線) model
set opt(ifqlen) 50                                     ;# max packet in ifq
set opt(nn) 2                                          ;# number of mobile nodes

set opt(rp) AODV                                       ;# routing protocol. DSDV, DSR, AODV.

#Destination-Sequenced Distance-Vector Routing(AODV)
#Dynamic Source Routing (DSR)
#destination sequenced distance vector (DSDV)
set opt(x) 670                                         ;# Topology大小
set opt(y) 670                                         ;# Topology大小
set opt(trace) wireless_basic.tr                       ;# trace file
set opt(nam.tr) wireless_basic.nam                     ;# the nam trace file

# ======================================================================
# Main Program
# ======================================================================
# Initialize Global Variables
set ns [new Simulator]                                 ;#建立一個新的模擬物件,並指向變數ns

# This command should be called before the universal trace command $ns trace-all
$ns use-newtrace                                       ;#建立一個新的trace資料

set namtrace [open $opt(nam.tr) w]                     ;#開起一個$opt(nam.tr)wireless_basic.nam,並且指向namtrace
#把模擬的過程寫入$namtrace,長為$opt(x),寬為opt(y),因為是wireless,所以,要改用namtrace-all-wireless指令
$ns namtrace-all-wireless $namtrace $opt(x) $opt(y)
;#開起一個$opt(trace)wireless_basic.tr,並且指向tracefd
set tracefd [open $opt(trace) w]
$ns trace-all $tracefd ;#把模擬器的封包過程寫入$tracefd

proc finish { } {                                      ;# new a procedure finish
global ns namtrace tracefd opt                         ;# set global variable
$ns flush-trace                                        ;#把trace清空,都寫入
close $namtrace                                        ;# close file
close $tracefd                                         ;# close file
exec nam $opt(nam.tr) &                                ;#在背景執行nam去打開$opt(nam.tr)
exit 0
}


# set up topography object 定義Mobile Node所活動的topology大小
set topo [new Topography]                              ;#建立一個新的地形
$topo load_flatgrid $opt(x) $opt(y)                    ;#設定長寬

#An omniscient observer
#Stores smallest number of hops from one node to another
#Optimal case to compare routing protocol performance
#Automatically generated by scenario file
#set god [create-god <no of mnodes>]設定node個數
#$god set-dist <from> <to> <#hops>
# Create God (General Operations Director)
# 加入這一行,會出現"num_nodes is set 2"的訊息
create-god $opt(nn)

# Create channel
set chan_ [new $opt(chan)]            ;#set chan_ [new Channel/WirelessChannel] 設定Channel

# Create node(0) and node(1)

# configure node, please note the change below.設定節點的參數
$ns node-config -adhocRouting $opt(rp) \                ;# -adhocRouting AODV 
                -llType $opt(ll) \                      ;# -llType LL
                -macType $opt(mac) \                    ;# -macType Mac/Simple
                -ifqType $opt(ifq) \                    ;# -ifqType Queue/DropTail/PriQueue
                -ifqLen $opt(ifqlen) \                  ;# -ifqLen 50
                -antType $opt(ant) \                    ;# -antType Antenna/OmniAntenna
                -propType $opt(prop) \                  ;# -propType Propagation/TwoRayGround
                -phyType $opt(netif) \                  ;# -phyType Phy/WirelessPhy
                -topoInstance $topo \                   ;# -topoInstance
                -agentTrace ON \                        ;# 在無線網路,要設定是否要打開agent Trace
                -routerTrace ON \                       ;# 在無線網路,要設定是否要打開router Trace
                -macTrace ON \                          ;# 在無線網路,要設定是否要打開mac Trace
                -movementTrace ON \                     ;# 在無線網路,要設定是否要打開movement Trace
                -channel $chan_                         ;# 設定channel 
#以下指令打完,會出現"INITIALIZE THE LIST xListHead"的訊息
for {set i 0} {$i < $opt(nn)} {incr i} {
set node($i) [$ns node]
$node($i) random-motion 0                               ;# disable random motion
$ns initial_node_pos $node($i) 20                       ;# 在nam中定義節點初始所在位置
}

#
# Provide initial (X,Y, for now Z=0) co-ordinates for mobilenodes
#
$node(0) set X_ 15.0
$node(0) set Y_ 15.0
$node(0) set Z_ 0.0

$node(1) set X_ 150.0
$node(1) set Y_ 150.0
$node(1) set Z_ 0.0

#
# Now produce some simple node movements
# Node_(1) starts to move towards node_(0)
#
$ns at 0.0 "$node(0) setdest 50.0 50.0 5.0"              ;# 以5.0的速度移動到目標(50.0,50.0)
$ns at 0.0 "$node(1) setdest 60.0 40.0 10.0"             ;# 以10.0的速度移動到目標(60.0,40.0)


# Node(1) then starts to move away from node_(0)
# 若加入這一行指令,在執行這一個tcl時,會出現"SORTING LISTS ...DONE!"的訊息
$ns at 3.0 "$node(1) setdest 240.0 240.0 30.0" ;#以30.0的速度移動到目標(240.0,240.0)

# Setup traffic flow between nodes
# TCP connections between node(0) and node(1)

set tcp [new Agent/TCP]                                  ;#建立TCP物件
$tcp set class_ 2                                        ;#設定顏色
set sink [new Agent/TCPSink]                             ;#建立TCPSink物件
$ns attach-agent $node(0) $tcp                           ;#把node(0)建立在TCP通訊協定上
$ns attach-agent $node(1) $sink                          ;#把node(1)建立在TCPSink通訊協定上
$ns connect $tcp $sink                                   ;#把TCP與TCPSink相連
set ftp [new Application/FTP]                            ;#建立ftp通訊
$ftp attach-agent $tcp                                   ;#把ftp建立在tcp協定上
$ns at 0.5 "$ftp start"                                  ;#在時間0.5ftp開始傳送

#
# Tell nodes when the simulation ends
#
for {set i 0} {$i < $opt(nn) } {incr i} {
$ns at 6.0 "$node($i) reset";                            ;#會reset node上所有的agents
}
$ns at 6.0 "finish"
$ns at 6.01 "puts \"NS EXITING...\" ; $ns halt"          ;#ns停止

puts "Starting Simulation..."
$ns run

純程式碼
example.tcl

set ns [new Simulator]

$ns use-newtrace

set namtrace [open wireless_basic.nam w]
$ns namtrace-all-wireless $namtrace 670 670

set tracefd [open wireless_basic.tr w]
$ns trace-all $tracefd

proc finish {} {
  global ns namtrace tracefd
  $ns flush-trace
  close $namtrace
  close $tracefd
  exec nam wireless_basic.nam &
  exit 0
}

set topo [new Topography]
$topo load_flatgrid 670 670

create-god 2

set chan_ [new Channel/WirelessChannel]

$ns node-config -adhocRouting AODV \
                -llType LL \
                -macType Mac/Simple \
                -ifqType Queue/DropTail/PriQueue \
                -ifqLen 50 \
                -antType Antenna/OmniAntenna \
                -propType Propagation/TwoRayGround \
                -phyType Phy/WirelessPhy \
                -topoInstance $topo \
                -agentTrace ON \
                -routerTrace ON \
                -macTrace ON \
                -movementTrace ON \
                -channel $chan_

for {set i 0} {$i<2} {incr i} {
  set node($i) [$ns node]
  $node($i) random-motion 0
  $ns initial_node_pos $node($i) 20
}

$node(0) set X_ 15.0
$node(0) set Y_ 15.0
$node(0) set Z_ 0.0

$node(1) set X_ 150.0
$node(1) set Y_ 150.0
$node(1) set Z_ 0.0

$ns at 0.0 "$node(0) setdest 50.0 50.0 5.0"
$ns at 0.0 "$node(1) setdest 60.0 40.0 10.0"

$ns at 3.0 "$node(1) setdest 240.0 240.0 30.0"

set tcp [new Agent/TCP]
$ns color 2 Red
$tcp set class_ 2
set sink [new Agent/TCPSink]
$ns attach-agent $node(0) $tcp
$ns attach-agent $node(1) $sink
$ns connect $tcp $sink
set ftp [new Application/FTP]
$ftp attach-agent $tcp
$ns at 0.5 "$ftp start"

for {set i 0} {$i<2} {incr i} {
  $ns at 6.0 "$node($i) reset"
}


$ns at 6.0 "finish"
$ns at 6.01 "puts \"NS EXITING...\";$ns half"

puts "Starting Simulator..."
$ns run

NS-2-TCP Agent



############################################################
# set option value
############################################################
set opt(trace) out.nam                  ;# 設定nam檔為out.nam
set opt(nodes) 10                       ;# 節點個數
set opt(rtproto) DV                     ;# 路由協定
set opt(src.packet.size) 1000           ;# 來源端封包大小
set opt(src.packet.int) 0.005           ;# 來源端封包間隔

############################################################
# main program
############################################################
set ns [new Simulator]                  ;# 在檔案一開始會先建立一個的模擬
$ns rtproto $opt(rtproto)               ;# 設定路由協定

set nf [open $opt(trace) w]             ;# 開啟一個可寫入的檔案out.nam
$ns namtrace-all $nf                    ;# 將所有模擬的資料都寫入$nf這個檔案中
$ns use-newtrace

proc finish {} {                        ;# 新增一個procedure "finish" 
  global ns nf opt                      ;# 讓這個proc能讀取這個scrpit的其他變數
  $ns flush-trace                       ;# Use new trace format 使用新的trace format

  close $nf
  exec nam $opt(trace) &
  exit 0
}

for {set i 0} {$i < $opt(nodes)} {incr i} { ;# 建立節點
  set n($i) [$ns node]
}

for {set i 0} {$i < $opt(nodes)} {incr i} { ;# 建立一個環狀的topology
$ns duplex-link $n($i) $n([expr ($i+1)%$opt(nodes)]) 1Mb 10ms DropTail
}

set tcpS0 [new Agent/TCP]                   ;# TCP Sender
$ns attach-agent $n(0) $tcpS0               ;# 將TCP Sender裝在$n(0)
set tcpR0 [new Agent/TCPSink]               ;# TCP Sink with one ACK per packet
$ns attach-agent $n(2) $tcpR0               ;# 將TCP Sink裝在$n(2)

$ns connect $tcpS0 $tcpR0                   ;# 將TCP Sender 和TCP Sink做連結

set ftp [$tcpS0 attach-app FTP]             ;# TCP上層的流量是FTP

$ns at 0.5 "$ftp start"
$ns rtmodel-at 1.5 down $n(1)               ;# 在第1.5秒$n(1)停掉所有的interface
$ns rtmodel-at 3.5 up $n(0) $n(1)           ;# 在第2.5秒,將$n(0)和$n(1)的介面up
$ns rtmodel-at 5.5 up $n(1) $n(2)           ;# 在第2.5秒,將$n(1)和$n(2)的介面up
$ns at 7.5 "$ftp stop"
$ns at 9.5 "finish"                         ;# 在第9.5秒,結束模擬

$ns run                                     ;# 開始執行模擬

2008年8月29日 星期五

NS-2 - UDP Agent

############################################################
# set option value

# 設定參數
############################################################

#利用陣利設定參數
set opt(trace) out.nam                                        ;# 設定檔案參數
set opt(nodes) 10                                             ;# 節點個數
set opt(rtproto) DV                                           ;# 路由協定
set opt(src.packet.size) 800                                  ;# 來源端封包大小
set opt(src.packet.int) 0.5                                   ;# 來源端封包間隔
set opt(udp.MMS) 100                                          ;# Max Sefment Size for UDP afent
set opt(udp.dest.addr) 1                                      ;# 還不知道這個怎麼用?
set opt(udp.dest.port) 80
set opt(udp.ttl) 6                                            ;# Time-To-Live

############################################################
# main program
############################################################
set ns [new Simulator]                                        ;# 在檔案一開始會先建立一個的模擬環境
$ns rtproto $opt(rtproto)                                     ;# 設定路由協定

set nf [open $opt(trace) w]                                   ;# 開啟一個可寫入的檔案out.nam
$ns namtrace-all $nf                                          ;# 將所有模擬的資料都寫入$nf這個檔案中
$ns use-newtrace                                              ;# Use new trace format 使用新的trace format

proc finish {} {                                              ;# 新增一個procedure "finish"
  global ns nf opt                                            ;# 讓這個proc能讀取這個scrpit的其他變數,其中opt是陣列,只要global這一個opt,陣列其它元素就可以使用
  $ns flush-trace                                             ;# 將所有的trace object 寫入 buffer
  close $nf                                                   ;# 關掉out.nam檔
  exec nam $opt(trace) &                                      ;# 透過背景執行nam來開起out.nam檔
  exit 0                                                      ;# 離開
}

for {set i 0} {$i < $opt(nodes)} {incr i} {
  set n($i) [$ns node]                                        ;# 建立節點
}

for {set i 0} {$i < $opt(nodes)} {incr i} {                   ;# 建立一個環狀的topology
$ns duplex-link $n($i) $n([expr ($i+1)%$opt(nodes)]) 1Mb 10ms DropTail
}

set udp0 [new Agent/UDP]                                      ;# 新增一個udp,第一個node裝UDP Agent
$udp0 set packetSize_ $opt(udp.MMS)                           ;# Max Segment Size for UDP agent
$udp0 set dst_addr_ $opt(udp.dest.addr)                       ;# 目的地IP
$udp0 set dst_port_ $opt(udp.dest.port)                       ;# 目的地Port number
$udp0 set ttl_ $opt(udp.ttl)                                  ;# Time-To-Live

$ns attach-agent $n(0) $udp0                                  ;# 在$n(0)上裝上$udp0

set cbr0 [new Application/Traffic/CBR]                        ;# 先建立一個cbr,然後在udp上裝CBR
$cbr0 set packetSize_ $opt(src.packet.size)                   ;# 設定CBR封包大小
$cbr0 set interval_ $opt(src.packet.int)                      ;# 設定CBR發射封包的間隔時間
$cbr0 attach-agent $udp0                                      ;# 把cbr0架在udp0上,CBR應用程式是在UDP協定上運作的

set null0 [new Agent/Null]                                    ;# 先建立一個NULL特性,在第3個node上裝Null Agent,NULL Agent是用來drop packet的
$ns attach-agent $n(2) $null0                                 ;# 把null0建立在n(2)上

$ns connect $udp0 $null0                                      ;# 將來源端和目的端連結起來

$ns at 0.5 "$cbr0 start"                                      ;# 在第0.5秒開始送封包
$ns rtmodel-at 1.5 down $n(1)                                 ;# 在第1.5秒$n(1)停掉所有的interface
$ns rtmodel-at 3.5 up $n(0) $n(1)                             ;# 在第2.5秒,將$n(0)和$n(1)的介面up
$ns rtmodel-at 5.5 up $n(1) $n(2)                             ;# 在第2.5秒,將$n(1)和$n(2)的介面up
$ns at 9.5 "finish"                                           ;# 在第9.5秒,結束模擬

$ns run                                                       ;# 開始執行模擬

透過Windows Live Writer來寫blog

最近常用blog記錄我的學習進度~ 直接在網頁寫程式有時候會很麻煩~像是<要用&lt;取代, 因此,是有一點麻煩啦~

在網路上找到原來Windows Live Writer可以支援blogspot哩~

因為,在網頁使用半行的空白會被忽略~在Html模式要用&nbsp;一直取代~
真的很麻煩~不過,我覺得就是有經驗過之前用Html去編輯過~現在我對Html比較了解哩~

之後,應該常用Windows Live Writer來寫blog吧~

Windows Live Writer 下載 :
http://get.live.com/writer/overview

系統需求:
需安裝 .NET Framework 2.0 套件。

參考資料:

Windows Live Writer 超強部落格寫作軟體 讓您想寫就寫
如何用Windows Live Writer修改更早之前的舊文?

ns2 - Link的基本指令



透過ns-2來模擬上面的網路情況
simple.tcl

set ns [new Simulator]
;# 在檔案一開始會先建立一個的模擬
;# step1:先建立一個Simulator物件
;# step2:把ns變數設定為物件:set ns 物件

$ns color 1 Blue
;# 定義color index 1=> Blue
$ns color 2 Red
;# 定義color index 2=> Red

set nf [open out.nam w]
;# 開啟一個可寫入的檔案out.nam
;# step1:先執行open out.nam w,並傳回這一個物件
;# step2:設定nf為記錄這一個物件

$ns namtrace-all $nf
;# 將所有模擬的資料都寫入$nf這個檔案中

;# 新增一個procedure "finish"
proc finish {} {
  global ns nf
  ;# 宣告ns與nf為在外面定義過的變數
  $ns flush-trace
  ;# 把trace的結果寫入檔案中
  close $nf
  ;# 關掉檔案
  exec nam out.nam &
  ;# 在背景中,透過nam去執行out.nam
  exit 0
  ;# 離開
}

#建立4個Node
set n0 [$ns node]
set n1 [$ns node]
set n2 [$ns node]
set n3 [$ns node]
;# 設定n0為一個node
;# step1:$ns node傳回一個node物件
;# step2:設定n0為這一個傳回的物件

#建立三個link
$ns duplex-link $n0 $n2 1Mb 10ms DropTail
#; node 0連到node 2 頻寬為1Mb,delay time為10ms 為DropTail
$ns duplex-link $n1 $n2 1Mb 10ms DropTail
#; node 1連到node 2 頻寬為1Mb,delay time為10ms 為DropTail
$ns duplex-link $n3 $n2 1Mb 10ms SFQ
#; node 2連到node 3 頻寬為1Mb,delay time為10ms 為SFQ

#設定link的屬性
$ns duplex-link-op $n0 $n2 orient right-down
#; 把它想成一點,往右下延伸
$ns duplex-link-op $n1 $n2 orient right-up
#; 把它想成一點,往右上延伸
$ns duplex-link-op $n2 $n3 orient right
#; 把它想成一點,往右延伸

#Monitor the queue for the link between node 2 and node 3
$ns duplex-link-op $n2 $n3 queuePos 0.5
;# 觀測n2到n3之間queue的變化,這是要給NAM用的
;# 也就是說只查看安置由n2到n3的封包Queue的情況

set udp0 [new Agent/UDP]
;# 新增一個UDP agent
$udp0 set class_ 1
;# 將$upd1顏色設成1 (Blue)
$ns attach-agent $n0 $udp0
;# $n0架構在$udp0上

set cbr0 [new Application/Traffic/CBR]
;# 建立應用層的流量描述
$cbr0 set packetSize_ 500
;# 設定封包大小
$cbr0 set interval_ 0.005
;# 設定封包間隔時間
$cbr0 attach-agent $udp0
;# 依附在UDP agent上

set udp1 [new Agent/UDP]
$udp1 set class_ 2
;# 將$upd1顏色設成2 (Red)
$ns attach-agent $n1 $udp1

set cbr1 [new Application/Traffic/CBR]
$cbr1 set packetSize_ 500
$cbr1 set interval_ 0.005
$cbr1 attach-agent $udp1

set null0 [new Agent/Null]
;# 建立一個Null Agent
$ns attach-agent $n3 $null0
;# 將$n3架構在$null0

$ns connect $udp0 $null0
;# 把agent $udp0和agent $null0連在一起
$ns connect $udp1 $null0
;# 把agent $udp1和agent $null0連在一起

$ns at 0.5 "$cbr0 start"
$ns at 1.0 "$cbr1 start"
$ns at 4.0 "$cbr1 stop"
$ns at 4.5 "$cbr0 stop"
$ns at 5.0 "finish"

$ns run


注意在attach-agent的時候,有時候會不確定哪一個在前面,哪一個在後面~
反正,目前就這樣記,udp、tcp的份量比較大,放在後面

2008年8月28日 星期四

好用的免費軟體

Gimp[portable][Linux、Windows]
Gimp為媲美Photoshop的影像處理軟體
不過,我覺得那一些功能都太高級了~目前我使用不到~簡單的圖示,可以用OpenOffice.org Drawing喔~

OpenOffice.org[portable][Linux、Windows、Mac]:
OpenOffice.org(簡稱OOo或OO.o)是一套開放原始碼的辦公室軟體、包含Writer、Calc、Impress、Math、Draw、Base

Google 軟體集

Google瀏覽器



參考資料:
自由軟體學習地圖
Portable軟體
在 Windows 環境下使用自由軟體

2008年8月27日 星期三

ns2 - 指令格式

建立一個simple-link

$ns simplex-link <node1> <node2> <bandwidth> <delay> <queue type> <args>


建立一個duplex-link

$ns duplex-link <node1> <node2> <bandwidth> <delay> <queue type> <args>

<queue type> := DropTail | RED | CBQ | FQ | SFQ | DRR

設定simple-link的屬性

$ns simplex-link-op <n1> <n2> <op> <args>


設定duplex-link的屬性

$ns duplex-link-op <n1> <n2> <op> <args>

<op> := orient | color | queuePos | label

為nam定義color index, 後面可以這個index來指名顏色。

$ns color <color-id> <color>


[UDP Agent]

Maximum Segment Size (MSS)

$udp set packetSize_ <pksize>


目的地IP

$udp set dst_addr_ <address>


目的地Port number

$udp set dst_port_ <portnum>


Time-To-Live

$udp set ttl_ <time-to-live>


[TCP Agent]

TCP Agent被實作在tcp.{cc, h}中,主要有兩種TCP agent:one-way agent和 two-way agent。One-way就是單純只扮演Sender或是 Receiver,Two-way同時是Sender也是Receiver。

[One-Way Sender]

Agent/TCP:a "tahoe" TCP sender

Agent/TCP/Reno: a "Reno" TCP sender

Agent/TCP/Newreno:a "Reno" TCP sender with a modification

Agent/TCP/Sack1:TCP with selective repeat (follows RFC2018)

Agent/TCP/Vegas:TCP Vegas

Agent/TCP/Fack:Reno TCP with "forward acknowledgement"

One-Way Receiver

Agent/TCPSink:TCP sink with one ACK per Packet

Agent/TCPSink/DelAck:TCP sink with configurable delay per ACK

Agent/TCPSink/Sack1:selective ACK sink (follows RFC2018)

Agent/TCPSink/Sack1/DelAck:Sack1 with DelAck

Two-way只有支援Reno:Agent/TCP/FullTcp

[Wireless]

wireless model主要是由MobileNode所組成,MobileNode由Node這個類別繼承而來,因此MobileNode除了有基本的Node能力,還有移動和無線傳送接收的能力。目前ad-hoc routing protocol有支援四種Destination Sequence Distance Vector (DSDV)、 Dynamic Source Routing (DSR) 、 Temporally Ordered Routing Algorithm (TORA)以及 Ad-hoc On-demand Distance Vector (AODV)。

在建立Mobile Node之前,我們必須定義Mobile Node所活動的topology大小。

set topo [ new Topography ]
$topo load_flatgrid $opt(x) $opt(y)


接著我們要建立一個God instance,這是用來建立一個矩陣,用以儲存topology的連線資訊。

create-god $opt(nn)


舊的API建立Mobile Node根據使用的routing protocol,而新的 API則是藉由$ns node-config這個instproc來設定,接著就使用產生一般的node的方式產生Mobile Node。

$ns_ node-config -adhocRouting $opt(adhocRouting)
                 -llType $opt(ll)
                 -macType $opt(mac)
                 -ifqType $opt(ifq)
                 -ifqLen $opt(ifqlen)
                 -antType $opt(ant)
                 -propInstance [new $opt(prop)]
                 -phyType $opt(netif)
                 -channel [new $opt(chan)]
                 -topoInstance $topo
                 -wiredRouting OFF
                 -agentTrace ON
                 -routerTrace OFF
                 -macTrace OFF

for { set i 0 } { $i < $opt(nn) } { incr i } {
set node($i) [ $ns node ]
$node($i) random-motion 0 ;# disable random motion
}


雖然Mobile Node被設計成可以在三維空間中移動(X,Y,Z),但是Z尚未被使用,因此我們假設只在平面上移動,也就是Z永遠等於0。我們藉由設定X,Y,Z來初始Mobile Node的初始位置,並且使用setdest來移動Mobile Node,也可以使用$node start來做random的移動,不過不建議使用此方式,如果要做random的scenario可以使用CMU提供的tool -- setdest (放在~ns/indep-utils/cmu-scen-gen/中)。

$node set X_ <x1>
$node set Y_ <x2>
$node set Z_ 0
$ns at <time> $node setdest <x2> <y2> <speed> ;# 在時間time秒, 以速度speed往(x2,y2)移動

Tcl 語法

一開始可以先參考這裡:TCL 簡介
書簽:
[變數(variable)和變數替換(variable substituion)][表示式(expressions)][指令替換(command substitution)][流程控制(control flow)][程序(procedures)][陣列(arrays)][字串(strings)][輸出(output)]

key words:$、set、puts、expr、ns、if、elseif、else、incr、foreach、while、switch、proc、global

因為ns2的劇本是由tcl語法寫成的~所以,我們要先了解tcl語法如何使用~

因為沒有時間,
下面的網頁就寫的很清楚了,所以,大部分還是去參考下面的網頁吧~若以後,我有空再補吧~
我只寫出我遇到的問題~

;#
上面兩個聯合符號是表示後面的東西就是註解

[變數(variable)和變數替換(variable substituion)]

[表示式(expressions)]

[指令替換(command substitution)]

[流程控制(control flow)]
寫完範例後,竟然出現:「extra characters after close-brace while executing...」
因為在tcl語法中:
if {$value > 10}{
要改成: if {$value > 10} {
也就是if {}空一格{}
也就是說:
{左邊一定要存在一個空格
}右邊一定要存在一個空格

而且不能用

if {...}
{
  // do something
}

必需要用

if {...} {
  // do something
}


[程序(procedures)]:應該就是副程式的意思啦~
宣告
proc name {params1 params2 } {
  body
}
其中name為程序的名稱,params是參數列表,body則是程序的主體
例:

proc sum_proc {a b} {
  global myglobalvar
  puts "The value of the global variable is $myglobalvar"
  return [expr $a + $b]
}


呼叫
name param1 param2
例:

set myglobalvar 79
set sum [sum_proc $num1 $num2]

說明:
這裡的中括號表示是先運算中括號裡面的值,中括號裡面運算出來是2,則再執行set sum 2這一行指令

這個範例主要在說明區域變數(local variable)和全域變數(global variable)的觀念。這樣要特別說明的是當程序中有需要用到程序外已經定義好的變數前,必需先使用global這個保留字做宣告,才能存取程序外已經定義好的變數。

[陣列(arrays)]


set myarray(0) "Zero"
set myarray(1) "One"
set myarray(2) "Two"
for {set i 0} {$i < 3} {incr i 1} {
  puts $myarray($i)
}

這裡的陣列是用小括號來包住引數

ex6_2.tcl

set person_info(name) "Fred Smith"
set person_info(age) "25"
set person_info(occupation) "Plumber"
foreach thing {name age occupation} {
  puts "$thing == $person_info($thing)"
}

foreach thing{name age occupation}就是把它想成
set thing name;
set thing age;
set thing occupation;
分三個階段設定

ex6_3.tcl

set person_info(name) "Fred Smith"
set person_info(age) "25"
set person_info(occupation) "Plumber"
foreach thing [array names person_info] {
  puts "$thing == $person_info($thing)"
}

第一個loop時,$thing為name;而後面的就變成$person_info(name)也就是"Fred Smith"
第二個loop時,$thing為age;而後面的就變成$person_info(age)也就是"25"
第三個loop時,$thing為occupation;而後面的就變成$person_info(occupation)也就是"Plumber"

這個範例跟6.2最大的不同是在foreach這個迴圈,在6.2中,陣列中每個元素存放的位置必須一一列出,才能秀出陣列中每個元素的值,但是在這個範例,使用了[array names 矩陣名稱](注意是中括號喔~),使用的這樣的方法就可以列出person_info中的name、age、occupation,這個在元素很多的時候特別好用。而這裡的thing代表陣列的引數。

[字串特殊函數(strings function)]
ex7_1.tcl

set str "This is a string"
puts "The string is: $str"
puts "The length of the string is: [string length $str]"
puts "The character at index 3 is: [string index $str 3]"
puts "The characters from index 4 through 8 are: [string range $str 4 8]"
puts "The index of the first occurrence of letter \"i\" is: [string first i $str]"

說明:
[string length $str]可以用來顯示字串長度
[string index $str 3]可以用來顯示字串中的第四個字母為何(第一個字母的index為0)
[string range $str 4 8]可以用顯示從字串中第五個到第九個的字母
[string first i $str]可以用來顯示字母i在字串中第一次出現時的index值,也就是第一次出現時在第(index+1)個位置。

[輸出(output)]
ex8_1.tcl

set f [open "/tmp/myfile" "w"]
puts $f "We live in Texas. It's already 110 degrees out here."
puts $f "456"
close $f


執行的結果:
請使用文字編輯器打開/tmp/myfile,其內容為:

We live in Texas. It's already 110 degrees out here.
456

說明:
一般來說,puts若是沒有指定輸出裝置的話,內定的輸出裝置是螢幕,但此範例中有指定輸出的裝置為檔案,所以會把要秀出的字串寫入檔案内。

參考網頁:
TCL 簡介

Firefox - 套件

首先,firefox會那麼受歡迎,http://www.blogger.com/img/blank.gif
其中一個很重要的原因就是它額外的套件很多哩~
可以自動把下一個頁面先載入,並且把資料接在目前這一個頁面中,省去找下一頁的按紐與等待讀取下一頁的時間,非常之好用!尤其是在看網路漫畫的時候,更是好用!

Video DownloadHelper
可以下載flash的檔案~非常方便,特別是可以下載youtube的一堆影片~

Tab Mix Plus
可以設定分頁的功能,在配置上很好用~

若不知道有什麼套件好用,就先參考別人推薦的吧~

firefox add-one top 15

另外,就是firefox中文的套件網站

另外,我寫一下我目前的使用的套件

SuperDrapAndGo
可以直接拉連結來開新分頁,而不用在按右鍵,再按左鍵,選開分頁,很好用啦~

Download Statusbar
再下載檔案時,不會再跑出另一個視窗了~進度會在下面的顯示列上

FlashGot
可以整合一堆下載軟體,不錯~

IE Tab
可以在firefox的視窗中用IE核心瀏覽網頁

IE View
可以選擇聯結由IE視窗開啟,與IE Tab的差別在於,這是真正的IE視窗

Foxmarks Bookmark Synchronizer
可以同步多台電腦firefox上的書籤

Show Image
不用等整張圖片下載完才顯示~

新同文堂
可以翻譯繁體字與簡體字

Adblock Plus
可以拿來擋廣告,非常好用~

另外,也可以參考網友整理出來的東西
但是,我還沒有時間去弄

還有anki大大的推薦
軟件: Firefox 2.0.0.9 (2007102514)
操作系統: WINNT (x86-msvc)

軟件: Firefox 2.0.0.9 (2007102514)
操作系統: WINNT (x86-msvc)



【Firefox】Add-ons list @ Ubuntu 8.04

2008年8月26日 星期二

程式開發工具 - Eclipse

在search相關ns2的資料時,
在這一個網頁推荐可以透過Ecllipse來trace這個ns2的劇本搞錯了啦,他不是用來寫劇本,而是用來寫出劇本產生器啦(不過,若它功能這麼強大,先收著,以後應該有機會用到)。目前是還沒有用過,不過,上網找一下,一堆人推荐這一個程式,可以同時寫java、C++、ns2、PHP,看來我必需要學會習慣它。重點是,它是免費的,而且,它是由Java寫的,可以跨平台。

為什麼寫程式要用IDE(Integrated Development Environment)來寫程式?
用節省資源的vi來寫程式,這種開發方式生產力並不高,若只是開發學習用的小程序則影響不大,但若要開發大型項目時,程序檔案個數眾多,需要用project或solution的方式管理;且debug時breakpoint的加入,單步執行,觀察變量變化等,都需要更可視化的方式才能夠增加生產力;最重要的,由於現在的程序語言皆非常的龐大,又有複雜的函式庫,要程序員熟記所有的程序語法和function名稱,實在很困難,所以語法提示(Intellisense)的功能就非常重要,這些就必須靠IDE來達成。

在ubuntu要安裝實在是太簡單啦~
可以找到有關Eclipse的軟體~

[someone@host ~]$ apt-cache search eclipse


嗯,這兩筆好像是我目前所需要的~
eclipse-cdt - C/C++ Development Tools for Eclipse
eclipse - Extensible Tool Platform and Java IDE

安裝啦~apt會把相關的套件全部抓進來啦~

[someone@host ~]$ sudo apt-get install eclipse eclipse-cdt


耶~好像這樣就完成了耶~那把剛剛下載下來的安裝檔刪掉吧~

[someone@host ~]$ sudo apt-get clean


附帶一提:這是我的第一百篇文章耶~\( ̄□ ̄")/ (\ ̄□) ( \ ̄) \( )/ ( ̄"/) (□ ̄"/) \( ̄□ ̄")/

參考資料:
創新智慧資訊系統實驗室 - ns2教學文件
JavaWorld@TW - Eclipse
維基百科 - Eclipse
構建linux下IDE環境--Eclipse篇
在Eclipse中寫C與C++程式
(原創) 如何在Linux使用Eclipse + CDT開發C/C++程序? (OS) (Linux) (C/C++) (gcc) (g++)
Eclipse 上的 PHP 開發工具 - 安裝篇
用 Eclipse 平台進行 C/C++ 開發

ns2 on Ubuntu - install

因為,之後要改學長姐的行車網路模擬器,
所以,會參考行之有年的ns-2摸擬器。
要學習就要有環境,一開始就先來個安裝吧~

先安裝一下相關套件:

[someone@host ~ ]# sudo apt-get install build-essential
[someone@host ~ ]# sudo apt-get install tcl8.4 tcl8.4-dev tk8.4 tk8.4-dev
[someone@host ~ ]# sduo apt-get install libxmu-dev libxmu-headers


接著到 ns2 的 SourceForge 去下載檔案,這邊我下載到的最新版是 2.33(要用就要用最近滴~)

把ns-2解壓縮到/usr/local資料夾下,因為權限的關係,最好在解壓縮之前,在/usr/local下建立一個資料夾ns-allinone-2.33,並且把它的權限改成你常用的一個普通使用者,避免一直需要root的權限

[someone@host ~ ]# mkdir /usr/local/ns-allinone-2.33
[someone@host ~ ]# tar -zxvf ns-allinone-2.32.tar.gz -C /usr/local
[someone@host ~ ]# cd /usr/local/ns-allinone-2.33
[someone@host ~ ]# ./install


然後,安裝最後會要你在.csbrc或.bashrc中加入一些指令
我是加入在~/.bashrc中
.bashrc

export PATH=$PATH:/usr/local/ns-allinone-2.33/bin:/usr/local/ns-allinone-2.33/tcl8.4.18/unix:/usr/local/ns-allinone-2.33/tk8.4.18/unix
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/ns-allinone-2.33/otcl-1.13:/usr/local/ns-allinone-2.33/lib
export TCL_LIBRARY=$TCL_LIBRARY:/usr/local/ns-allinone-2.33/tcl8.4.18/library


安裝完後,就去驗証啦,應該會跑個半個小時吧~

[someone@host ~]# cd /usr/local/ns-allinone-2.33/ns-2.33/
[someone@host ~]# ./validate


若驗証完後,若沒有問題的話,它會說all pass;但是,沒有看到一個介面出來,可能會覺得魂身不對勁,好~
example2.tcl

#Create a simulator object
set ns [new Simulator]

#Define different colors for data flows
$ns color 1 Blue
$ns color 2 Red

#Open the nam trace file
set nf [open out.nam w]
$ns namtrace-all $nf

#Define a 'finish' procedure
proc finish {} {
global ns nf
$ns flush-trace
#Close the trace file
close $nf
#Execute nam on the trace file
exec nam out.nam &
exit 0
}

#Create four nodes
set n0 [$ns node]
set n1 [$ns node]
set n2 [$ns node]
set n3 [$ns node]

#Create links between the nodes
$ns duplex-link $n0 $n2 1Mb 10ms DropTail
$ns duplex-link $n1 $n2 1Mb 10ms DropTail
$ns duplex-link $n3 $n2 1Mb 10ms SFQ

$ns duplex-link-op $n0 $n2 orient right-down
$ns duplex-link-op $n1 $n2 orient right-up
$ns duplex-link-op $n2 $n3 orient right

#Monitor the queue for the link between node 2 and node 3
$ns duplex-link-op $n2 $n3 queuePos 0.5

#Create a UDP agent and attach it to node n0
set udp0 [new Agent/UDP]
$udp0 set class_ 1
$ns attach-agent $n0 $udp0

# Create a CBR traffic source and attach it to udp0
set cbr0 [new Application/Traffic/CBR]
$cbr0 set packetSize_ 500
$cbr0 set interval_ 0.005
$cbr0 attach-agent $udp0

#Create a UDP agent and attach it to node n1
set udp1 [new Agent/UDP]
$udp1 set class_ 2
$ns attach-agent $n1 $udp1

# Create a CBR traffic source and attach it to udp1
set cbr1 [new Application/Traffic/CBR]
$cbr1 set packetSize_ 500
$cbr1 set interval_ 0.005
$cbr1 attach-agent $udp1

#Create a Null agent (a traffic sink) and attach it to node n3
set null0 [new Agent/Null]
$ns attach-agent $n3 $null0

#Connect the traffic sources with the traffic sink
$ns connect $udp0 $null0
$ns connect $udp1 $null0

#Schedule events for the CBR agents
$ns at 0.5 "$cbr0 start"
$ns at 1.0 "$cbr1 start"
$ns at 4.0 "$cbr1 stop"
$ns at 4.5 "$cbr0 stop"
#Call the finish procedure after 5 seconds of simulation time
$ns at 5.0 "finish"

#Run the simulation
$ns run


就執行它吧~

[someone@host ~]# ns example2.tcl

就會出現以下視窗啦~



參考資料:
阿駕零零壹 © 學習筆記
cygwin + NS2 2.28 安裝成功

2008年8月25日 星期一

QT - region

有空再寫~

以下程式碼節錄至QT - chap 11

void CannonField::moveShot()
{
  QRegion r( shotRect() ); // 建立一個炮彈的region
  timerCount++;

  QRect shotR = shotRect();

  if ( shotR.x() > width() || shotR.y() > height() )
    autoShootTimer->stop();
  else
    r = r.unite( QRegion( shotR ) ); // 取聯集
  repaint( r );
}


首先我們使用QRegion來保留舊的shotRect()。QRegion可以保留任何種類的區域(我想也可以包含圖片吧),並且我們可以用它來簡化繪畫過程。

而之後,我們會針對兩個region來分析是否有碰撞到。

QT - pixmap

有空再寫~

這一個部分我們要說明透過pixmap來避免圖像閃爍。
以下程式碼節錄至QT - chap 10

void CannonField::paintEvent( QPaintEvent *e )
{
  if ( !e->rect().intersects( cannonRect() ) )
    return;

  QRect cr = cannonRect(); // cr為一個方塊,QRect包含(x,y)、長、寬。
  QPixmap pix( cr.size() ); // 建立一個與cr相同大小的pixmap
  pix.fill( this, cr.topLeft() ); // 把pixmap設定放在這一個畫布上,並設定pixmap左上角的位置

  QPainter p( &pix ); // 宣告一個QPainter,其畫圖設備在pix上
  p.setBrush( blue ); // 畫筆是藍色的
  p.setPen( NoPen ); // 圖沒有外框
  p.translate( 0, pix.height() - 1 ); // 轉換座標
  p.drawPie( QRect( -35,-35, 70, 70 ), 0, 90*16 ); // 畫一個扇形
  p.rotate( -ang ); // 以(0,0)點為旋轉點
  p.drawRect( QRect(33, -4, 15, 8) ); // 畫一個矩型
  p.end(); // 畫圖結束,釋放資源

  p.begin( this ); // 把畫布改到this,這裡指的是QWidget
  p.drawPixmap( cr.topLeft(), pix ); // 把剛剛畫好的pixmap畫在this(也就是QWidget)
}


反正,pixmap的精神就是把要畫的圖先畫在pixmap上,最後才把pixmap放到QWidget上。

QT - Paint

重點說明:repaint()、paintEvent()
因為,這個在之後非常重要,所以,在這裡說明一下

void QWidget::repaint () [slots]
把整個畫布以背景重新粉刷過一次,然後,呼叫void QWidget::paintEvent ( QPaintEvent * ),參數的部分就應該是傳整個畫布。
void QWidget::repaint ( const QRect & r, bool erase = TRUE ) [slots]
會在r這一個區域用背景重新粉刷過一次,然後,呼叫void QWidget::paintEvent(QPaintEvent *),參數的部分就是r。
repaint的部分其實就是決定要把目前的畫面哪一個部分要把它由背景填滿,也就是說,它的工作就是清除。

真正畫圖的部分是由QPaint去實作的,而我們通常把QPaint的宣告放在paintEvent中,因為,當我們呼叫repaint(const QRect &r,bool erase = TRUE)時,程式會透過它呼誓paintEvent(),並把r當參數傳給paintEvent(),這個時候,我們就可以在paintEvent中寫出畫圖的程式。

以下是畫圖的例子:

QPainter p( pd ); // 決定要在哪一個設備上畫圖
p.setBrush( blue ); // 設定畫筆為藍色
p.setPen( NoPen ); // 設定沒有邊框
p.drawEllipse(0,0,10,10); // 畫一個10*10的橢圓,剛好就是一個直徑為10的圓啦~


下面再一個例子:

void CannonField::paintEvent( QPaintEvent * )
{
  QString s = "Angle = " + QString::number( ang );
  QPainter p( this );
  p.drawText( 200, 200, s );
}


void CannonField::paintEvent( QPaintEvent * )
{
  QString s = "Angle = " + QString::number( ang );
  QPainter p;
  p.begin( this );
  p.drawText( 200, 200, s );
  p.end();
}

上面兩個程式碼的義意是一樣的。

begin():開始繪製
end():結束繪製。繪製時使用的任何資源都被釋放。注意雖然你幾乎不需要調用end(),建構函數將會執行它,但是至少還有一種情況需要它,就是雙重緩衝(就是先把要畫的先畫在pixmap再畫到qpainter)。

QPainter p( myPixmap, this )
// ...
p.end(); // 停止在myPixmap上的繪製
p.begin( this );
p.drawPixmap( myPixmap );


這是我們第一次試圖寫一個繪畫事件處理程序。
這個事件參數包含一個繪畫事件的描述。
QPaintEvent包含一個必須被刷新的視窗元件的區域。
現在,我們比較懶惰,並且只是畫每一件事。

我們的程式碼在一個固定位置顯示窗口部件的角度值。
首先我們創建一個含有一些文本和角度值的QString,
然後我們創建一個操作這個窗口部件的QPainter並使用它來畫這個字符串。
我們一會兒會回到QPainter,它可以做很多事。

repaint
void QWidget::repaint ( int x, int y, int w, int h, bool erase = TRUE ) [slots]
通過立即調用paintEvent()來直接重新繪製視窗元件,
除非更新是失效的或者窗口部件被隱藏。
如果erase為真,Qt在paintEvent()調用之前擦除區域(x,y,w,h)。
如果w是負數,它被width()-x替換,並且如果h是負數,它被height()-y替換。
如果你需要立即重新繪製,我們建議使用repaint(),比如在動畫期間。在絕大多數情況下,update()更好,因為它允許Qt來優化速度並且防止閃爍。
警告:如果你在一個函數中調用repaint(),而它自己又被paintEvent()調用,你也許會看到無線循環。update()函數從來不會產生循環。


在一開始的時候,就會執行一次paintEvent

2008年8月24日 星期日

在某一個條件下才去判斷另一個條件

今天寫程式時,遇到一個情況。

if (情況一)
{
  天兵吸煙;
}
else if (情況二)
{
  天兵喝酒;
}
else if (情況三)
{
  天兵睡覺;
}

案例:
現在情況變了,只有當情況四發生時,我才會去分析情況一
情況四沒有發生時,我不會去分析情況一,而直接分析情況二情況三的分析。如何做最少的改變完成要求的程式?

噹噹~
我想到一個方式,可能沒有什麼吧~但是,我還是要記錄下來~

if (情況四 && 情況一) // 只有當情況四符合時,才去判斷情況一
{
  天兵吸煙;
}
else if (情況二)
{
  天兵喝酒;
}
else if (情況三)
{
  天兵睡覺;
}

vim - 常用指令

先去跑步游泳啦~等一下再來寫~

:[range]s/pattern/string/[c,e,g,i]
range 指的是範圍
% 是目前編輯的文章,# 是前一次編輯的文章。
pattern 就是要被替換掉的字串,可以用 regexp 來表示。
string 將 pattern 由 string 所取代。
c confirm,每次替換前會詢問。
e 不顯示 error。
g globe,不詢問,整行替換。
i ignore 不分大小寫。

:n1,n2s/word1/word2/gn1 與 n2 為數字。在第 n1 與 n2 行之間尋找 word1 這個字串,並將該字串取代為 word2 !
例:在 100 到 200 行之間搜尋 vbird 並取代為 VBIRD 則:『:100,200s/vbird/VBIRD/g』。

:1,$s/word1/word2/g從第一行到最後一行尋找 word1 字串,並將該字串取代為 word2 !

:1,$s/word1/word2/gc從第一行到最後一行尋找 word1 字串,並將該字串取代為 word2 !且在取代前顯示提示字元給使用者確認 (confirm) 是否需要取代!

:%s/log.*/log/g收尋目前文件中所有的內容,把log.*取代為log,其中我認為%指的就是目前文件的所有內容

:%!sort -u對目前文件中所有的內容拿來執行sort -u這一個指令,我個人認為%指的就是目前文件的所有內容,而!後面就可以接shell的指令

:!sort -u若上面的指令不加%的話,則不會把指令的結果整個覆蓋在目前的這一個文件中

[補充 2009/01/05]
vi (or vim)是 Unix-like 作業系統下最常用的文字編輯器,操作上跟一般編輯器(如gedit)不同。
以下是基本操作方法:
輸入:a、i、o

到第一行:gg
到最後一行:G
到某一行:xxG
到行首:0
到行末:$

複製:yy
貼上:p
復原:u
把剛剛回復的動作再取消:ctrl-r

刪一個字:x
刪整行:dd

[vim 的環境設定參數]
顯示行數: :set nu
是否自動縮排: :set autoindent
設定按一次tab跳8個空格: :set tabstop=8
使得貼文字時,不會出現整個排版錯誤::set paste
設定用明顯顏色標示要找的keyword: :set hlsearch
設定右下角有狀態列: :set ruler
可以利用倒退鍵 (backspace) 來刪除任意字元。當 backspace 為 2 時,就是可以刪除任意值;0 或 1 時,僅可刪除剛剛輸入的字元, 而無法刪除原本就已經存在的文字了!: :set backspace=2
依副檔名來決定特殊符號的顏色: :syntax on
是否要顯示--INSERT-- 之類的字眼在左下角的狀態列: :set showmode
字串搜尋不區分大小寫: :set ignorecase

vi 的搜尋:/、再次搜尋:n
到 shell::sh(在 shell 中回到 vi:exit

水平分割文字編輯視窗: :split filename
若有指定「檔案名稱」,則新視窗會開啟該檔案; 若沒有指定,則新視窗仍會開啟原檔案。
另外,在編輯視窗中可以利用 ctrl+w 配合方向鍵跳躍選取所要編輯的視窗,
若想要關閉視窗,則在欲關閉視窗裡的命令模式下,
打入離開指令,如: :wq 即可關閉該視窗。

垂直分割文字編輯視窗: :vsplit filename
若有指定「檔案名稱」,則新視窗會開啟該檔案; 若沒有指定,則新視窗仍會開啟原檔案。
另外,在編輯視窗中可以利用 ctrl+w 配合方向鍵跳躍選取所要編輯的視窗,
若想要關閉視窗,則在欲關閉視窗裡的命令模式下,
打入離開指令,如: :wq 即可關閉該視窗。

儲存::w
離開::q
儲存兼離開::wqshift+zz
強制離開(不儲存)::q!
設定儲存的檔名: :w filename

另外,加入vim的圖解鍵盤指令


[2009.03.10 補充]
Q: 如何透過指令輸入連續輸入
input int[0]
input int[1]
input int[2]
input int[3]
A:
:for i in range(0,3) | put ='input int[' . i . ']' | endfor
語法就是script的語法,而我猜那一個 | 是應該就是有一點像是大括號的意思,把要實作的與for語法區隔開來。而,中間的小數點「.」是表示連接前後變數與字串的作用

[2009.10.18 補充]
Q: 如何同時註解掉多行程式碼
A: 在normal mode按crtl+v進入選取模式,選取要mark的行數,如下圖

再按I,在最前面加入「// 」,再Esc,可以以出現你要的結果了!

Q: 如何記錄上次編輯的時候編輯到哪裡了?
A: 在開啟新的檔案的時候,在normal mode先按「`」再按「"

Q: 如何使用vim的語法,去尋找第一個不是"123456"的行
A: vim 的否定語法是 \@!
使用搜尋則是 /^\(.*123456.*\)\@!/^\(\(.*123456.*\)\@!\).*

Q: 在寫程式的時候,常會用到大括號之類的,當我在其中一個符號上時,如何知道其相對應的符號是在哪裡?
A: 在normal mode中,把指標移到其中一個符號上,再按%,就可以跳到其相對應的符號上了

Q: 在windows下寫的純文字檔會在每一行的最後,會產生一個^M換行控制碼,那麼要如何把它移掉哩?
A: 是利用字串取代:
:%s/\r//g

Q: 如何利用vim內建的功能去計算每一個字串(例:int)出現的次數
A: :%s/int//gn

Q: 已經開啟一個檔案之後,如何透過tab開啟另一個檔案
A: :tabedit file.name
相關指令: :tabprev:tabnext:tabmove < index>:tabnext < index>

[2009.12.08 補充]
K
函式查詢
若您在 VIM 中撰寫 C/C++ 程式,可以在 C/C++ 標準函式厙提供的函式名字上按「K」,便可以呼叫出 man page 查詢該函式的用法

=
自動程式縮排對齊
若您在 VIM 中撰寫 C/C++ 程式,可以利用「gg」指令將游標移到視窗最上方、利用「v」切換到選取模式、再用「G」將游標移到檔案尾端 (即達到全選的功能),最後按「=」,VIM 便會幫你的程式做自動對齊

[2009.12.19 補充]
"ayy
將本行文字複製到 a 緩衝區。
a 可為 26 個英文字母中的一個,如果是小寫的話,原先的內容會被清掉,如果是大寫的話是 append 的作用,會把內容附加到原先內容之後。"是 Enter 鍵隔壁的那一個同上符號(ditto marks),當然是要和 shift 鍵同時按的。

"ap
將 a 緩衝區的內容貼上。

問題來了!忘記誰是誰的時候怎麼辦?
:reg
(冒號命令)就會列出所有 registers 的代號及內容。
咦!怎麼還有數目字、特殊符號的緩衝區,原來您剛剛刪除(複製)的內容就預設放在 " 這個緩衝區,然後依序是 0,1,2,...9。也就是說您按 p 不加什麼的話,是取出 " 緩衝區的內容。% 指的是目前編輯的檔案,# 指的是前一次編輯的檔案。

.
重複前次的編輯動作,相當好用的一個指令!

*
尋找游標所在處之 word(要完全符合)。

#
同上,但 * 是向前(下)找,# 則是向後(上)找。

g*
* ,但部份符合即可。

g#
# ,但部份符合即可。n, N 之繼續尋找鍵仍適用。

書籤功能
mx x 代表 26 個小寫英文字母,這樣游標所在處就會被 mark。
`x 回到書籤原設定位置。` 是 backward quote,就是 Tab 鍵上面那一個。
'x 回到書籤設定行行首。' 是 forward quote,是 Enter 鍵隔壁那一個。
Vim 對於書籤的擴充功能
小寫英文字母
只作用於單一檔案內。
大寫英文字母
可作用於各檔案間。例如 mA 會在 viminfo 中紀錄下這個檔案及位置,結束 vim,然後再啟動 vim,按 'A 就會回到當初做標記的那個檔案及所在位置(vim 會自動開啟做有 A 標記的檔案)。別懷疑,請自行馬上做個實驗就知道啦!:-)
阿拉伯數目字
可作用於前次編輯的十個檔案。數目字的用法比較特殊,'0 是回到前一次編輯檔案中離開前的最後位置,'1 則是回到前二次編輯檔案的最後位置,依此類推。您不必使用 m 來標示,vim 會自動記憶。很玄吧!其實這是 viminfo 的功能,您要認真追究的話,請 :h viminfo-file-marks。viminfo 關掉,就沒這個功能了!所謂前次指的是前次啟動的 vim。不管是哪一種的書籤,到達 mark 處(或檔案),想返回原來的位置(或檔案),可以按 Ctrl + O。
:marks
得知目前所有書籤的列表。

標示指令
v 小寫 v,這是屬於字元標示(character visual),按下 v 後您就可以移動游標,游標走過的地方就會標示起來。再按一次 v 或按 Esc 鍵就會結束 v-mode。
V 大寫 V,這是行標示(line visual),按下 V 後會整行標示起來(包括行首前空白的部分),您移動上下鍵,會標示多行。再按一次 V 或 Esc 鍵就會結束 v-mode。
Ctrl+v 這是區塊標示(blockwise visual),可縱向標示矩形區域。再按一次 Ctrl+v 就會結束 v-mode。結束 v-mode 的方式亦可使用 Esc 鍵,或統一使用 Ctrl+c。Windows 系統下 Ctrl+v 是複製鍵,可以使用 Ctrl+Q 來替代。
d 刪除標示區內容。
y 複製標示區內容。
c 替換標示區內容。
gq 重排標示區內容。ㄟ…… 是要先標示好才按的。"ay 還能不能用呢?當然可以,這樣就會把標示區內容存於 a 緩衝區中。可以用 "ap 來貼上。
Shift+> 標示區內容向右移一個 Tab。
Shift+< 標示區內容向左移一個 Tab。

視窗操作
凡是視窗操作的按鍵都是由 Ctrl+w 來起頭的,w 就是 window 的意思。

Ctrl+w s 即 :sp(lit),會開一新視窗,且原檔分屬兩個視窗。
Ctrl+w f 開一新視窗,並編輯游標所在處之 word 為檔名的檔案。
Ctrl+w q 即 :q 結束分割出來的視窗。
Ctrl+w o 即 :only! 使游標所在之視窗,成為目前唯一顯示的視窗其它視窗會隱藏起來。
Ctrl+w j 移至下視窗。
Ctrl+w k 移至上視窗。還記得 hjkl 的按鍵移動方式嗎?
:sp 檔名 開另一新視窗來編輯檔案。

shell 命令
:!外部指令 執行外部指令。當然您的指令要在 $PATH 環境變數內。
:!! 執行前一次執行之外部指令。在這裡的 ! 可不是強迫中止喔!
@: 這是 Vim 的一個很特殊的指令,可以重複前一次的冒號命令。
:sh(ell) 執行 shell。使用 exit 回到 vim。

另外,在此補充一下補全的功能。不是只有 Tab 鍵的補全功能喔!也可以使用上下方向鍵,叫出歷史指令,叫出歷史指令可用於冒號命令及尋找命令(/)。例如,您前已下了 :!ps aux 這個指令,您可以按 : 後就直接按向上方向鍵。別忘了!尋找指令也是可以這樣用喔!

:r !commond 這個就妙了!會在游標所在處次一行插入外部指令 commond 執行後的輸出內容。
例如 :r !date 就會插入日期時間。這在 elvis 是會插入在游標所在處那一行。
:n,mw !commond 以 n 至 m 行內之資料,當做外部指令 commond 的 input。這算是相當高級的用法了,初學者大概還用不上,不過印象中留有一個這樣的功能,以後總是會用得上的。
K 大寫 K 會顯示游標所在處之 word 的 man page 系統線上使用手冊。

如何得知目前的設定

:set:se 會顯示所有經過修改的部份,就是和預設值不一樣的部份。
:set all 顯示目前所有設定值內容。
:scriptnames 顯示各種設定檔的所在路徑及其檔名。
:set option? 顯示 option 這設定的目前值。
:option 直接線上設定,有些設定需加 = 後加上設定值內容。
:set nooption 取消該設定。:set 後面是可以多重設定的。例如
:set autoindent noconfirm autowrite,這樣三種設定就會同時重設。

您當然可以改設定檔來改變設定值。在 Vim 也可以使用 :opt[ion] 來直接線上設定,會列出目前的設定,在 set 這個字上按 Enter 即可改變設定,或就直接修改其值亦可,改完後按 :q 就可以了。在簡短說明處按 Enter 則會叫出該部份的說明檔給您參考,您說方不方便?改好後

:mk[exrc] 則會寫入 ~/.exrc 檔
:mkv[imrc] 則會寫入 ~/.vimrc 檔

^M是按 Ctrl+v 後不放再按M,^M 是特殊字元,是一個字元,而不是兩個字元

[2010.01.01 補充]
在收尋的時候,使用\<pattern\>,也就是括號把要找的字串括起來,意思是說,的的確確是找所要的那個字。換句話說,如果文件中只有一個main,但是,若是\<ma\>去尋找的話,那就會找不到。在使用*,則會自動在收尋的字串中,分別在字串的前後加入\<\>;若只是想要找部分相同的字串的話,可以使用g*,就可以找到部分相同的字串。

[2010.01.31 補充]
Q: 如何刪掉由目前這一行刪到第15行
A: 在normal mode的下輸入d15gg
A: 在normal mode的下輸入ma → 跳到要刪除的行號 → d'a

Q: 如何刪掉第6行到第15行
A: :6,15d

Q: 刪除{}夾住的資料
A: 在normal mode的下輸入di{

Q: 刪除()夾住的資料
A: 在normal mode的下輸入di(

[2011.06.27 補充]
Q: 如何重覆貼內容2000次到目前的檔案裡面
A1: 把general buffer的內容重覆貼2000次到檔案最後
:for i in range(0,1999) | put = getreg () | endfor
getreg()可以取得暫存器的值
getreg()預設取得general buffer的內容,而用yy就是存到general buffer內
getreg('*')取得剪貼簿的內容
getreg('/')取得上一次收尋的內容
A1:
在normal mode做以下動作
1. yy
2. 2000p
A2: 把剪貼簿的內容,重覆貼2000次到目前的檔案最後
:for i in range(0,1999) | put = @* | endfor

[2011.09.26 補充]
Q: 把第3到10行的資料,剪下並且貼到22行
A: :3,10move 22

[2014.07.09 補充]
尋找abc字串,並且取代成客製化字串
:let i=1 | g/abc/s//\='xyz_' . i/ | let i=i+1

參考資料:
鳥哥
vi / vim 圖解鍵盤指令
vi 中一些常用的使令
大家來學 Vim 一個歷久彌新的編輯器
基本 VIM 操作指令
vim label of Rickey's pets
VIM Regular Expressions
vihelp
Append general buffer to the end of every line in VI
Making a list of numbers