一、简介

ns2是常用的网络仿真软件,目前最常用的版本是 ns-2.34(发布于2009年)和 ns-2.35(发布于2011年)。ns2编译安装过程较为繁琐,尤其是需要手工解决一些因编译环境变化而带来的语法错误,对新手很不友好。

本文描述了编译运行 ns-2.35 的全过程,并提供了解决编译错误的补丁。

所使用环境为:

  • 虚拟机:VMware® Workstation 15 Pro
  • 宿主机系统:Windows 10 专业版
  • 虚拟机系统:ubuntu-16.04.6-desktop-amd64
  • 软件版本:ns-allinone-2.35

二、安装依赖项

首先需要更新系统:

sudo apt-get update #更新源列表
sudo apt-get upgrade #更新已经安装的包
sudo apt-get dist-upgrade #更新软件,升级系统

安装 ns2 需要的几个包(建议使用国内源):

sudo apt-get install build-essential
sudo apt-get install tcl8.5 tcl8.5-dev tk8.5 tk8.5-dev #for tcl and tk
sudo apt-get install libxmu-dev libxmu-headers #for nam

三、安装 ns-2.3.5

下载安装包,并复制到需要安装的目录,官网下载地址:https://www.isi.edu/nsnam/ns/ns-build.html#allinone,或点击 链接 直接下载。

解压缩下载后的压缩包

tar -xvf ns-allinone-2.35.tar.gz
cd ns-allinone-2.35

ns-2.35 发布于2011年11月,在新版本的编译环境下同样需要打补丁才能成功编译。

获取补丁文件:

wget https://raw.githubusercontent.com/zylan29/ns-expr/master/ns-allinone-2.35-bugfix.patch

如无法获取可创建 ns-allinone-2.35-bugfix.patch 文件,将下面内容粘贴进去保存。

diff -rupN ns-allinone-2.35-orig/nam-1.15/Makefile.in ns-allinone-2.35/nam-1.15/Makefile.in
--- ns-allinone-2.35-orig/nam-1.15/Makefile.in	2011-11-05 01:18:41.000000000 +0800
+++ ns-allinone-2.35/nam-1.15/Makefile.in	2018-02-23 14:40:44.335097197 +0800
@@ -45,7 +45,7 @@ datarootdir = @datarootdir@
 
 CC = @CC@
 CPP = @CXX@
-CCOPT = @V_CCOPT@
+CCOPT = @V_CCOPT@ -funsigned-char
 MKDEP = ./conf/mkdep
 # Have to be the same as that defined in conf/makefile.win
 TCL2C = @V_TCL2CPP@
diff -rupN ns-allinone-2.35-orig/nam-1.15/makefile.vc ns-allinone-2.35/nam-1.15/makefile.vc
--- ns-allinone-2.35-orig/nam-1.15/makefile.vc	2002-04-16 05:58:28.000000000 +0800
+++ ns-allinone-2.35/nam-1.15/makefile.vc	2018-02-23 14:40:33.763254509 +0800
@@ -43,7 +43,7 @@ MANDEST = @mandir@
 
 CC = @CC@
 CPP = @CXX@
-CCOPT = @V_CCOPT@
+CCOPT = @V_CCOPT@ -funsigned-char
 MKDEP = ./conf/mkdep
 # Have to be the same as that defined in conf/makefile.win
 TCL2C = @V_TCL2CPP@
diff -rupN ns-allinone-2.35-orig/ns-2.35/linkstate/ls.h ns-allinone-2.35/ns-2.35/linkstate/ls.h
--- ns-allinone-2.35-orig/ns-2.35/linkstate/ls.h	2010-03-08 13:54:51.000000000 +0800
+++ ns-allinone-2.35/ns-2.35/linkstate/ls.h	2018-02-23 12:48:58.613528097 +0800
@@ -134,7 +134,7 @@ public:
 		return ib.second ? ib.first : baseMap::end();
 	}
 
