==================================================================================
[참고 : Marc Greis's Tutorial의 "VII. A new protocol fo ns" ]
본 내용은 위 사이트의 NS by Example의 내용을 학습하면서 정리한 것입니다.
여기서 정리된 내용으로 인해 발생 할 수 있는 문제에 대해서는 책임을 지지 않습니다.
USE AT YOUR OWN RISK!
==================================================================================
■ 본 예제는 Marc Greis's Tutorial의 ping 예제를 추가하는 부분을 정리한 것임. 최근 NS 버전에는
ping이 작성되어 있으므로 NS에 새로운 Application을 추가하는 방법을 학습하기 위한 예제로 이름만
수정하여 작성하였음.
■ 따라서 소스 자체에 대한 의미보다는 NS에 새로운 어플리케이션을 추가하는 방법적인면에 중점을 두고 이해 바람.
■ 실습을 위해 "ping" 이라는 명칭 대신 "hoya"라는 예제명으로 고쳐 작성.
■ OTcl과 C++ 링크에 대한 부분은 본 블로그의 [OTcl & C++ Linkage]를 참조하거나 기타 다른 NS2 관련 사이트를 참조.
■ hoya.h
========================================================================================
/* This is a ping example included in the ns2 */
/* I modified the ping.h and ping.cc as hoya */
#ifndef ns_hoya_h
#define ns_hoya_h
#include "agent.h"
#include "tclcl.h"
#include "packet.h"
#include "address.h"
#include "ip.h"
// "hoya"라는 새로운 프로토콜에 대한 패킷 헤더 구조를 정의
// ret | send_time 두 개의 필드로 "hoya"의 패킷 헤더를 정의
struct hdr_hoya {
// 0: sender -> the node, 1: sender <- the node
// 즉, 0이면 ping_request, 1이면 ping_reply가 될 것임
char ret;
// timestamp when this packet is sent.
// 나중에 RTT(round_trip_time)를 계산하기 위함
double send_time;
// Header access methods
// 패킷으로 부터 "hoya" 패킷에 접근하기 위한 방법을 정의하는 매크로
static int offset_; // required by PacketHeaderManager
inline static int& offset() { return offset_; }
inline static hdr_hoya* access(const Packet* p) {
return (hdr_hoya*) p->access(offset_);
}
};
// declare "HoyaAgent" as a subclass of "Agent"
// 나중에 이 클래스에 대한 객체를 생성하기 위해
// TclClass를 상속합든 HoyaClass를 정의해야함
class HoyaAgent : public Agent {
public:
HoyaAgent();
virtual int command(int argc, const char*const* argv);
virtual void recv(Packet*, Handler*);
};
#endif // ns_hoya_h
========================================================================================
■ hoya.cc
========================================================================================
/* This is a ping example included in the ns2 */
/* I modified the ping.h and ping.cc as hoya */
#include "hoya.h"
int hdr_hoya::offset_;
static class HoyaHeaderClass : public PacketHeaderClass {
public:
HoyaHeaderClass() : PacketHeaderClass("PacketHeader/Hoya", sizeof(hdr_hoya))
{
bind_offset(&hdr_hoya::offset_);
}
} class_hoyahdr;
// HoyaAgent 객체를 생성하기 위해 TclClass 상속받는 HoyaClass 생성
// C++ (HoyaAgent)와 Tcl (Agent/Hoya)를 링크하게 됨.
// NS 실행시 static vairable를 실행하여 HoyaClass의 인스턴스가 생성됨
// 따라서 Tcl에서 "new Agent/Hoya" 명령어를 통해 HoyaAgent::create()가 호출됨
static class HoyaClass : public TclClass {
public:
HoyaClass() : TclClass("Agent/Hoya") {}
TclObject* create(int, const char*const*)
{
return (new HoyaAgent());
}
} class_hoya;
// constructor : Tcl과 C++에서 접근되는 변수들을 binding
// '_'로 끝나는 변수들은 local object scope를 가짐
HoyaAgent::HoyaAgent() : Agent(PT_HOYA) // PT_HOYA : packet.h에 추가될 프로토콜 이름
{
// Tcl 인스턴스 변수 "packetSize_ " 와 C++ 변수 "size_" 바인딩
// bind()는 클래스의 생성자에 있어야 함
// Tcl 변수는 ns-default.tcl 에 등록하거나 시뮬레이션 스크립트에서 정의 가능.
bind("packetSize_", &size_);
}
// HoyaAgent 클래스에 대한 Tcl 명령어가 호출될 때 실행되는 메소드
int HoyaAgent::command(int argc, const char*const* argv)
{
if (argc == 2) {
// 즉,
// set hoyaagent [new Agent/Hoya]
// $hoyaagent start
// 명령어 실행에 대한 command() 의 처리 코드
if (strcmp(argv[1], "start") == 0) {
// Create a new packet
Packet* pkt = allocpkt();
// Access the Hoya header for the new packet:
hdr_hoya* hdr = hdr_hoya::access(pkt);
// Set the 'ret' field to 0, so the receiving node
// knows that it has to generate an echo packet
hdr->ret = 0;
// Store the current time in the 'send_time' field
hdr->send_time = Scheduler::instance().clock();
// 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 HoyaAgent()::command,
// call the command() function for the base class
return (Agent::command(argc, argv));
}
// 수신 패킷에 대한 처리를 위한 코드를 작성
void HoyaAgent::recv(Packet* pkt, Handler*)
{
// Access the IP header for the received packet:
hdr_ip* hdrip = hdr_ip::access(pkt);
// Access the Hoya header for the received packet:
hdr_hoya* hdr = hdr_hoya::access(pkt);
// Is the 'ret' field = 0 (i.e. the receiving node is being hoyaed)?
if (hdr->ret == 0) {
// Send an 'echo'. First save the old packet's send_time
double stime = hdr->send_time;
// Discard the packet
Packet::free(pkt);
// Create a new packet
Packet* pktret = allocpkt();
// Access the Hoya header for the new packet:
hdr_hoya* hdrret = hdr_hoya::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;
// Send the packet
send(pktret, 0);
} else {
// A packet was received. Use tcl.eval to call the Tcl
// interpreter with the hoya results.
// Note: In the Tcl code, a procedure
// 'Agent/Hoya recv {from rtt}' has to be defined which
// allows the user to react to the hoya 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);
}
}
========================================================================================
■ hoya.tcl
========================================================================================
#Create a simulator object
set ns [new Simulator]
#Open a trace file
set nf [open hoya_out.nam w]
$ns namtrace-all $nf
#Define a 'finish' procedure
proc finish {} {
global ns nf
$ns flush-trace
close $nf
exec nam hoya_out.nam &
exit 0
}
#Create three nodes
set n0 [$ns node]
set n1 [$ns node]
set n2 [$ns node]
#Connect the nodes with two links
$ns duplex-link $n0 $n1 1Mb 10ms DropTail
$ns duplex-link $n1 $n2 1Mb 10ms DropTail
#Define a 'recv' function for the class 'Agent/Hoya'
Agent/Hoya instproc recv {from rtt} {
$self instvar node_
puts "node [$node_ id] received hoya answer from \
$from with round-trip-time $rtt ms."
}
#Create two hoya agents and attach them to the nodes n0 and n2
set p0 [new Agent/Hoya]
$ns attach-agent $n0 $p0
set p1 [new Agent/Hoya]
$ns attach-agent $n2 $p1
#Connect the two agents
$ns connect $p0 $p1
#Schedule events
$ns at 0.2 "$p0 start"
$ns at 0.4 "$p1 start"
$ns at 0.6 "$p0 start"
$ns at 0.6 "$p1 start"
$ns at 1.0 "finish"
#Run the simulation
$ns run
========================================================================================
■ NS 수정사항
1. 일단 hoya.h와 hoya.cc 소스 코드를 ns-2.xx 폴더내에 작성합니다
(이 폴더내에 따로 hoya라는 폴더를 만들어서 이 폴더에서 코드를 저장해도 무방함).
2. packet.h의 enum packet_t { 부분에 "PT_HOYA"를 추가하고, class p_info { 의 p_info()내에
name_[PT_HOYA] = "Hoya"를 추가합니다. (아마도 common 디렉토리에 있을 것)
3. tcl/lib/ns-default.tcl 파일에 "Agent/Hoya set packetSize_ 64"를 추가
4. tcl/lib/ns-packet.tcl 파일에 foreach proto { 부분에 "Hoya" 추가 (위치는 그다지 중요하지 않은것 같음)
5. Makefile에 "OBJ_CC" 부분에 "hoya/hoya.o \" 라고 추가(hoya 폴더를 따로 만들어 작성한경우임).
6. 컴파일 : make depend; make
7. hoya.tcl 실행해보기.
[출처] [NS2] 새로운 어플리케이션 추가 (ex. Ping)|작성자 호야다
'Network > Ns2_source' 카테고리의 다른 글
First wimax simulation script - wimax1.tcl 11Mb에 대한 실험 - 논문에 실제 참조해봄- (0) | 2009.01.17 |
---|---|
ns2 - TCP OVER NOISY LINKS AND QUEUE MONITORING (0) | 2009.01.17 |
AP의 설정 (0) | 2009.01.17 |
mac의 transmit (0) | 2009.01.17 |
awk script- delay 계산 (0) | 2009.01.17 |