由于网络上面的TCP拥塞控制讲解很多,这里就不多介绍了,大家可以看看其他博主的博客大部分都讲的很清楚,顺便给大家推荐一个视频可以看看。
推荐观看视频:b站TCP拥塞控制讲解视频
下面可以看看我的实验代码,希望不要用于实验提交等等非法用途,仅供参考学习
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<string.h>
#define Network_State_Right 1 //网络状态正常
#define Network_State_Congestion 2 //网络状态拥塞 采用慢开始算法
#define Network_State_Timed_Out 3 //网络状态超时重传(发送三个重复响应) 采用快恢复算法
#define Mss 1 //报文段大小为1kb
int Cwnd=1*Mss; //初始值为1MSS,也就是1kb
int Ssthresh=16*Mss; //慢启动门限一般情况下为cwnd的16倍
int Number_of_transfers=0; //记录当前传输次数
int sum_Data_Mss=0; //记录当前的传输总量,初始值为0
int Init_Data_Mss=0; //需要传输的报文段总量,单位kb
int rwnd=0*Mss; //接受窗口
int Status[1000]; //Status用来记录当前的接收方的接受状态,大小为1000
int i=0; //i用来迭代Status数组
int fmin(int x,int y)
{
return x>y?y:x;
}
/*
由于这里的网络状态无法预测
所以采用了随机数的随机生成
*/
int judge_state_of_the_network()
{
int Probability=rand()%100+1; //让概率是从1-100随机出现 1-80是网络状态正常 80-90是网络状态拥塞 90-100是网络状态超时
if(Probability>=1&&Probability<=80)
{
return Network_State_Right;
}
if(Probability>80&&Probability<=90)
{
return Network_State_Congestion;
}
if(Probability>90&&Probability<=100)
{
return Network_State_Timed_Out;
}
//否则异常程序结束
exit(1);
}
/*
网络传输算法
*/
void Network_Transmission()
{
if(sum_Data_Mss>=Init_Data_Mss)
{
printf("\n\n传输完毕!!!!!!!!!!\n\n");
return;
}
Number_of_transfers++;
sum_Data_Mss+=(Cwnd/Mss)*Mss;
printf("**********************************************\n");
printf("这是第%d次发送方传输,发送报文段大小为%dkb\n",Number_of_transfers,Cwnd);
if(Cwnd<Ssthresh) //如果小于慢开始门限,启动慢开始算法,如果反之,启动拥塞避免算法
{
printf("Cwnd=%d,Ssthresh=%d,Cwnd<Ssthresh,启动慢开始算法,Cwnd加倍\n",Cwnd,Ssthresh);
}else{
printf("Cwnd=%d,Ssthresh=%d,Cwnd>=Ssthresh,启动拥塞避免算法,Cwnd+1\n",Cwnd,Ssthresh);
}
printf("\n\n以下为接收方信息:");
rwnd=Cwnd;
//发送方数据传输完毕,接受方信息返回
int p=judge_state_of_the_network();
if(p==1)
{
if(Cwnd<Ssthresh)
{
Cwnd=((Cwnd/Mss)*2)*Mss;
}else{
Cwnd=((Cwnd/Mss)+1)*Mss;
}
Status[i]=p;
printf("接受方返回信息正常\n");
}
if(p==2)
{
printf("网络发生堵塞,接受方接受异常,接收方返回信息为:null\n");
Status[i]=p;
sum_Data_Mss-=(Cwnd/Mss)*Mss;
rwnd=0;
//网络堵塞,传统的将Ssthresh变为Cwnd的一半,并且将Cwnd变成1*Mss,之后采用慢开始算法
Ssthresh=((Cwnd/Mss)/2)*Mss;
Cwnd=1*Mss;
}
if(p==3)
{
printf("网络发生超时重传,接收方返回信息存在三次重复响应\n");
Status[i]=p;
//由于网络异常发生超时重传,采用快恢复算法
Ssthresh=(Cwnd/Mss)/2*Mss;
Cwnd=Ssthresh;
}
printf("这次接受:%dkb,现在已经接受:%dkb,目标大小为:%dkb",rwnd,fmin(sum_Data_Mss,Init_Data_Mss),Init_Data_Mss);
printf("\n\n");
i++;
//递归循环直到传输完全
Network_Transmission();
}
int main()
{
srand((unsigned)time(NULL)); //调用种子函数使每次的随机数不一样
//初始化需要用到的数组
memset(Status,0,sizeof(Status));
printf("请输入需要网络传输的报文段大小,单位为kb(建议大小为100-1000):");
scanf("%d",&Init_Data_Mss);
Network_Transmission();
printf("以下是状态信息:\n");
int k=1;
for(int j=1;j<=Number_of_transfers;j++)
{
if(Status[j]==1)
{
printf("%d ",k);
k++;
}else if(Status[j]==2)
{
printf("拥塞 ");
}else if(Status[j]==3)
{
printf("%d %d %d %d %d ",k,k,k,k,k+1);
k+=4;
j++;
}
}
return 0;
}
关于代码的详细说明再代码处就已经做了说明,可以看看运行结果