NS2相关学习——完成一个新协议(2)
生活随笔
收集整理的這篇文章主要介紹了
NS2相关学习——完成一个新协议(2)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
在上節中,我們把教程要求的3.1-3.3過了一遍,這一次回到正途上來。看看到底是怎么完成一個新的協議的。
本節中的代碼實現了一些簡單的“ping”協議(靈感來自“ns注釋和文檔”(現在更名為ns手冊)的第9.6章中的“ping請求者”,但相當不同)。 一個節點將能夠發送一個數據包到另一個節點,它將立即返回,以便可以計算往返時間。
1、頭文件
在新的頭文件'ping.h'中,首先必須聲明將攜帶相關數據的新的Ping包頭的數據結構。
以下代碼段將類“PingAgent”聲明為類“Agent”的子類。
?int off_ping_將用于訪問數據包的ping頭。 請注意,對于具有本地對象范圍的變量通常使用尾隨“_”。
2、c++代碼
首先必須定義C ++代碼和Tcl代碼之間的聯系。
首先,定義了協議頭類以及應用類(C++中)
static class PingHeaderClass : public PacketHeaderClass { public:PingHeaderClass() : PacketHeaderClass("PacketHeader/Ping", sizeof(hdr_ping)) {} } class_pinghdr;static class PingClass : public TclClass { public:PingClass() : TclClass("Agent/Ping") {}TclObject* create(int, const char*const*) {return (new PingAgent());} } class_ping;下一段代碼是類“PingAgent”的構造函數。 它綁定了必須在Tcl和C ++中訪問的變量。TCL中的(packetSize)——>C++(size)
PingAgent::PingAgent() : Agent(PT_PING) {bind("packetSize_", &size_);bind("off_ping_", &off_ping_); }
當執行類“PingAgent”的Tcl命令時,將調用函數'command()'。 在本案例中,將是'$ pa send'(假設'pa'是Agent / Ping類的一個實例),因為我們希望將ping數據包從代理發送到另一個ping代理。 我們基本上必須在'command()'函數中解析命令,如果沒有匹配,則必須將其參數傳遞給基類的command()函數(在這種情況下為“代理” ::命令()'(詳見代碼倒數第二行的return))
int PingAgent::command(int argc, const char*const* argv) {if (argc == 2) {if (strcmp(argv[1], "send") == 0) {// Create a new packetPacket* pkt = allocpkt();// Access the Ping header for the new packet:hdr_ping* hdr = (hdr_ping*)pkt->access(off_ping_);// Set the 'ret' field to 0, so the receiving node knows// that it has to generate an echo packethdr->ret = 0;// Store the current time in the 'send_time' fieldhdr->send_time = Scheduler::instance().clock();// Send the packetsend(pkt, 0);// return TCL_OK, so the calling function knows that the// command has been processedreturn (TCL_OK);}}// If the command hasn't been processed by PingAgent()::command,// call the command() function for the base classreturn (Agent::command(argc, argv)); }
函數recv()定義了接收到數據包時要執行的操作。 如果'ret'字段為0,則必須返回“send_time”字段的值相同但“ret”字段設置為1的數據包。 如果'ret'為1,則會調用Tcl函數(必須由Tcl中的用戶定義)函數并處理該事件。
void PingAgent::recv(Packet* pkt, Handler*) {// Access the IP header for the received packet:hdr_ip* hdrip = (hdr_ip*)pkt->access(off_ip_);// Access the Ping header for the received packet:hdr_ping* hdr = (hdr_ping*)pkt->access(off_ping_);// 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_timedouble stime = hdr->send_time;// Discard the packetPacket::free(pkt);// Create a new packetPacket* pktret = allocpkt(); // Access the Ping header for the new packet:hdr_ping* hdrret = (hdr_ping*)pktret->access(off_ping_);// Set the 'ret' field to 1, so the receiver won't send another echohdrret->ret = 1; // Set the send_time field to the correct valuehdrret->send_time = stime; // 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); } }
完整代碼: /** File: Code for a new 'Ping' Agent Class for the ns* network simulator* Author: Marc Greis (greis@cs.uni-bonn.de), May 1998**/#include "ping.h"static class PingHeaderClass : public PacketHeaderClass { public:PingHeaderClass() : PacketHeaderClass("PacketHeader/Ping", sizeof(hdr_ping)) {} } class_pinghdr;static class PingClass : public TclClass { public:PingClass() : TclClass("Agent/Ping") {}TclObject* create(int, const char*const*) {return (new PingAgent());} } class_ping;PingAgent::PingAgent() : Agent(PT_PING) {bind("packetSize_", &size_);bind("off_ping_", &off_ping_); }int PingAgent::command(int argc, const char*const* argv) {if (argc == 2) {if (strcmp(argv[1], "send") == 0) {// Create a new packetPacket* pkt = allocpkt();// Access the Ping header for the new packet:hdr_ping* hdr = (hdr_ping*)pkt->access(off_ping_);// Set the 'ret' field to 0, so the receiving node knows// that it has to generate an echo packethdr->ret = 0;// Store the current time in the 'send_time' fieldhdr->send_time = Scheduler::instance().clock();// Send the packetsend(pkt, 0);// return TCL_OK, so the calling function knows that the// command has been processedreturn (TCL_OK);}}// If the command hasn't been processed by PingAgent()::command,// call the command() function for the base classreturn (Agent::command(argc, argv)); }void PingAgent::recv(Packet* pkt, Handler*) {// Access the IP header for the received packet:hdr_ip* hdrip = (hdr_ip*)pkt->access(off_ip_);// Access the Ping header for the received packet:hdr_ping* hdr = (hdr_ping*)pkt->access(off_ping_);// 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_timedouble stime = hdr->send_time;// Discard the packetPacket::free(pkt);// Create a new packetPacket* pktret = allocpkt();// Access the Ping header for the new packet:hdr_ping* hdrret = (hdr_ping*)pktret->access(off_ping_);// Set the 'ret' field to 1, so the receiver won't send another echohdrret->ret = 1;// Set the send_time field to the correct valuehdrret->send_time = stime;// Send the packetsend(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 timesprintf(out, "%s recv %d %3.1f", name(), hdrip->src_ >> Address::instance().NodeShift_[1], (Scheduler::instance().clock()-hdr->send_time) * 1000);Tcl& tcl = Tcl::instance();tcl.eval(out);// Discard the packetPacket::free(pkt);} }
總結
以上是生活随笔為你收集整理的NS2相关学习——完成一个新协议(2)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 文本显示变量_【RPA课堂】UiPath
- 下一篇: 讲座记录——大数据共享和交易的挑战与初探