日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

NS2相关学习——完成一个新协议(2)

發布時間:2024/8/23 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 NS2相关学习——完成一个新协议(2) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在上節中,我們把教程要求的3.1-3.3過了一遍,這一次回到正途上來。看看到底是怎么完成一個新的協議的。

本節中的代碼實現了一些簡單的“ping”協議(靈感來自“ns注釋和文檔”(現在更名為ns手冊)的第9.6章中的“ping請求者”,但相當不同)。 一個節點將能夠發送一個數據包到另一個節點,它將立即返回,以便可以計算往返時間。

1、頭文件

在新的頭文件'ping.h'中,首先必須聲明將攜帶相關數據的新的Ping包頭的數據結構。

struct hdr_ping {char ret;double send_time; };如果數據包正在從發送方正在被ping通的節點上,則char'ret'將被設置為“0”,而在返回路由時將被設置為“1”。 double “send_time”是發送時在分組上設置的時間戳,用于后來計算往返時間。

以下代碼段將類“PingAgent”聲明為類“Agent”的子類。

class PingAgent : public Agent {public:PingAgent();int command(int argc, const char*const* argv);void recv(Packet*, Handler*);protected:int off_ping_; };

?int off_ping_將用于訪問數據包的ping頭。 請注意,對于具有本地對象范圍的變量通常使用尾隨“_”。

在下面的部分中,將介紹定義構造函數“PingAgent()”的C ++代碼以及在本聲明中重新定義的函數'command()'和'recv()'。

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)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。