-
-
#include “pong.h”
-
-
int hdr_pong::offset_;
-
-
// PacketHeaderClass를 상속받아 PongHeaderClass를 선언
-
// 이미 많은 protocol header들이 PacketHeaderClass를 상속받아 정의되어 있다.
-
// 동일한 방법으로 PacketHeader 아래에 Pong header를 둔다.
-
// pong.h 에서 정의한 hdr_pong의 offset를 연결한다.
-
static class PongHeaderClass : public PacketHeaderClass {
-
public:
-
PongHeaderClass() : PacketHeaderClass(“PacketHeader/Pong”, sizeof(hdr_pong)) {
-
bind_offset(&hdr_pong::offset_);
-
}
-
} class_ponghdr;
-
-
// TclClass를 상속받아 PongClass를 선언
-
// Agent 하위에 Pong을 두기 위해 “Agent/Pong”을 지정
-
// 이 부분은 tcl 파일을 작성할 때 “set p0 [new Agent/Pong]”와 같이 사용됨
-
// PongAgent를 TclObject로 생성하여 반환
-
static class PongClass : public TclClass {
-
public:
-
PongClass() : TclClass(“Agent/Pong”) { }
-
TclObject* create(int, const char*const*) {
-
return (new PongAgent);
-
}
-
} class_pong;
-
-
// PongAgent의 생성자를 구체적으로 정의하는 부분
-
// 생성자에서는 C++과 Tcl을 바인드하도록 함.
-
PongAgent::PongAgent() : Agent(PT_PONG) {
-
bind(“packetSize_”, &size_);
-
}
-
-
// PongAgent의 command 메소드를 정의
-
// 궁극적으로 이 부분은 pong packet을 send하는 부분이다.
-
// Packet을 생성하고, pong header의 시작지점으로 이동하여,
-
// ret를 0으로 설정하고, 시간을 설정한 다음, Packet을 전송한다.
-
int PongAgent::command(int argc, const char*const* argv) {
-
if(argc == 2) {
-
if(strcmp(argv[1], “send”) == 0) {
-
-
// 새로운 packet을 준비
-
// Creaqte a new packet
-
Packet* pkt = allocpkt();
-
-
// packet의 pong header 시작 지점으로 이동
-
// Access the Pong header for the new packet
-
hdr_pong* hdr = hdr_pong::access(pkt);
-
-
// pong header의 ret를 0으로 설정
-
// Set the ‘ret’ field to 0, so the receiving node
-
// knows that it to generate an echo packet
-
hdr->ret = 0;
-
-
// pong header의 send time을 현재의 시간으로 설정
-
// Store the current time in the ‘send_time’ field
-
hdr->send_time = Scheduler::instance().clock();
-
-
// 만들어진 packet을 전송
-
// Send the packet
-
send(pkt, 0);
-
-
// Return TCL_OK, so the calling function knows that
-
// the command has been procoessed
-
return (TCL_OK);
-
}
-
}
-
-
// If the command hasn’t been proceesed by PongAgent()::command,
-
// call the command() function for the base class
-
return (Agent::command(argc, argv));
-
}
-
-
// PongAgent의 recv() 메소드를 정의
-
// Pong Packet을 수신하였을 때 수행하는 부분을 정의
-
void PongAgent::recv(Packet* pkt, Handler*) {
-
// ip header의 시작 지점으로 이동
-
// Access the IP header for the received packet
-
hdr_ip* hdrip = hdr_ip::access(pkt);
-
-
// pong header의 시작 지점으로 이동
-
// Access the pong header for the received packet
-
hdr_pong* hdr = hdr_pong::access(pkt);
-
-
// ret = 0 이면, 즉 처음 수신한 packet일 때 처리하는 부분
-
if(hdr->ret == 0) {
-
// packet에 있는 시간을 stime에 할당
-
double stime = hdr->send_time;
-
-
// packet을 폐기
-
Packet::free(pkt);
-
-
// 응답을 위한 packet을 생성
-
Packet* pktret = allocpkt();
-
-
// packet의 pong header 시작지점으로 이동
-
hdr_pong* hdrret = hdr_pong::access(pktret);
-
-
// packet의 ret를 1로 설정
-
hdrret->ret = 1;
-
-
// packet의 send_time에 packet을 수신한 시간을 설정
-
hdrret->send_time = stime;
-
-
// packet을 전송
-
send(pktret, 0);
-
} else { // ret = 1 이면, 즉 보낸 packet이 다시 되돌아왔을 때 처리하는 부분
-
// 출력을 위한 변수 out을 선언
-
char out[100];
-
-
// out 변수에 내용을 기록
-
// “이름(Agent/Pong) recv from(Source address) rtt(round-trip-time)”의 형태를 갖추어 기록
-
sprintf(out, “%s recv %d %3.1f”,
-
-
// %s에 해당하는 부분(노드 이름)
-
name(),
-
-
// %d에 해당하는 부분(노드 주소)
-
hdrip->src_.addr_ >> Address::instance().NodeShift_[1],
-
-
// %3.1f에 해당하는 부분(응답시간)
-
// (현재시간 – send_time * 1000) –> round-trip-time
-
(Scheduler::instance().clock() – hdr->send_time) * 1000);
-
-
// tcl instance를 생성
-
Tcl& tcl =Tcl::instance();
-
-
// tcl instance로 out을 반환
-
tcl.eval(out);
-
-
// packet을 폐기
-
Packet::free(pkt);
-
}
-
}
[…] http://pchero21.com/500 […]