-	void eraseAll() { erase(baseMap::begin(), baseMap::end()); }
+	void eraseAll() { this->erase(baseMap::begin(), baseMap::end()); }
 	T* findPtr(Key key) {
 		iterator it = baseMap::find(key);
 		return (it == baseMap::end()) ? (T *)NULL : &((*it).second);
diff -rupN ns-allinone-2.35-orig/ns-2.35/Makefile.in ns-allinone-2.35/ns-2.35/Makefile.in
--- ns-allinone-2.35-orig/ns-2.35/Makefile.in	2011-10-24 00:29:54.000000000 +0800
+++ ns-allinone-2.35/ns-2.35/Makefile.in	2018-02-23 14:40:00.823857387 +0800
@@ -53,7 +53,7 @@ PERL	= @PERL@
 # for diffusion
 #DIFF_INCLUDES = "./diffusion3/main ./diffusion3/lib ./diffusion3/nr ./diffusion3/ns"
 
-CCOPT	= @V_CCOPT@ 
+CCOPT	= @V_CCOPT@ -funsigned-char
 STATIC	= @V_STATIC@
 #LDFLAGS	= $(STATIC)
 LDFLAGS	= @LDFLAGS@ 
diff -rupN ns-allinone-2.35-orig/ns-2.35/makefile.vc ns-allinone-2.35/ns-2.35/makefile.vc
--- ns-allinone-2.35-orig/ns-2.35/makefile.vc	2010-05-10 06:28:41.000000000 +0800
+++ ns-allinone-2.35/ns-2.35/makefile.vc	2018-02-23 14:40:18.364670289 +0800
@@ -53,7 +53,7 @@ PERL	= @PERL@
 # for diffusion
 #DIFF_INCLUDES = "./diffusion3/main ./diffusion3/lib ./diffusion3/nr ./diffusion3/ns"
 
-CCOPT	= @V_CCOPT@ 
+CCOPT	= @V_CCOPT@ -funsigned-char
 STATIC	= @V_STATIC@
 #LDFLAGS	= $(STATIC)
 LDFLAGS	= @LDFLAGS@ 
diff -rupN ns-allinone-2.35-orig/ns-2.35/mdart/mdart_adp.cc ns-allinone-2.35/ns-2.35/mdart/mdart_adp.cc
--- ns-allinone-2.35-orig/ns-2.35/mdart/mdart_adp.cc	2010-05-10 06:28:41.000000000 +0800
+++ ns-allinone-2.35/ns-2.35/mdart/mdart_adp.cc	2018-02-23 12:45:26.800160252 +0800
@@ -105,7 +105,7 @@ void ADP::sendDarq(nsaddr_t reqId, int r
 #ifdef DEBUG_ADP
 	fprintf(stdout, "%.9f\tADP::sendDarq(%d)\t\t\tin node %d\twith address %s\n", CURRENT_TIME, reqId, mdart_->id_, bitString(mdart_->address_));
 #endif
-	nsaddr_t dstAdd_ = hash(reqId);
+	nsaddr_t dstAdd_ = ::hash(reqId);
 #ifdef DEBUG_ADP
 	fprintf(stdout, "\tsending darq for node %s\n", bitString(dstAdd_));
 #endif
@@ -393,7 +393,7 @@ void ADP::sendDaup() {
 	fprintf(stdout, "%.9f\tMDART::sendDaup()\t\t\t\tin node %d\twith address %s\n", CURRENT_TIME, mdart_->id_, bitString(mdart_->address_));
 //	printDHT();
 #endif
-	nsaddr_t dstAdd_ = hash(mdart_->id_);
+	nsaddr_t dstAdd_ = ::hash(mdart_->id_);
 #ifdef DEBUG_ADP
 	fprintf(stdout, "\tsending daup for node  %s\n", bitString(dstAdd_));
 	mdart_->routingTable_->print();

打补丁:

patch -p1 < ns-allinone-2.35-bugfix.patch

编译 ns-2.3.5 的全部组件:

sudo ./install

安装成功后会显示类似 successfully installed 的字样。

最后修改当前用户环境变量(对应的文件为’/home/用户名’中的.bashrc,并非’/ns-allinone-2.35’底下的空白.bashrc)

vim ~/.bashrc

在文件末尾添加:

export PATH=”$PATH:/home/安装文件夹名/ns-allinone-2.35/bin:/home/安装文件夹名/ns-allinone-2.35/tcl8.5.10/unix:/home/安装文件夹名/ns-allinone-2.35/tk8.5.10/unix”
export LD_LIBRARY_PATH=”$LD_LIBRARY_PATH:/home/安装文件夹名/ns-allinone-2.35/otcl-1.14:/home/安装文件夹名/ns-allinone-2.35/lib”
export TCL_LIBRARY=”$TCL_LIBRARY:/home/安装文件夹名/ns-allinone-2.35/tcl8.5.10/library”

激活修改后的配置:

source ~/.bashrc

输入 ns,出现 %,说明 ns2 安装成功

四、测试

测试 simple.tcl 脚本:

cd ns-allinone-2.35/ns-2.35/tcl/ex/
ns simple.tcl

显示下图则全部安装成功!

img


参考: