📄 mm-app.cc
字号:
// // Author: Jae Chung // File: mm-app.cc// Written: 07/17/99 (for ns-2.1b4a) // Modifed: 10/14/01 (for ns-2.1b8a) // #include "random.h"#include "mm-app.h"// MmApp OTcl linkage classstatic class MmAppClass : public TclClass { public: MmAppClass() : TclClass("Application/MmApp") {} TclObject* create(int, const char*const*) { return (new MmApp); }} class_app_mm;// When snd_timer_ expires call MmApp:send_mm_pkt()void SendTimer::expire(Event*){ t_->send_mm_pkt();}// When ack_timer_ expires call MmApp:send_ack_pkt()void AckTimer::expire(Event*){ t_->send_ack_pkt();}// Constructor (also initialize instances of timers)MmApp::MmApp() : running_(0), snd_timer_(this), ack_timer_(this){ bind_bw("rate0_", &rate[0]); bind_bw("rate1_", &rate[1]); bind_bw("rate2_", &rate[2]); bind_bw("rate3_", &rate[3]); bind_bw("rate4_", &rate[4]); bind("pktsize_", &pktsize_); bind_bool("random_", &random_);}// OTcl command interpreterint MmApp::command(int argc, const char*const* argv){ Tcl& tcl = Tcl::instance(); if (argc == 3) { if (strcmp(argv[1], "attach-agent") == 0) { agent_ = (Agent*) TclObject::lookup(argv[2]); if (agent_ == 0) { tcl.resultf("no such agent %s", argv[2]); return(TCL_ERROR); } // Make sure the underlying agent support MM if(agent_->supportMM()) { agent_->enableMM(); } else { tcl.resultf("agent \"%s\" does not support MM Application", argv[2]); return(TCL_ERROR); } agent_->attachApp(this); return(TCL_OK); } } return (Application::command(argc, argv));}void MmApp::init(){ scale_ = 0; // Start at minimum rate seq_ = 0; // MM sequence number (start from 0) interval_ = (double)(pktsize_ << 3)/(double)rate[scale_];}void MmApp::start(){ init(); running_ = 1; send_mm_pkt();}void MmApp::stop(){ running_ = 0;}// Send application data packetvoid MmApp::send_mm_pkt(){ hdr_mm mh_buf; if (running_) { // the below info is passed to UDPmm agent, which will write it // to MM header after packet creation. mh_buf.ack = 0; // This is a MM packet mh_buf.seq = seq_++; // MM sequece number mh_buf.nbytes = pktsize_; // Size of MM packet (NOT UDP packet size) mh_buf.time = Scheduler::instance().clock(); // Current time mh_buf.scale = scale_; // Current scale value agent_->sendmsg(pktsize_, (char*) &mh_buf); // send to UDP // Reschedule the send_pkt timer double next_time_ = next_snd_time(); if(next_time_ > 0) snd_timer_.resched(next_time_); }}// Schedule next data packet transmission timedouble MmApp::next_snd_time(){ // Recompute interval in case rate or size chages interval_ = (double)(pktsize_ << 3)/(double)rate[scale_]; double next_time_ = interval_; if(random_) next_time_ += interval_ * Random::uniform(-0.5, 0.5); return next_time_;}// Receive message from underlying agentvoid MmApp::recv_msg(int nbytes, const char *msg){ if(msg) { hdr_mm* mh_buf = (hdr_mm*) msg; if(mh_buf->ack == 1) { // If received packet is ACK packet set_scale(mh_buf); } else { // If received packet is MM packet account_recv_pkt(mh_buf); if(mh_buf->seq == 0) send_ack_pkt(); } }}// Sender sets its scale to what reciver notifiesvoid MmApp::set_scale(const hdr_mm *mh_buf){ scale_ = mh_buf->scale;}void MmApp::account_recv_pkt(const hdr_mm *mh_buf){ double local_time = Scheduler::instance().clock(); // Calculate RTT if(mh_buf->seq == 0) { init_recv_pkt_accounting(); p_accnt.rtt = 2*(local_time - mh_buf->time); } else p_accnt.rtt = 0.9 * p_accnt.rtt + 0.1 * 2*(local_time - mh_buf->time); // Count Received packets and Calculate Packet Loss p_accnt.recv_pkts ++; p_accnt.lost_pkts += (mh_buf->seq - p_accnt.last_seq - 1); p_accnt.last_seq = mh_buf->seq;}void MmApp::init_recv_pkt_accounting(){ p_accnt.last_seq = -1; p_accnt.last_scale = 0; p_accnt.lost_pkts = 0; p_accnt.recv_pkts = 0;}void MmApp::send_ack_pkt(void){ double local_time = Scheduler::instance().clock(); adjust_scale(); // send ack message hdr_mm ack_buf; ack_buf.ack = 1; // this packet is ack packet ack_buf.time = local_time; ack_buf.nbytes = 40; // Ack packet size is 40 Bytes ack_buf.scale = p_accnt.last_scale; agent_->sendmsg(ack_buf.nbytes, (char*) &ack_buf); // schedul next ACK time ack_timer_.resched(p_accnt.rtt);}void MmApp::adjust_scale(void){ if(p_accnt.recv_pkts > 0) { if(p_accnt.lost_pkts > 0) p_accnt.last_scale = (int)(p_accnt.last_scale / 2); else { p_accnt.last_scale++; if(p_accnt.last_scale > 4) p_accnt.last_scale = 4; } } p_accnt.recv_pkts = 0; p_accnt.lost_pkts = 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -