上一次是写添加没有新包头的协议,这次包含包头信息
同上,这次协议的例子是模拟节点a给节点b传输一个数据包,节点b收到返回一个数据包。
a收到后再次发送,b收到后再次返回。完毕。
相当于四次握手
协议名字叫 xdw_send_msg
=================================
开始,前提准备见上一篇
=================================
第1步:
在/usr/local/ns2/ns-allinone-2.34/ns-2.34/xdw下添加xdw_send_msg.h和xdw_send_msg.cc两个文件
第2步:
xdw_send_msg.h内容如下:
#ifndef xdw_send_h
#define xdw_send_h
#include "agent.h"
#include "tclcl.h"
#include "packet.h"
#include "address.h"
#include "ip.h"
struct hdr_xdw_send //包头数据结构
{
int times; //自己定义的,下面的都是必须的
static int offset_;
inline static int& offset()
{
return offset_;
}
//访问包的内容,传入父类指针,转化为子类
inline static hdr_xdw_send * access(const Packet * p)
{
return (hdr_xdw_send*) p->access(offset_);
}
};
class xdw_send_agent : public Agent
{
public :
xdw_send_agent();
void get_para();
virtual void recv(Packet *, Handler *);
protected:
int command(int argc, const char*const*argv);
void send_msg(int seq);
};
#endif
第3步:
xdw_send_msg.cc内容如下:
#include "xdw_send_msg.h"
#define MYNODE Address::instance().get_nodeaddr(addr()) //本节点地址
int hdr_xdw_send::offset_;
static class xdw_sendHeaderClass : public PacketHeaderClass
{
public:
xdw_sendHeaderClass() : PacketHeaderClass("PacketHeader/XDWSend",sizeof(hdr_xdw_send))
{
bind_offset(&hdr_xdw_send::offset_);
}
} class_xdw_sendshdr;
static class XDWSendClass:public TclClass
{
public:
XDWSendClass():TclClass("Agent/XDWSend"){};
TclObject *create(int,const char* const*)
{
return (new xdw_send_agent());
}
}class_my_agent;
xdw_send_agent::xdw_send_agent():Agent()
{
}
void xdw_send_agent::send_msg(int seq)
{
Packet* pkt = allocpkt();
hdr_xdw_send* hdrpacket = hdr_xdw_send::access(pkt);
hdrpacket->times=seq;
printf("=>At %lf node %d is sending a packet.seq=%d./n",NOW,MYNODE,seq);
send(pkt, 0);
}
int xdw_send_agent::command(int argc, const char*const* argv)
{
if( argc == 2 )
{
if( !strcmp (argv[1],"send_msg"))
{
send_msg(1);
return (TCL_OK);
}
}
return (Agent::command(argc, argv));
}
void xdw_send_agent::recv(Packet *p, Handler *)
{
struct hdr_ip *hdrip = (hdr_ip*)hdr_ip::access(p);
struct hdr_xdw_send *hdrxdwsend = (hdr_xdw_send*)hdr_xdw_send::access(p);
printf("=>At %lf node %d receive the packet from node %d /n",NOW,MYNODE,hdrip->saddr());
if(hdrxdwsend->times==1||hdrxdwsend->times==3)
{
printf("now node %d is sending the ack packet/n",MYNODE);
send_msg(hdrxdwsend->times+1);
}
else if(hdrxdwsend->times==2)
{
printf("node 0 send again/n");
send_msg(hdrxdwsend->times+1);
}
else
{
printf("node 0 stop the send process./n");
}
Packet::free(p);
}
第4步:
测试tcl脚本xdw_send_msg.tcl内容如下
set ns [new Simulator]
$ns color 1 Blue
$ns color 2 Red
set nf [open xdw_send_msg.nam w]
set tf [open xdw_send_msg.tr w]
$ns namtrace-all $nf
$ns trace-all $tf
proc finish {} {
global ns nf
$ns flush-trace
close $nf
exec nam xdw_send_msg.nam &
exit 0
}
set n0 [$ns node]
set n1 [$ns node]
$ns duplex-link $n0 $n1 1Mb 10ms DropTail
set test1 [new Agent/XDWSend]
$ns attach-agent $n0 $test1
set null [new Agent/XDWSend]
$ns attach-agent $n1 $null
$ns connect $test1 $null
$ns at 0.1 "$test1 send_msg"
$ns at 0.3 "finish"
$ns run
第5步:
修改/usr/local/ns2/ns-allinone-2.34/ns-2.34/common下packet.h文件
在typedef unsigned int packet_t;
static const packet_t PT_TCP = 0;
....
static packet_t PT_NTYPE = 65; // This MUST be the LAST one
之间添加
static const packet_t PT_XDWSEND = 64; //序号排到什么就是什么
在static void initName()
中添加
name_[PT_XDWSEND] = "XDWSend";
第6步:
修改/usr/local/ns2/ns-allinone-2.34/ns-2.34下的makefile文件
在OBJ_CC = /下面添加xdw/xdw_send_msg.o /
第7步:
终端进入/usr/local/ns2/ns-allinone-2.34/ns-2.34/ 输入make重新编译
第8步:
终端进入/usr/local/ns2/ns-allinone-2.34/ns-2.34/xdw 输入ns xdw_send_msg.tcl
结果
:
=>At 0.100000 node 0 is sending a packet.seq=1.
=>At 0.110000 node 1 receive the packet from node 0
now node 1 is sending the ack packet
=>At 0.110000 node 1 is sending a packet.seq=2.
=>At 0.120000 node 0 receive the packet from node 1
node 0 send again
=>At 0.120000 node 0 is sending a packet.seq=3.
=>At 0.130000 node 1 receive the packet from node 0
now node 1 is sending the ack packet
=>At 0.130000 node 1 is sending a packet.seq=4.
=>At 0.140000 node 0 receive the packet from node 1
node 0 stop the send process.
转自http://hi.baidu.com/xdwa/blog/item/f2728c225b64a6fed7cae2fc.html
PS:
make编译错误,类似:“in constructor Agent::Agent()没有匹配的调用函数,备选Agent(packet_t)或者Agent(const Agent&)”
解决方法:将“xdw_send_agent::xdw_send_agent():Agent()
{
}
”
改为“xdw_send_agent::xdw_send_agent():Agent(PT_XDWSEND) //加上参数
{
}
”