今天开始沉下心来好好搞项目,我们小组的任务是完成利用网络
编码技术改进传统TCP
协议,我主要是负责进行ns仿真。今天上午回顾了一下以前进行的工作,下午试验在ns2中植入了一个小协议
Bing(其实就是Ping协议,由于在现有ns源代码中已经有了Ping协议,故改名为Bing协议)。以下是植入的过程:
First Step: 编写bing.h文件
#ifndef ns_bing_h
#define ns_bing_h
#include "agent.h"
#include "tclcl.h"
#include "packet.h"
#include "address.h"
#include "ip.h"
/*
* 定义Bing协议的分组头结构
*/
struct hdr_bing {
char ret; // 用来判断是否发送pktret响应包
double send_time; // 包传送时间
int seq; // sequence number
// Header access methods
static int offset_; // required by PacketHeaderManager // 分组头在整个包头中的偏移量。 疑问:何时确定的这个偏移量的值???
inline static int& offset() { return offset_; }
inline static hdr_bing* access(const Packet* p) {
return (hdr_bing*) p->access(offset_);
}
};
class BingAgent : public Agent {
public:
BingAgent();
int seq; // a send sequence number like in real ping
virtual int command(int argc, const char*const* argv); // 重写父类的command函数,在这里实际就是传送包的函数
virtual void recv(Packet*, Handler*);
};
#endif // ns_ping_h
Second Step: 编写bing.cc文件
#include "bing.h"
#include <iostream>;
/*
* bing协议需要被NS-2所接受并且,可以在OTcl代码中使用,需要定义如下代码:
* 以下代码使得OTcl中的bingHead/Ping类与C++中的hdr_bing绑定在一起,这样定义出的分组头为Bing
*/
int hdr_bing::offset_;
static class BingHeaderClass : public PacketHeaderClass {
public:
BingHeaderClass() : PacketHeaderClass("PacketHeader/Bing",
sizeof(hdr_bing)) {
bind_offset(&hdr_bing::offset_);
}
} class_binghdr;
/*
* 以下代码从TclCL继承一个BingClass类,其构造函数通过调用基类的构造函数TclClass("Agent/Bing")指定其
* 对应的OTcl对象为Agent/Bing,这实际是做了登记工作。
*/
static class BingClass : public TclClass {
public:
BingClass() : TclClass("Agent/Bing") {}
TclObject* create(int, const char*const*) {
return (new BingAgent());
}
} class_bing;
BingAgent::BingAgent() : Agent(PT_BING), seq(0)
{
bind("packetSize_", &size_);
}
int BingAgent::command(int argc, const char*const* argv)
{
if (argc == 2) {
if (strcmp(argv[1], "send") == 0) {
// Create a new packet
Packet* pkt = allocpkt();
// Access the Ping header for the new packet:
hdr_bing* hdr = hdr_bing::access(pkt);
// Set the 'ret' field to 0, so the receiving node
// knows that it has to generate an echo packet
hdr->ret = 0;
hdr->seq = seq++;
// Store the current time in the 'send_time' field
hdr->send_time = Scheduler::instance().clock();
std::cout << Agent::size_ << endl;
// Send the packet
send(pkt, 0);
// return TCL_OK, so the calling function knows that
// the command has been processed
return (TCL_OK);
}
}
// If the command hasn't been processed by PingAgent()::command,
// call the command() function for the base class
return (Agent::command(argc, argv));
}
void BingAgent::recv(Packet* pkt, Handler*)
{
// Access the IP header for the received packet:
hdr_ip* hdrip = hdr_ip::access(pkt);
// Access the Ping header for the received packet:
hdr_bing* hdr = hdr_bing::access(pkt);
// Is the 'ret' field = 0 (i.e. the receiving node is being pinged)?
if (hdr->ret == 0) {
// Send an 'echo'. First save the old packet's send_time
double stime = hdr->send_time;
int rcv_seq = hdr->seq;
// Discard the packet
Packet::free(pkt);
// Create a new packet
Packet* pktret = allocpkt();
// Access the Ping header for the new packet:
hdr_bing* hdrret = hdr_bing::access(pktret);
// Set the 'ret' field to 1, so the receiver won't send
// another echo
hdrret->ret = 1;
// Set the send_time field to the correct value
hdrret->send_time = stime;
// Added by Andrei Gurtov for one-way delay measurement.
hdrret->seq = rcv_seq;
// Send the packet
send(pktret, 0);
} else {
// A packet was received. Use tcl.eval to call the Tcl
// interpreter with the ping results.
// Note: In the Tcl code, a procedure
// 'Agent/Ping recv {from rtt}' has to be defined which
// allows the user to react to the ping result.
char out[100];
// Prepare the output to the Tcl interpreter. Calculate the
// round trip time
sprintf(out, "%s recv %d %3.1f", name(),
hdrip->src_.addr_ >> Address::instance().NodeShift_[1],
(Scheduler::instance().clock()-hdr->send_time) * 1000);
Tcl& tcl = Tcl::instance();
tcl.eval(out);
// Discard the packet
Packet::free(pkt);
}
}
Third Step:
(1) 在lib/ns-packet.tcl中添加包头名字Bing;
(2) 在common/packet.h中新增包类型:PT_BING; 并定义新增包类型的名字name_[PT_BING]= "bing";
(3)在lib/ns-default.tcl中增加定义变量初始值的语句。这里的变量只包括通过bind函数进行OTcl与
C++语言绑定的变量:
Agent/Bing set packetSize_ 64;
Fourth Step:
最后,修改ns/Makefile文件,并编译。
Bing协议植入过程就此结束!