大作业 NS2中TCP源代码分析_第1页
大作业 NS2中TCP源代码分析_第2页
大作业 NS2中TCP源代码分析_第3页
大作业 NS2中TCP源代码分析_第4页
大作业 NS2中TCP源代码分析_第5页
已阅读5页,还剩33页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

NS2中TCP源代码分析1:NS2简介NS2是一个开放源码的多协议网络模拟软件,来源于1989年的RealNetworkSimulator项目,经过多年的发展,于1995年得到施乐公司(Xerox)的支持,加入VINT项目。NS2—直以来都在吸收世界各地研究者的成果,包括UCB、CMU等大学和SUN等公司的无线网络方面的代码,因此NS2一直都在不断的被更新和完善。NS2是一个面向对象的、离散事件驱动的网络环境模拟工具,可以完整地模拟整个网络环境。NS2使用一整套C++类库实现了绝大多数常见的网络协议以及链路层的模型,如:有线网络或无线网络的TCP、UDP、路由、多播等多种协议模型,利用这些类库的实例就可以搭建起整个网络的模型,而且包括详尽的细节实现。NS2使用了两种编程语言,OTcl(具有面向对象特性的Tcl脚本程序设计语言)和C++,NS2采用这两种语言是因为仿真工具有两方面的事情要做:一方面,具体协议的模拟和实现,这需要一种能高效率的处理字节、报头等信息的程序设计语言,即对运行速度非常重要,而运行模拟环境的时间、寻找和修复Bug的时间,以及重新编译和运行的时间不是很重要,在这种情况下,C++语言是非常合适的;另一方面,许多网络中的实验或研究工作主要是围绕着网络组件和环境的具体参数的设置和改变而进行的,需要在短时间内快速的开发或模拟出所需要的网络环境,并且方便的修改和发现,在这种情况下,网络环境设置的时间就显得重要了,而脚本语言在这方面有很大的优势,具有面向对象特性的Tcl脚本语言可以充分的满足此需求。C++和OTcl两种语言的对象和变量是通过TclCL关联起来的,C++的类和对象为编译类和编译对象,相反地OTcl的类和对象为解释类和解释对象,TclCL是在OTcl基础上的封装。通过下面的NS2架构图来理解几者之间的关系。对NS2使用者来说,OTcl脚本语言用于实现网络拓扑部分,OTcl是架构在Tcl之上的面向对象后的延伸,事件调度器和网络组件这两部分主要用C++编写。C++在最底层则是表示NS2的核心主要就是C++。TclCL是连接OTcl和C++的桥梁,最后搭配用户接口就构成了NS2。2:NS2中TCP源码分析在源码包中,TCP源码放置在ns-allinone-2.35\tcp文件夹里。打开tcp.cc#include<stdlib.h>#include<math.h>#include<sys/types.h>#include"ip.h"#include"tcp.h"#include"flags.h"#include"random.h"#include"basetrace.h"#include"hdr_qs.h"inthdr_tcp::offset_;staticclassTCPHeaderClass:publicPacketHeaderClass{public:TCPHeaderClass():PacketHeaderClass("PacketHeader/TCP",sizeof(hdr_tcp)){bind_offset(&hdr_tcp::offset_);}}class_tcphdr;staticclassTcpClass:publicTclClass{public://存储类名Agent/TCP至classname_TcpClass():TclClass("Agent/TCP"){}TclObject*create(int,constchar*const*){return(newTcpAgent());}}class_tcp;TcpAgent::TcpAgent():Agent(PT_TCP),t_seqno_(0),t_rtt_(0),t_srtt_(0),t_rttvar_(0),t_backoff_(0),ts_peer_(0),ts_echo_(0),tss(NULL),tss_size_(100),rtx_timer_(this),delsnd_timer_(this),burstsnd_timer_(this),dupacks_(0),curseq_(0),highest_ack_(0),cwnd_(0),ssthresh_(0),maxseq_(0),count_(0),rtt_active_(0),rtt_seq_(-1),rtt_ts_(0.0),lastreset_(0.0),closed_(0),first_decrease_(1),fcnt_(0),nrexmit_(0),restart_bugfix_(1),cong_action_(0),ecn_burst_(0),ecn_backoff_(0),ect_(0),qs_requested_(0),qs_approved_(0),qs_window_(0),qs_cwnd_(0),frto_(0),debug_(0){#ifdefTCP_DELAY_BIND_ALL#else/*!TCP_DELAY_BIND_ALL*///notdelay-boundbecausedelay-boundtracevarsaren'tyetsupportedbind("t_seqno_",&t_seqno_);bind("rtt_",&t_rtt_);bind("srtt_",&t_srtt_);bind("rttvar_",&t_rttvar_);bind("backoff_",&t_backoff_);bind("dupacks_",&dupacks_);bind("seqno_",&curseq_);bind("ack_",&highest_ack_);bind("cwnd_",&cwnd_);bind("ssthresh_",&ssthresh_);bind("maxseq_",&maxseq_);bind("ndatapack_",&ndatapack_);bind("ndatabytes_",&ndatabytes_);bind("nackpack_",&nackpack_);bind("nrexmit_",&nrexmit_);bind("nrexmitpack_",&nrexmitpack_);bind("nrexmitbytes_",&nrexmitbytes_);bind("necnresponses_",&necnresponses_);bind("ncwndcuts_",&ncwndcuts_);bind("ncwndcuts1_",&ncwndcuts1_);bind("debug_",&debug_);//addedbysmallko#endif/*TCP_DELAY_BIND_ALL*/}voidTcpAgent::delay_bind_init_all(){//Defaultsforboundvariablesshouldbesetinns-default.tcl.delay_bind_init_one("window_");delay_bind_init_one("windowInit_");delay_bind_init_one("windowInitOption_");delay_bind_init_one("syn_");delay_bind_init_one("windowOption_");delay_bind_init_one("windowConstant_");delay_bind_init_one("windowThresh_");delay_bind_init_one("delay_growth_");delay_bind_init_one("overhead_");delay_bind_init_one("tcpTick_");delay_bind_init_one("ecn_");delay_bind_init_one("SetCWRonRetransmit_");delay_bind_init_one("old_ecn_");delay_bind_init_one("eln_");delay_bind_init_one("eln_rxmit_thresh_");delay_bind_init_one("packetSize_");delay_bind_init_one("tcpip_base_hdr_size_");delay_bind_init_one("ts_option_size_");delay_bind_init_one("bugFix_");delay_bind_init_one("bugFix_ack_");delay_bind_init_one("bugFix_ts_");delay_bind_init_one("lessCareful_");delay_bind_init_one("slow_start_restart_");delay_bind_init_one("restart_bugfix_");delay_bind_init_one("timestamps_");delay_bind_init_one("ts_resetRTO_");delay_bind_init_one("maxburst_");delay_bind_init_one("aggressive_maxburst_");delay_bind_init_one("maxcwnd_");delay_bind_init_one("numdupacks_");delay_bind_init_one("numdupacksFrac_");delay_bind_init_one("exitFastRetrans_");delay_bind_init_one("maxrto_");delay_bind_init_one("minrto_");delay_bind_init_one("srtt_init_");delay_bind_init_one("rttvar_init_");delay_bind_init_one("rtxcur_init_");delay_bind_init_one("T_SRTT_BITS");delay_bind_init_one("T_RTTVAR_BITS");delay_bind_init_one("rttvar_exp_");delay_bind_init_one("awnd_");delay_bind_init_one("decrease_num_");delay_bind_init_one("increase_num_");delay_bind_init_one("k_parameter_");delay_bind_init_one("l_parameter_");delay_bind_init_one("trace_all_oneline_");delay_bind_init_one("nam_tracevar_");delay_bind_init_one("QOption_");delay_bind_init_one("EnblRTTCtr_");delay_bind_init_one("control_increase_");delay_bind_init_one("noFastRetrans_");delay_bind_init_one("precisionReduce_");delay_bind_init_one("oldCode_");delay_bind_init_one("useHeaders_");delay_bind_init_one("low_window_");delay_bind_init_one("high_window_");delay_bind_init_one("high_p_");delay_bind_init_one("high_decrease_");delay_bind_init_one("max_ssthresh_");delay_bind_init_one("cwnd_range_");delay_bind_init_one("timerfix_");delay_bind_init_one("rfc2988_");delay_bind_init_one("singledup_");delay_bind_init_one("LimTransmitFix_");delay_bind_init_one("rate_request_");delay_bind_init_one("qs_enabled_");delay_bind_init_one("tcp_qs_recovery_");delay_bind_init_one("qs_request_mode_");delay_bind_init_one("qs_thresh_");delay_bind_init_one("qs_rtt_");delay_bind_init_one("frto_enabled_");delay_bind_init_one("sfrto_enabled_");delay_bind_init_one("spurious_response_");#ifdefTCP_DELAY_BIND_ALL//outbecausedelay-boundtracevarsaren'tyetsupporteddelay_bind_init_one("t_seqno_");delay_bind_init_one("rtt_");delay_bind_init_one("srtt_");delay_bind_init_one("rttvar_");delay_bind_init_one("backoff_");delay_bind_init_one("dupacks_");delay_bind_init_one("seqno_");delay_bind_init_one("ack_");delay_bind_init_one("cwnd_");delay_bind_init_one("ssthresh_");delay_bind_init_one("maxseq_");delay_bind_init_one("ndatapack_");delay_bind_init_one("ndatabytes_");delay_bind_init_one("nackpack_");delay_bind_init_one("nrexmit_");delay_bind_init_one("nrexmitpack_");delay_bind_init_one("nrexmitbytes_");delay_bind_init_one("necnresponses_");delay_bind_init_one("ncwndcuts_");delay_bind_init_one("ncwndcuts1_");#endif/*TCP_DELAY_BIND_ALL*/delay_bind_init_one("debug_");//addedbysmallkoAgent::delay_bind_init_all();reset();intTcpAgent::delay_bind_dispatch(constchar*varName,constchar*localName,TclObject*tracer){if(delay_bind(varName,localName,"window_",&wnd_,tracer))returnTCL_OK;if(delay_bind(varName,localName,"windowInit_",&wnd_init_,tracer))returnTCL_OK;if(delay_bind(varName,localName,"windowInitOption_",&wnd_init_option_,tracer))returnTCL_OK;if(delay_bind_bool(varName,localName,"syn_",&syn_,tracer))returnTCL_OK;if(delay_bind(varName,localName,"windowOption_",&wnd_option_,tracer))returnTCL_OK;if(delay_bind(varName,localName,"windowConstant_",&wnd_const_,tracer))returnTCL_OK;if(delay_bind(varName,localName,"windowThresh_",&wnd_th_tracer))returnTCL_OK;if(delay_bind_bool(varName,localName,"delay_growth_",&delay_growth_,tracer))returnTCL_OK;if(delay_bind(varName,localName,"overhead_",&overhead_,tracer))returnTCL_OK;if(delay_bind(varName,localName,"tcpTick_",&tcp_tick_,tracer))returnTCL_OK;if(delay_bind_bool(varName,localName,"ecn_",&ecn_,tracer))returnTCL_OK;if(delay_bind_bool(varName,localName,"SetCWRonRetransmit_",&SetCWRonRetransmit_,tracer))returnTCL_OK;if(delay_bind_bool(varName,localName,"old_ecn_",&old_ecn_,tracer))returnTCL_OK;if(delay_bind(varName,localName,"eln_",&eln_,tracer))returnTCL_OK;if(delay_bind(varName,localName,"eln_rxmit_thresh_",&eln_rxmit_thresh_,tracer))returnTCL_OK;if(delay_bind(varName,localName,"packetSize_",&size_,tracer))returnTCL_OK;if(delay_bind(varName,localName,"tcpip_base_hdr_size_",&tcpip_base_hdr_size_,tracer))returnTCL_OK;if(delay_bind(varName,localName,"ts_option_size_",&ts_option_size_,tracer))returnTCL_OK;if(delay_bind_bool(varName,localName,"bugFix_",&bug_fix_tracer))returnTCL_OK;if(delay_bind_bool(varName,localName,"bugFix_ack_",&bugfix_ack_,tracer))returnTCL_OK;

