Gnutellasim是美国乔治亚理工学院的一位学生写的模拟p2p应用的软件,其运行在ns2上,目前模拟的协议为Gnutella,可以模仿写自己的协议,有一定参考价值,它可以运行在ns2和分布式ns2上,对于初学者可以在ns2上先理解它的原理,如果的确需要大规模仿真,可以在pdns上实验。下面是手工安装的方法,ns2.27、2.28都可以,估计更好版本也可以,如果报错也多为类型不匹配,可以用强制转换通过编译,我觉得使用这个软件的焦点在于理解它的原理,然后写自己的算法。 下载gnusrc2.26.tar.gz(源程序)和revised2.26.tar.gz(里面有修改ns Makefile和ns几个.cc,.h文件的方法)C9hLinux联盟 cd ~/ns-allinone-2.26/ns-2.26C9hLinux联盟 tar xvfz gnusrc2.26.tgz;或者解压在其他目录,拷贝其中gnutella目录到ns-2.26中,拷贝tcl/lib/ns-gnutella.tcl到ns-2.26/tcl/lib中;我选择后面一种方式C9hLinux联盟 修改Makefile如下;如果是linux,可以修改Makefiel.in,然后./configure产生MakefileC9hLinux联盟 --->增加下面代码到OBJ_GEN宏上方C9hLinux联盟 # Qi additions for Gnutella SimulationC9hLinux联盟 OBJ_GNUSIM = \C9hLinux联盟 gnutella/tcp-advw.o \C9hLinux联盟 gnutella/tcp-sock.o \C9hLinux联盟 gnutella/nssocket.o \C9hLinux联盟 gnutella/nssocket_prio.o \C9hLinux联盟 gnutella/peer_agent.oC9hLinux联盟 --->添加定义$(OBJ_GNUSIM)到宏OBJ中C9hLinux联盟 --->修改all: $(NS) $(BUILD_NSE) all-recursive为all: $(NS)C9hLinux联盟 --->在clean:下方增加C9hLinux联盟 #Qi add clean target for cleaning GnutellaSim related objectsC9hLinux联盟 gnusimclean:C9hLinux联盟 $(RM) $(OBJ_GNUSIM)C9hLinux联盟 下面修改ns的文件C9hLinux联盟 --->common/agent.cc文件:C9hLinux联盟 改变389行附近的函数void Agent::connect(nsaddr_t /*dst*/)为:C9hLinux联盟 void Agent::connect(nsaddr_t dst)C9hLinux联盟 {C9hLinux联盟 //Qi changes for GnutellaSimC9hLinux联盟 dst_.addr_ = dst;C9hLinux联盟 }C9hLinux联盟 在函数void Agent::recv(Packet* p, Handler*)上方(430行左右)增加代码:C9hLinux联盟 //Qi additions for GnutellaSimC9hLinux联盟 void Agent::sendto(int nbytes, const char flags[], nsaddr_t dst, nsaddr_t port)C9hLinux联盟 {C9hLinux联盟 dst_.addr_ = dst;C9hLinux联盟 dst_.port_ = port;C9hLinux联盟 sendmsg(nbytes, flags);C9hLinux联盟 }C9hLinux联盟 --->common/agent.h文件:C9hLinux联盟 在76行附近增加(void recv(Packet*, Handler*);下方):C9hLinux联盟 //QiC9hLinux联盟 virtual void sendto(int nbytes, const char* flags, nsaddr_t dst, nsaddr_t dport);C9hLinux联盟 virtual void connect(ns_addr_t dst) {dst_ = dst; }C9hLinux联盟 --->tcp/tcp.h文件:C9hLinux联盟 在56行附近增加(int tcp_flags_;下方):C9hLinux联盟 int advwin_; /* Qi: Receiver Advertised Window */C9hLinux联盟 在78行附近增加(int& last_rtt() { return (last_rtt_); }下方):C9hLinux联盟 int& advwin() {return (advwin_); } //Qi: Receiver Advertised WindowC9hLinux联盟 将215行附近的void newack(Packet*);改为:C9hLinux联盟 virtual void newack(Packet*); /* Qi: changed to "virtual" */C9hLinux联盟 --->tcp/tcp-full.h文件:C9hLinux联盟 将212行附近的int foutput(int seqno, int reason = 0); // output 1 packet改为:C9hLinux联盟 virtual int foutput(int seqno, int reason = 0); // (Qi: change to virtual) output 1 packetC9hLinux联盟 --->tcl/lib/ns-default.tcl文件:C9hLinux联盟 修改722行的Agent/TCP set tcpip_base_hdr_size_ 40为:C9hLinux联盟 # Qi add receiver advertised window field to TCP header (40 + 4 = 44)C9hLinux联盟 Agent/TCP set tcpip_base_hdr_size_ 44C9hLinux联盟 --->tcl/lib/ns-lib.tcl文件:C9hLinux联盟 在210行附近增加(# PGM下方):C9hLinux联盟 # Qi: GnutellaSimC9hLinux联盟 source ns-gnutella.tclC9hLinux联盟 ---如果编译报错,我修改了一处,不知道会不会有问题(redhat linux9中不用修改!cygwin要修改):C9hLinux联盟 gnutella/nssocket.cc的49,50两行;后面一个参数给个强制转换(unsigned int *)C9hLinux联盟 make ns - 编译成功的话就应该成功了C9hLinux联盟
|