用ns写的一个网络模拟 实现rdt 里面有所有源代码和文档说明

源代码在线查看: rdt-app.cc

软件大小: 757 K
上传用户: wyly
关键词: rdt 网络 模拟 有源
下载地址: 免注册下载 普通下载 VIP

相关代码

								#include "random.h"				#include "rdt-app.h"												// rdtApp OTcl linkage class				static class rdtAppClass : public TclClass {				 public:				  rdtAppClass() : TclClass("Application/rdtApp") {}				  TclObject* create(int, const char*const*) {				    return (new rdtApp);				  }				} class_app_rdt;												// When snd_timer_ expires call rdtApp:send_rdt_pkt()				void SendTimer::expire(Event*)				{				  t_->send_rdt_pkt();				}												// When ack_timer_ expires call rdtApp:send_ack_pkt()				void AckTimer::expire(Event*)				{				  t_->send_ack_pkt();				}												// Constructor (also initialize instances of timers)				rdtApp::rdtApp() : 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 interpreter				int rdtApp::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 rdt Application", argv[2]);					return(TCL_ERROR);				      }				      				      agent_->attachApp(this);				      return(TCL_OK);				    }				  }				  return (Application::command(argc, argv));				}																void rdtApp::init()				{				  rwindow_=7;	//初始化接受方窗口大小				  swindow_=7;	//初始化发送方窗口大小				  scale_ = 0; // Start at minimum rate				  rseq_ = 8;   // rdt sequence number (start from 8) (receiver)				  sseq_ = 8;  // rdt sequence number (start from 8) (sender)				  lastack_ =8; //the seq of the last ack_pkt				  interval_ = (double)(pktsize_ 				}												void rdtApp::start()				{				  init();				  running_ = 1;				  send_rdt_pkt();				}												void rdtApp::stop()				{				  running_ = 0;				}												// Send application data packet				void rdtApp::send_rdt_pkt()				{				  hdr_rdt mh_buf;								  if (running_) {				    // the below info is passed to UDPrdt agent, which will write it 				    // to rdt header after packet creation.				    swindow_--;				    mh_buf.ack = 0;            // This is not a ack packet				    mh_buf.rej = 0;            // This is not a rej packet				    mh_buf.seq = ((sseq_++) % 8);         // rdt sequece number				    mh_buf.nbytes = pktsize_;  // Size of rdt 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 time				double rdtApp::next_snd_time()				{				  // Recompute interval in case rate or size chages				  interval_ = (double)(pktsize_ 				  double next_time_ = interval_;				  if(random_) 				    next_time_ += interval_ * Random::uniform(-0.5, 0.5);				  return next_time_;				}												// Receive message from underlying agent				void rdtApp::recv_msg(int nbytes, const char *msg)				{				  if(msg) {				    hdr_rdt* mh_buf = (hdr_rdt*) msg;									if(mh_buf->ack == 1) {				      // If received packet is ACK packet						adjust_swindow(mh_buf);						lastack_ = mh_buf->seq;					        set_scale(mh_buf);					    }					else if( mh_buf ->rej == 1) {					 // If received packet is REJ packet						resend_rdt_pkt(mh_buf);					}					else {				      // If received packet is rdt packet						account_recv_pkt(mh_buf);						if(mh_buf->seq == 8) send_ack_pkt();						else if(mh_buf->seq !=((rseq_ + 1) % 8)) {							send_rej_pkt();							}							else {								rseq_= mh_buf ->seq;								rwindow_--;							}					    }				  }				}								void rdtApp::adjust_swindow( const hdr_rdt *mh_buf)				{					if(swindow_ == 0) {						swindow_ = swindow_ +( (mh_buf->seq + 8 - lastack_ ) % 8);						send_rdt_pkt();					}					else						swindow_ = swindow_ +( (mh_buf->seq + 8 - lastack_ ) % 8);				}												void rdtApp::adjust_rwindow(void)				{					rwindow_ = rwindow_ + (( rseq_ - lastack_ ) % 8);				}								void rdtApp::resend_rdt_pkt( const hdr_rdt *mh_buf)				{					sseq_ =mh_buf->seq;					send_rdt_pkt();				}													void rdtApp::send_ack_pkt(void)				{				  double local_time = Scheduler::instance().clock();								  adjust_scale();								  // send ack message				  hdr_rdt ack_buf;				  ack_buf.rej=0;				  ack_buf.ack = 1;  // this packet is ack packet				  ack_buf.seq= rseq_;				  ack_buf.time = local_time;				  ack_buf.nbytes = 40;  // Ack packet size is 40 Bytes				  ack_buf.scale = p_accnt.last_scale;								  adjust_rwindow();								  agent_->sendmsg(ack_buf.nbytes, (char*) &ack_buf);								  // schedul next ACK time				  ack_timer_.resched(p_accnt.rtt);				}												void rdtApp::send_rej_pkt(void)				{									  double local_time = Scheduler::instance().clock();								  adjust_scale();								  // send ack message				  hdr_rdt ack_buf;				  ack_buf.rej=1;				  ack_buf.seq= rseq_;				  ack_buf.ack = 0;  // 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);				}												// Sender sets its scale to what reciver notifies				void rdtApp::set_scale(const hdr_rdt *mh_buf)				{ 				  scale_ = mh_buf->scale;				}												void rdtApp::account_recv_pkt(const hdr_rdt *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 rdtApp::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 rdtApp::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;				}							

相关资源