if(delay_bind_bool(varName,localName,"bugFix_ts_",&bugfix_tstracer))returnTCL_OK;"lessCareful_","timestamps_","ts_resetRTO_",if(delay_bind_bool(varName,localName,&less_careful_"lessCareful_","timestamps_","ts_resetRTO_",if(delay_bind_bool(varName,localName,&ts_option_,tracer))returnTCL_OK;if(delay_bind_bool(varName,localName,&ts_resetRTO_,tracer))returnTCL_OK;if(delay_bind_bool(varName,localName,"slow_start_restart&slow_start_restart_,tracer))returnTCL_OK;if(delay_bind_bool(varName,localName,"restart_bugfix_",&restart_bugfix_,tracer))returnTCL_OK;if(delay_bind(varName,localName,"maxburst_",&maxbursttracer))returnTCL_OK;if(delay_bind_bool(varName,localName,"aggressive_maxburst_"&aggressive_maxburst_,tracer))returnTCL_OK;if(delay_bind(varName,localName,"maxcwnd_",&maxcwnd_,tracer))returnTCL_OK;if(delay_bind(varName,localName,"numdupacks_",&numdupacks_,tracer))returnTCL_OK;if(delay_bind(varName,localName,"numdupacksFrac_",&numdupacksFrac_,tracer))returnTCL_OK;if(delay_bind_bool(varName,localName,"exitFastRetrans_",&exitFastRetrans_,tracer))returnTCL_OK;if(delay_bind(varName,localName,"maxrto_",&maxrto_,tracer))returnTCL_OK;if(delay_bind(varName,localName,"minrto_",&minrto_,tracer))returnTCL_OK;if(delay_bind(varName,localName,"srtt_init_",&srtt_init_,tracer))returnTCL_OK;if(delay_bind(varName,localName,"rttvar_init_",&rttvar_init_,tracer))returnTCL_OK;if(delay_bind(varName,localName,"rtxcur_init_",&rtxcur_init_,tracer))returnTCL_OK;if(delay_bind(varName,localName,"T_SRTT_BITS",&T_SRTT_BITS,tracer))returnTCL_OK;if(delay_bind(varName,localName,"T_RTTVAR_BITS",&T_RTTVAR_BITS,tracer))returnTCL_OK;if(delay_bind(varName,localName,"rttvar_exp_",&rttvar_exp_,tracer))returnTCL_OK;if(delay_bind(varName,localName,"awnd_",&awnd_,tracer))〃1〃1〃"decrease_num_",if(delay_bind(varName,localName,&decrease_num_,tracer))returnTCL_OK;if(delay_bind(varName,localName,"increase_num_",&increase_num_,tracer))returnTCL_OK;if(delay_bind(varName,localName,"k_parameter_",&k_parameter_,tracer))returnTCL_OK;if(delay_bind(varName,localName,"l_parameter_",&l_parameter_,tracer))returnTCL_OK;if(delay_bind_bool(varName,localName,"trace_all_oneline_",&trace_all_oneline_,tracer))returnTCL_OK;if(delay_bind_bool(varName,localName,"nam_tracevar_",&nam_tracevar_,tracer))returnTCL_OK;if(delay_bind(varName,localName,"QOption_",&QOption_,tracer))returnTCL_OK;if(delay_bind(varName,localName,"EnblRTTCtr_",&EnblRTTCtr_tracer))returnTCL_OK;if(delay_bind(varName,localName,"control_increase_",&control_increase_,tracer))returnTCL_OK;if(delay_bind_bool(varName,localName,"noFastRetrans_",&noFastRetrans_,tracer))returnTCL_OK;if(delay_bind_bool(varName,localName,"precisionReduce_",&precision_reduce_,tracer))returnTCL_OK;if(delay_bind_bool(varName,localName,"oldCode_",&oldCode_,tracer))returnTCL_OK;if(delay_bind_bool(varName,localName,"useHeaders_",&useHeaders_,tracer))returnTCL_OK;if(delay_bind(varName,localName,"low_window_",&low_window_,tracer))returnTCL_OK;if(delay_bind(varName,localName,"high_window_",&high_window_,tracer))returnTCL_OK;if(delay_bind(varName,localName,"high_p_",&high_p_,tracer))returnTCL_OK;if(delay_bind(varName,localName,"high_decrease_",&high_decrease_,tracer))returnTCL_OK;if(delay_bind(varName,localName,"max_ssthresh_",&max_ssthresh_,tracer))returnTCL_OK;if(delay_bind(varName,localName,"cwnd_range_",&cwnd_range_,tracer))returnTCL_OK;if(delay_bind_bool(varName,localName,"timerfix_",&timerfix_,tracer))returnTCL_OK;if(delay_bind_bool(varName,localName,"rfc2988_",&rfc2988_,tracer))returnTCL_OK;if(delay_bind(varName,localName,"singledup_",&singledup_,tracer))returnTCL_OK;if(delay_bind_bool(varName,localName,"LimTransmitFix_",if(delay_bind_bool(varName,localName,"LimTransmitFix_",&LimTransmitFix_,tracer))returnTCL_OK;if(delay_bind(varName,localName,"rate_request_",&rate_request_,tracer))returnTCL_OK;if(delay_bind(varName,localName,"ssthresh_",&ssthresh_if(delay_bind(varName,localName,"ssthresh_",&ssthresh_,tracer))returnTCL_OK;if(delay_bind(varName,localName,"maxseq_",&maxseq_,tracer))returnTCL_OK;if(delay_bind(varName,localName,"ndatapack_",&ndatapack_,tracer))returnTCL_OK;if(delay_bind_bool(varName,localName,"qs_enabled_",&qs_enabled_,tracer))returnTCL_OK;if(delay_bind_bool(varName,localName,"tcp_qs_recovery_",&tcp_qs_recovery_,tracer))returnTCL_OK;if(delay_bind_bool(varName,localName,"frto_enabled_",&frto_enabled_,tracer))returnTCL_OK;if(delay_bind_bool(varName,localName,"sfrto_enabled_",&sfrto_enabled_,tracer))returnTCL_OK;if(delay_bind_bool(varName,localName,"spurious_response_",&spurious_response_,tracer))returnTCL_OK;#ifdefTCP_DELAY_BIND_ALL//notif(delay-bounddelay-boundtracevarsaren'tyetsupportedif(delay_bind(varName,localName,"t_seqno_",&t_seqno_,tracer))returnTCL_OK;if(delay_bind(varName,localName,"rtt_",&t_rtt_,tracer))returnTCL_OK;if(delay_bind(varName,localName,"srtt_",&t_srtt_,tracer))returnTCL_OK;if(delay_bind(varName,localName,"rttvar_",&t_rttvar_,tracer))returnTCL_OK;if(delay_bind(varName,localName,"backoff_",&t_backoff_,tracer))returnTCL_OK;if(delay_bind(varName,localName,"dupacks_",&dupacks_,tracer))returnTCL_OK;if(delay_bind(varName,localName,"seqno_",&curseq_,tracer))returnTCL_OK;if(delay_bind(varName,localName,"ack_",&highest_ack_,tracer))returnTCL_OK;if(delay_bind(varName,localName,"cwnd_",&cwnd_,tracer))returnTCL_OK;if(delay_bind(varName,localName,"ndatabytes_",&ndatabytes_if(delay_bind(varName,localName,"ndatabytes_",&ndatabytes_,tracer))returnTCL_OK;if(delay_bind(varName,localName,"nackpack_",&nackpack_,tracer))returnTCL_OK;if(delay_bind(varName,localName,"nrexmit_",&nrexmit_,tracer))returnTCL_OK;"nrexmitpack_","nrexmitbytes_",〃〃"necnresponses_",if(delay_bind(varName,localName,&nrexmitpack_"nrexmitpack_","nrexmitbytes_",〃〃"necnresponses_",if(delay_bind(varName,localName,&nrexmitbytes_,tracer))returnTCL_OK;if(delay_bind(varName,localName,&necnresponses_,tracer))returnTCL_OK;if(delay_bind(varName,localName,"ncwndcuts_",&ncwndcutstracer))returnTCL_OK;if(delay_bind(varName,localName,"ncwndcuts1_",&ncwndcuts1tracer))returnTCL_OK;#endifif(delay_bind(varName,localName,"debug_",&debug_,tracer))returnTCL_OK;returnAgent::delay_bind_dispatch(varName,localName,tracer);}#defineTCP_WRK_SIZE512/*Printoutallthetracedvariableswheneveranyoneischanged*/voidTcpAgent::traceAll(){if(!channel_)return;doublecurtime;Scheduler&s=Scheduler::instance();charwrk[TCP_WRK_SIZE];curtime=&s?s.clock():0;snprintf(wrk,TCP_WRK_SIZE,"time:%-8.5fsaddr:%-2dsport:%-2ddaddr:%-2ddport:""%-2dmaxseq:%-4dhiack:%-4dseqno:%-4dcwnd:%-6.3f""ssthresh:%-3ddupacks:%-2drtt:%-6.3fsrtt:%-6.3f""rttvar:%-6.3fbkoff:%-d\n",curtime,addr(),port(),daddr(),dport(),int(maxseq_),int(highest_ack_),int(t_seqno_),double(cwnd_),int(ssthresh_),int(dupacks_),int(t_rtt_)*tcp_tick_,(int(t_srtt_)>>T_SRTT_BITS)*tcp_tick_,int(t_rttvar_)*tcp_tick_/4.0,int(t_backoff_));(void)Tcl_Write(channel_,wrk,-1);}/*Printoutjustthevariablethatismodified*/voidTcpAgent::traceVar(TracedVar*v){if(!channel_)return;doublecurtime;Scheduler&s=Scheduler::instance();charwrk[TCP_WRK_SIZE];curtime=&s?s.clock():0;//XXXcomparingaddressesisfasterthancomparingnamesif(v==&cwnd_)snprintf(wrk,TCP_WRK_SIZE,"%-8.5f%-2d%-2d%-2d%-2d%s%-6.3f\n",curtime,addr(),port(),daddr(),dport(),v->name(),double(*((TracedDouble*)v)));elseif(v==&t_rtt_)snprintf(wrk,TCP_WRK_SIZE,"%-8.5f%-2d%-2d%-2d%-2d%s%-6.3f\n",curtime,addr(),port(),daddr(),dport(),v->name(),int(*((TracedInt*)v))*tcp_tick_);elseif(v==&t_srtt_)snprintf(wrk,TCP_WRK_SIZE,"%-8.5f%-2d%-2d%-2d%-2d%s%-6.3f\n",curtime,addr(),port(),daddr(),dport(),v->name(),(int(*((TracedInt*)v))>>T_SRTT_BITS)*tcp_tick_);elseif(v==&t_rttvar_)snprintf(wrk,TCP_WRK_SIZE,"%-8.5f%-2d%-2d%-2d%-2d%s%-6.3f\n",curtime,addr(),port(),daddr(),dport(),v->name(),int(*((TracedInt*)v))*tcp_tick_/4.0);elsesnprintf(wrk,TCP_WRK_SIZE,"%-8.5f%-2d%-2d%-2d%-2d%s%d\n",curtime,addr(),port(),daddr(),dport(),v->name(),int(*((TracedInt*)v)));(void)Tcl_Write(channel_,wrk,-1);}voidTcpAgent::trace(TracedVar*v){if(nam_tracevar_){Agent::trace(v);}elseif(trace_all_oneline_)traceAll();elsetraceVar(v);}////in1-wayTCP,syn_indicateswearemodeling//aSYNexchangeatthebeginning.Ifthisistrue//andwearedelayinggrowth,thenuseaninitial//windowofone.Ifnot,wedowhateverinitial_window()//saystodo.//voidTcpAgent::set_initial_window()//初始化CWND{if(syn_&&delay_growth_)cwnd_=1.0;//连接开始,初始窗口为1elsecwnd_=initial_window();}voidTcpAgent::reset_qoption(){intnow=(int)(Scheduler::instance().clock()/tcp_tick_+0.5);T_start=now;RTT_count=0;RTT_prev=0;RTT_goodcount=1;F_counting=0;W_timed=-1;F_full=0;Backoffs=0;}//reset()仅被delay_bind_init_all()调用,用于初始化参数voidTcpAgent::reset(){rtt_init();rtt_seq_=-1;/*XXXlookupvariables*/dupacks_=0;curseq_=0;set_initial_window();t_seqno_=0;maxseq_=-1;last_ack_=-1;highest_ack_=-1;ssthresh_=int(wnd_);//wnd_默认为20,SSTHRESH初始也为20if(max_ssthresh_>0&&max_ssthresh_<ssthresh_)ssthresh_=max_ssthresh_;//max_ssthresh_默认为0,表示无卩限wnd_restart_=1.;awnd_=wnd_init_/2.0;recover_=0;closed_=0;last_cwnd_action_=0;boot_time_=Random::uniform(tcp_tick_);//计算RTT时用到,用来模拟系统启动时间(在两个TCP时钟之间)first_decrease_=1;//用于在slowdown。中判断是否第一次减少CWND,=1,是/*W.N.:forremovingpacketsfrompreviousincarnations*/lastreset_=Scheduler::instance().clock();/*Nowthesevariableswillbereset-DebojyotiDutta12thOct'2000*/ndatapack_=0;ndatabytes_=0;nackpack_=0;nrexmitbytes_=0;nrexmit_=0;nrexmitpack_=0;necnresponses_=0;ncwndcuts_=0;ncwndcuts1_=0;if(control_increase_){prev_highest_ack_=highest_ack_;}if(wnd_option_==8){//HighSpeedTCPhstcp_.low_p=1.5/(low_window_*low_window_);doublehighLowWin=log(high_window_)-log(low_window_);doublehighLowP=log(high_p_)-log(hstcp_.low_p);hstcp_.dec1=0.5-log(low_window_)*(high_decrease_-0.5)/highLowWin;hstcp_.dec2=(high_decrease_-0.5)/highLowWin;hstcp_.p1=log(hstcp_.low_p)-log(low_window_)*highLowP/highLowWin;hstcp_.p2=highLowP/highLowWin;}if(QOption_){intnow=(int)(Scheduler::instance().clock()/tcp_tick_+0.5);T_last=now;T_prev=now;W_used=0;if(EnblRTTCtr_){reset_qoption();}}}/*仅在reset()作初始化时调用,reset()又被delay_bind_init_all()调用/**Initializevariablesfortheretransmittimer.*/voidTcpAgent::rtt_init()//初始化RTT、SRTT、RTTVAR、RTXCUR和回退(补偿)因子{t_rtt_=0;t_srtt_=int(srtt_init_/tcp_tick_)<<T_SRTT_BITS;t_rttvar_=int(rttvar_init_/tcp_tick_)<<T_RTTVAR_BITS;t_rtxcur_=rtxcur_init_;//初始化重传定时时间t_backoff_=1;}//由set_rtx_timer()调用rtt_timeout()设定超时值doubleTcpAgent::rtt_timeout()//根据给定的t_rtxcur_(考虑上下限和回退因子){doubletimeout;if(rfc2988_){//按rfc2988的算法,不同处在于2988的minrto要乘回退因子,默认为FALSE//CorrectionfromTomKellytobeRFC2988-compliant,by//clampingminrto_beforeapplyingt_backoff_.if(t_rtxcur_<minrto_)//重传超时值不能小于最小RTOtimeout=minrto_*t_backoff_;//否则按最小值算elsetimeout=t_rtxcur_*t_backoff_;//按给定值RTXCUR算,都要乘回退因子}else{timeout=t_rtxcur_*t_backoff_;if(timeout<minrto_)timeout=minrto_;}if(timeout>maxrto_)//限制最大超时值timeout=maxrto_;if(timeout<2.0*tcp_tick_){//超时值为负则退出,小于2个tcp时钟则为2个tcp时钟if(timeout<0){fprintf(stderr,"TcpAgent:negativeRTO!(%f)\n",timeout);exit(1);}timeout=2.0*tcp_tick_;}return(timeout);}//由newack()调用,再由recv_newack_helper()调用,最终由recv()调用//算得的t_rtxcur_由rtt_timeout()调用,再由set_rtx_timer()调用rtt_timeout设定超时值,set_rtx_timer()主要由output()等调用/*Thishasbeenmodifiedtousethetahoecode.*/voidTcpAgent::rtt_update(doubletao)//更新RTT,将双精度的RTT转化成整数的RTT,由此计算t_rtxcur_//tao为newack()中的now-ts_echo或now-rtt_ts_,相当于未整数化的{doublenow=Scheduler::instance().clock();if(ts_option_)//采用回应时间戳的情况,默认不采用t_rtt_=int(tao/tcp_tick_+0.5);//RTT整数化,+0.5表示不四舍五入,只要有小数,都入。其中tcp_tick—默认为0.01,即RTT的值精确到0.01秒else{//不采用时间戳的情况doublesendtime=now-tao;//计算本端发送该序号的时间sendtime+=boot_time_;//发送时间要加上boot时间,boot时间用于系统模拟启动时间??是个随机数,小于一个tcp嘀哒doubletickoff=fmod(sendtime,tcp_tick_);//取发送时间对tcp_tick—取模的余数,是整数t_rtt_=int((tao+tickoff)/tcp_tick_);//计算不采用时间戳的RTT时间}if(t_rtt_<1)//rtt不能小于一个TCP时钟周期t_rtt_=1;////t_srtt_has3bitstotherightofthebinarypoint//t_rttvar_has2//Thus"t_srtt_>>T_SRTT_BITS"istheactualsrtt,//and"t_srtt_"is8*srtt.//Similarly,"t_rttvar_>>T_RTTVAR_BITS"istheactualrttvar,//and"t_rttvar_"is4*rttvar.//以下计算srtt和varrtt,算法不必关心if(t_srtt_!=0){registershortdelta;delta=t_rtt_-(t_srtt_>>T_SRTT_BITS);//d=(m-a0)if((t_srtt_+=delta)<=0)//srtt的计算:al=7/8a0+1/8mt_srtt_=1;if(delta<0)delta=-delta;delta-=(t_rttvar_>>T_RTTVAR_BITS);if((t_rttvar_+=delta)<=0)//varrtt的计算:var1=3/4var0+1/4|d|t_rttvar_=1;}else{t_srtt_=t_rtt_<<T_SRTT_BITS;//srtt=rttt_rttvar_=t_rtt_<<(T_RTTVAR_BITS-1);//rttvar=rtt/2}////Currentretransmitvalueis//(unscaled)smoothedroundtripestimate//plus2"rttvar_exp_times(unscaled)rttvar.////计算重传超时时间RTO=SRTT+max(G,K*RTTVAR),算法不必关心t_rtxcur_=(((t_rttvar_<<(rttvar_exp_+(T_SRTT_BITS-T_RTTVAR_BITS)))+t_srtt_)>>T_SRTT_BITS)*tcp_tick_;return;}//在reset_rtx_timer()中使用,t_backoff用于在重传超时时对RTO进行翻倍voidTcpAgent::rtt_backoff(){if(t_backoff_<64)/*t_backoff_即RTO补偿因子,初始化为0,启动后为1,最大为64,即最大重传超时时间为:最初的RTO*64*/t_backoff_<<=1;//每次补偿因子*2if(t_backoff_>8){//补偿因子>8,说明重发了3次以上,则对rtt平均偏差和平滑值做出修正/*Ifbackedoffthisfar,clobberthesrttvalue,storingitinthemeandeviationinstead.*/t_rttvar_+=(t_srtt_>>T_SRTT_BITS);t_srtt_=0;}}/*headersize:howbigisanIP+TCPheaderinbytes;includeoptionssuchaststhisfunctionshouldbevirtualsoothers(e.g.SACK)canoverride*/intTcpAgent::headersize()//IP+TCP头大小=基本头大小+时间选项大小{inttotal=tcpip_base_hdr_size_;if(total<1){fprintf(stderr,"TcpAgent(%s):warning:tcpiphdrsizeisonly%dbytes/n",name(),tcpip_base_hdr_size_);}if(ts_option_)total+=ts_option_size_;return(total);}//output()发送单个分组,被send_much、send_one等调用,不直接使用voidTcpAgent::output(intseqno,intreason)//reason表示重发原因,本端不用,传给对端用

{//后面有//记录本分组的字节数//当前将发送的//后面有//记录本分组的字节数//当前将发送的//记录发送当前分组的//当前分组号<以发最highest_ack_==maxseq_时,该值为0Packet*p=allocpkt();hdr_tcp*tcph=hdr_tcp::access(p);hdr_flags*hf=hdr_flags::access(p);hdr_ip*iph=hdr_ip::access(p);intdatabytes=hdr_cmn::access(p)->size();tcph->seqno()=seqno;分组号tcph->ts()=Scheduler::instance().clock();时间戳intis_retransmit=(seqno<maxseq_);大分组号,表示本次是重传该分组//MarkpacketfordiagnosispurposesifweareinQuick-StartPhaseif(qs_approved_){hf->qs()=1;}//storetimestamps,withbugfix_ts_.FromAndreiGurtov.//(ArealTCPwouldusescoreboardforthis.)if(bugfix_ts_&&tss==NULL){tss=(double*)calloc(tss_size_,sizeof(double));if(tss==NULL)exit(1);}//dynamicallygrowthetimestamparrayifit'sgettingfullif(bugfix_ts_&&window()>tss_size_*0.9){double*ntss;ntss=(double*)calloc(tss_size_*2,sizeof(double));printf("resizingtimestamptable/n");if(ntss==NULL)exit(1);for(inti=0;i<tss_size_;i++)ntss[(highest_ack_+i)%(tss_size_*2)]=tss[(highest_ack_+i)%tss_size_];free(tss);tss_size_*=2;tss=ntss;}if(tss!=NULL)tss[seqno%tss_size_]=tcph->ts();tcph->ts_echo()=ts_peer_;//将对方发送的时间戳返回给对方tcph->reason()=reason;//重发的原因传给对方tcph->last_rtt()=int(int(t_rtt_)*tcp_tick_*1000);//将上次的RTT结果传给对方,以毫秒计,只用于统计if(ecn_){//不看hf->ect()=1;//ECN-capabletransport}if(cong_action_&&(!is_retransmit||SetCWRonRetransmit_)){//不看hf->cong_action()=TRUE;cong_action_=FALSE;}/*Checkifthisisif(seqno==0){if(syn_){databytes=0;curseq_+=1;theinitialSYNpacket.*///是否支持第一个分组//是第一个分组,且支持SYN//是SYN分组,则不参加ndatabytes的统计//应用的最大分组数+1hdr_cmn::access(p)->size()=tcpip_base_hdr_size}if(ecn_){hf->ecnecho()=1;//hf->cong_action()=1;hf->ect()=0;}if(qs_enabled_){hdr_qs*qsh=hdr_qs::access(p);//dataoutiskilobytesqueuedforsendingintdataout=(curseq_-maxseq_-1)*(size_+headersize())/1024;intqs_rr=rate_request_;if(qs_request_mode_==1){//PS:AvoidmakingunnecessaryQSrequests//usearoughestimationofRTTinqs_rtt_//tocalculatethedesiredratefromdataout.if(dataout*1000/qs_rtt_<qs_rr){qs_rr=dataout*1000/qs_rtt_;}//qs_thresh_isminimumnumberofunsent//segmentsneededtoactivateQSrequestif((curseq_-maxseq_-1)<qs_thresh_){qs_rr=0;}}if(qs_rr>0){//QuickStartcodefromSrikanthSundarrajan.qsh->flag()=QS_REQUEST;qsh->ttl()=Random::integer(256);}}ttl_diff_=(iph->ttl()-qsh->ttl())%256;qsh->rate()=hdr_qs::Bps_to_rate(qs_rr*1024);qs_requested_=1;}else{qsh->flag()=QS_DISABLE;}}}elseif(useHeaders_==true){//不是第一个分组hdr_cmn::access(p)->size()+=headersize();//计算分组头大小}hdr_cmn::access(p)->size();/*ifnooutstandingdata,besuretosetrtxtimeragain*/if(highest_ack_==maxseq_)//最高的已确认ACK号=最大已发分组号,表示已发送的全都得到了确认,force_set_rtx_timer=1;//该数据肯定为新的未收到ACK的数据,肯定要重新设置重传定时器,原因见后面的“注”/*callhelperfunctiontofillinadditionalfields*/output_helper(p);++ndatapack_;//统计总的发送分组数ndatabytes_+=databytes;//统计总发送字节数send(p,0);//发送该分组if(seqno==curseq_&&seqno>maxseq_)//发送序号=最大允许发送序号,表示已发完idle();//告诉应用程序已经发完数据TellapplicationIhavesenteverythingsofarif(seqno>maxseq_){新发送分组//发送序号>上次最大发送序号,表示是maxseq_=seqno;if(!rtt_active_){//新发送分组,记录最大发送序号//如果上一个RTT样本刚刚收到,rtt_active=l表示正在等待RTT接收样本ACK返回rtt_active_=1;//表示本分组是新的RTT样本,rtt开始新的计算if(seqno>rtt_seq_){//若发送序号〉上次RTT样本号rtt_seq_=seqno;//则本序号是新的RTT样本rtt_ts_=Scheduler::instance().clock();//且记录该样本的发送时间戳}}else{//不是新分组了,则是重传++nrexmitpack_;//统计重传分组数nrexmitbytes_+=databytes;//统计重传字节数if(!(rtx_timer_.status()==TIMER_PENDING)||force_set_rtx_timer)/*TIMER_PENDING表示超时重传定时器在等待状态,即对定时器定时的分组号尚未收到ACK,若该分组的ACK刚刚收到,或在强制重传定时器的情况时,对重传定时器重新设定超时*//*Notimerpending.Scheduleone.*/set_rtx_timer();}/*重传定时的原理:只设定一个重传定时器,对每一个发送的分组号,设为A,设为检查定时器是否已经在用,若没有用,则设定该定时器,此时该定时器对应该分组号;若在用,则不修改,继续传该分组。收到对方对分组A的确认ACK,则将重新设定定时器,到下一个分组号A+1,此时定时器对应A+1分组;以后,每收到一个新确认,都将定时器对应到该分组号+1。即每次都对第一个未被确认的分组进行监控,保证此分组一旦得不到确认就超时。*//*Mustconvertbytesintopacketsforone-wayTCPs.Ifnbytes==-1,thiscorrespondstoinfinitesend.Weapproximate*infinitebyaverylargenumber(TCP_MAXSEQ).*///该程序由上层应用调用,用来产生TCP流,完成tcp连接、传输、结束全过程,而不用管数据具体怎么传输voidTcpAgent::sendmsg(intnbytes,constchar*/*flags*/)//若nbyte=-l,表示发送允许的无限多数据{if(nbytes==-1&&curseq_<=TCP_MAXSEQ)//若无限发送,则确定发送的最大数据量curseq_=TCP_MAXSEQ;elsecurseq_+=(nbytes/size_+(nbytes%size_?1:0));//有限发送,则按字节数计算将发送的总的序列数send_much(0,0,maxburst_);//尽量发送多的数据,直到发送完或连接终止,maxburst_是最大允许发送的数值,默认值0,表示不限数量}voidTcpAgent::advanceby(intdelta){curseq_+=delta;if(delta>0)closed_=0;send_much(0,0,maxburst_);}intTcpAgent::command(intargc,constchar*const*argv){if(argc==3){if(strcmp(argv[1],"advance")==0){intnewseq=atoi(argv[2]);if(newseq>maxseq_)advanceby(newseq-curseq_);elseadvanceby(maxseq_-curseq_);return(TCL_OK);}if(strcmp(argv[1],"advanceby")==0){advanceby(atoi(argv[2]));return(TCL_OK);}if(strcmp(argv[1],"eventtrace")==0){et_=(EventTrace*)TclObject::lookup(argv[2]);return(TCL_OK);}/**CurtisVillamizar'stricktotransfertcpconnection*parameterstoemulatehttppersistentconnections.**Anotherwaytodothesamethingistoopenonetcp*objectandusestart/stop/maxpkts_oradvancebytocontrol*howmuchdataissentineachburst.*Withasingleconnection,slow_start_restart_*shouldbeconfiguredasdesired.**Thisimplementation(persist)maynotcorrectly*emulatepure-BSD-basedsystemswhichclosecwnd*aftertheconnectiongoesidle(slow-start*restart).SeeappendixCinJacobsonandKarelsCongestionAvoidanceandControl''at<HYPERLINK/papers/congavoid.ps.Z>(*not*theoriginal'88paper)forwhyBSDdoesthis.SeePerformanceInteractionsBetweenP—HTTPandTCPImplementations''inCCR27(2)fordescriptionsofwhatothersystemsdothesame.**/if(strcmp(argv[1],"persist")==0){TcpAgent*other=(TcpAgent*)TclObject::lookup(argv[2]);cwnd_=other->cwnd_;awnd_=other->awnd_;ssthresh_=other->ssthresh_;t_rtt_=other->t_rtt_;t_srtt_=other->t_srtt_;t_rttvar_=other->t_rttvar_;t_backoff_=other->t_backoff_;return(TCL_OK);}}return(Agent::command(argc,argv));}/**Returnsthewindowsizeadjustedtoallow<num>segmentspastrecovery*pointtobetransmittedonn

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论