⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tfrc.cc

📁 Ns2 TCP 协议改进 版本 提高goodput
💻 CC
📖 第 1 页 / 共 2 页
字号:
	/* fine grained RTT estimate for use in the equation */	if (rtt_ > 0) {		rtt_ = df_*rtt_ + ((1-df_)*(now - tao));		sqrtrtt_ = df_*sqrtrtt_ + ((1-df_)*sqrt(now - tao));	} else {		rtt_ = now - tao;		sqrtrtt_ = sqrt(now - tao);	}	rttcur_ = now - tao;}/* * Receive a status report from the receiver. */void TfrcAgent::recv(Packet *pkt, Handler *){	double now = Scheduler::instance().clock();	hdr_tfrc_ack *nck = hdr_tfrc_ack::access(pkt);	//double ts = nck->timestamp_echo;	double ts = nck->timestamp_echo + nck->timestamp_offset;	double rate_since_last_report = nck->rate_since_last_report;	// double NumFeedback_ = nck->NumFeedback_;	double flost = nck->flost; 	int losses = nck->losses;	true_loss_rate_ = nck->true_loss;	round_id ++ ;	UrgentFlag = 0;	if (rate_since_last_report > 0) {		/* compute the max rate for slow-start as two times rcv rate */ 		ss_maxrate_ = 2*rate_since_last_report*size_;		if (conservative_) { 			if (losses >= 1) {				/* there was a loss in the most recent RTT */				if (debug_) printf("time: %5.2f losses: %d rate %5.2f\n", 				  now, losses, rate_since_last_report);				maxrate_ = rate_since_last_report*size_;			} else { 				/* there was no loss in the most recent RTT */				maxrate_ = scmult_*rate_since_last_report*size_;			}			if (debug_) printf("time: %5.2f losses: %d rate %5.2f maxrate: %5.2f\n", now, losses, rate_since_last_report, maxrate_);		} else 			maxrate_ = 2*rate_since_last_report*size_;	} else {		ss_maxrate_ = 0;		maxrate_ = 0; 	}			/* update the round trip time */	update_rtt (ts, now);	/* .. and estimate of fair rate */	if (voip_ != 1) {		// From RFC 3714:		// The voip flow gets to send at the same rate as		//  a TCP flow with 1460-byte packets.		fsize_ = size_;	}	rcvrate = p_to_b(flost, rtt_, tzero_, fsize_, bval_);	// rcvrate is in bytes per second, based on fairness with a    	// TCP connection with the same packet size size_.	      	if (voip_) {		// Subtract the bandwidth used by headers.		double temp = rcvrate*(size_/(1.0*headersize_+size_));		rcvrate = temp;	}	/* if we get no more feedback for some time, cut rate in half */	double t = 2*rtt_ ; 	if (t < 2*size_/rate_) 		t = 2*size_/rate_ ; 	NoFeedbacktimer_.resched(t);		/* if we are in slow start and we just saw a loss */	/* then come out of slow start */	if (first_pkt_rcvd == 0) {		first_pkt_rcvd = 1 ; 		slowstart();		nextpkt();	}	else {		if (rate_change_ == SLOW_START) {			if (flost > 0) {				rate_change_ = OUT_OF_SLOW_START;				oldrate_ = rate_ = rcvrate;			}			else {				slowstart();				nextpkt();			}		}		else {			if (rcvrate>rate_) 				increase_rate(flost);			else 				decrease_rate ();				}	}	if (printStatus_) {		printf("time: %5.2f rate: %5.2f\n", now, rate_);		double packetrate = rate_ * rtt_ / size_;		printf("time: %5.2f packetrate: %5.2f\n", now, packetrate);	}	Packet::free(pkt);}/* * Used in setting the initial rate. * This is from TcpAgent::initial_wnd(). */double TfrcAgent::initial_rate(){        if (rate_init_option_ == 1) {		// init_option = 1: static initial rate of rate_init_                return (rate_init_);        }        else if (rate_init_option_ == 2) {                // do initial rate according to RFC 3390.                if (size_ <= 1095) {                        return (4.0);                } else if (size_ < 2190) {                        return (3.0);                } else {                        return (2.0);                }        }        // XXX what should we return here???        fprintf(stderr, "Wrong number of rate_init_option_ %d\n",                rate_init_option_);        abort();        return (2.0); // XXX make msvc happy.}// ss_maxrate_ = 2*rate_since_last_report*size_;// rate_: the rate set from the last pass through slowstart()// oldrate_: the rate the time before that.void TfrcAgent::slowstart () {	double now = Scheduler::instance().clock(); 	if (round_id <= 1) {		/* This is the first report, so */		/*   change rate to initial rate.*/		oldrate_ = rate_;		rate_ =  initial_rate()*size_/rtt_;		/* Compute delta so that if slow_increase_ is set to true, */		/*  rate increases slowly to new value. */		delta_ = (rate_ - oldrate_)/(rate_*rtt_/size_);		last_change_ = now;	} else if (!ss_changes_ && rate_+SMALLFLOAT< size_/rtt_) {		oldrate_ = rate_;		rate_ = size_/rtt_;		delta_ = (rate_ - oldrate_)/(rate_*rtt_/size_);		last_change_ = now;	} else if (ss_maxrate_ > 0) {		/* Compute delta, so that if slow_increase_ is set,   */		/*  the rate increases slowly to its new value.       */		if (ssmult_*rate_ < ss_maxrate_ && now - last_change_ > rtt_) {			/* Multiply the rate by ssmult_.                 */			if (ss_changes_) oldrate_ = rate_;			rate_ = ssmult_*rate_; 			delta_ = (rate_ - oldrate_)/(rate_*rtt_/size_);			last_change_=now;		} else if (oldrate_ > ss_maxrate_) {			// Time to reduce the sending rate,			//   to emulate ack-clocking.			rate_ = oldrate_ = 0.5*ss_maxrate_;			delta_ = 0; 			last_change_ = now;		} else if ((!ss_changes_ || round_id > 2) 			&& rate_ > ss_maxrate_) {			// if round_id is 2, then ss_maxrate_ doesn't			//   reflect the slow-start sending rate yet.			if (ss_changes_) oldrate_ = rate_;			rate_ = ss_maxrate_; 			delta_ = (rate_ - oldrate_)/ (rate_*rtt_/size_);			last_change_ = now; 		} else {			// rate < ss_maxrate < ssmult_*rate_			if (now - last_change_ > rtt_) {				if (ss_changes_) oldrate_ = rate_;				rate_ = ss_maxrate_;				delta_ = (rate_ - oldrate_)/ (rate_*rtt_/size_);				last_change_=now;			}		}	} else {		// If we get here, ss_maxrate <= 0, so the receive rate is 0.		// We should go back to a very small sending rate!!!		// Changed by Sally on 10/20/2004.		if (ss_changes_) oldrate_ = rate_;		if (ss_changes_) rate_ = size_/rtt_; else rate_ = ssmult_*rate_;		delta_ = (rate_ - oldrate_)/(rate_*rtt_/size_);		last_change_=now;	}	}void TfrcAgent::increase_rate (double p){                       double now = Scheduler::instance().clock();	double mult = (now-last_change_)/rtt_ ;	if (mult > 2) mult = 2 ;	rate_ = rate_ + (size_/rtt_)*mult ;	double maximumrate = (maxrate_>size_/rtt_)?maxrate_:size_/rtt_ ;	maximumrate = (maximumrate>rcvrate)?rcvrate:maximumrate;	rate_ = (rate_ > maximumrate)?maximumrate:rate_ ;	        rate_change_ = CONG_AVOID;          last_change_ = now;	heavyrounds_ = 0;}       void TfrcAgent::decrease_rate () {	double now = Scheduler::instance().clock(); 	rate_ = rcvrate;	double maximumrate = (maxrate_>size_/rtt_)?maxrate_:size_/rtt_ ;	// Allow sending rate to be greater than maximumrate	//   (which is by default twice the receiving rate)	//   for at most maxHeavyRounds_ rounds.	if (rate_ > maximumrate)		heavyrounds_++;	else		heavyrounds_ = 0;	if (heavyrounds_ > maxHeavyRounds_) {		rate_ = (rate_ > maximumrate)?maximumrate:rate_ ;	}	rate_change_ = RATE_DECREASE;	last_change_ = now;}void TfrcAgent::sendpkt(){	if (active_) {		double now = Scheduler::instance().clock(); 		Packet* p = allocpkt();		hdr_tfrc *tfrch = hdr_tfrc::access(p);		hdr_flags* hf = hdr_flags::access(p);		if (ecn_) {			hf->ect() = 1;  // ECN-capable transport		}		tfrch->seqno=seqno_++;		tfrch->timestamp=Scheduler::instance().clock();		tfrch->rtt=rtt_;		tfrch->tzero=tzero_;		tfrch->rate=rate_;		tfrch->psize=size_;		tfrch->fsize=fsize_;		tfrch->UrgentFlag=UrgentFlag;		tfrch->round_id=round_id;		ndatapack_++;		ndatabytes_ += size_;		if (useHeaders_ == true) {			hdr_cmn::access(p)->size() += headersize_;		}		last_pkt_time_ = now;		send(p, 0);	}}void TfrcAgent::reduce_rate_on_no_feedback(){	rate_change_ = RATE_DECREASE; 	if (oldCode_ || !datalimited_ || rate_ > 4.0 * size_/rtt_ ) {		// if we are not datalimited,		//   or the current rate is greater than four pkts per RTT		rate_*=0.5;	}	UrgentFlag = 1;	round_id ++ ;	double t = 2*rtt_ ; 	if (t < 2*size_/rate_) 		t = 2*size_/rate_ ; 	NoFeedbacktimer_.resched(t);	nextpkt();}void TfrcSendTimer::expire(Event *) {  	a_->nextpkt();}void TfrcNoFeedbackTimer::expire(Event *) {	a_->reduce_rate_on_no_feedback ();	// TODO: if the first (SYN) packet was dropped, then don't use	//   the larger initial rates from RFC 3390:        // if (highest_ack_ == -1 && wnd_init_option_ == 2)	//     wnd_init_option_ = 1;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -