%选择重传ARQ
clear
FrameNum=1e2;%帧数
FrameLength=10;%帧长
FrameOrder=0;%帧号
FrameOrderBuff=0;%帧号缓存
ACK=[0 0];%ACK的组成为 第1位帧号,第2位传输有效位,第2位等于1时表示该帧发送正确,等于0是表示发送错误需要重传
ACKQueue=zeros(5,3);%每行代表一组ACK数据,第1位是数据有效位,第2,3位为ACK数据;列数为队列长度
MaxARQNum=4;%最大重传次数
ARQNum=zeros(FrameNum,2);ARQNum(:,1)=1:FrameNum;%每一帧实际重传次数
FrameError=0;%误帧数
for i=1:3%压入3个空帧,表示2个帧传输时延
ACKQueue=QueueIn(ACKQueue,[0,1]);
end
FrameQueue=zeros(20,2+FrameLength);%每行代表一组帧数据,第1位是数据有效位,第2位为帧号,剩下是帧数据;列数为队列长度
while(1)
%%发送端
[ACKQueue,ACK]=QueueOut(ACKQueue);
FrameBuff=QueueData(FrameQueue,1);%帧号+帧
if(ACK(1)==FrameBuff(1))
[FrameQueue,FrameBuff]=QueueOut(FrameQueue);%读取缓存队列头部数据,并将头部数据退出队列
end
if(ACK(2)==1 && FrameOrderBuff<FrameNum) %该帧传输正确,发送下一帧
FrameOrder=FrameOrderBuff+1;
FrameOrderBuff=FrameOrder;
TrSeq=[1 0 1 0 1 1 1 0 0 1];
FrameQueue=QueueIn(FrameQueue,[FrameOrder TrSeq]);%将新生成的帧数据加入缓存队列
elseif(ACK(2)==0)%该帧传输错误,重传该帧
FrameOrder=FrameBuff(1);
TrSeq=FrameBuff(2:end);
FrameQueue=QueueIn(FrameQueue,FrameBuff);%将该帧重新加入缓存队列
elseif(ACK(2)==1 && FrameOrderBuff==FrameNum)
ACKDeep=QueueDeep(ACKQueue);
if ACKDeep==sum(ACKQueue(:,3)) %ACK队列中的所指示的帧全部发送正确
break; %退出循环
else
while(1)
[ACKQueue,ACK]=QueueOut(ACKQueue);
[FrameQueue,FrameBuff]=QueueOut(FrameQueue);
if ACK(2)==0 %寻找ACK队列中传错的那一帧的信息
break;
end
end
TrSeq=FrameBuff(2:end);
FrameQueue=QueueIn(FrameQueue,FrameBuff);%将该帧重新加入缓存队列
end
end
%%信道简易模型
ReSeq=TrSeq;
ReSeq(1)=randi([0 1],1,1);
%%接收端
if(isequal(ReSeq,TrSeq))
ACK=[FrameOrder 1];
else
if(ARQNum(FrameOrder,2)==MaxARQNum)%重传数达到最大次数则不再重传
FrameError=FrameError+1;%记为误帧数加1
ACK=[FrameOrder 1];
else
ACK=[FrameOrder 0];
ARQNum(FrameOrder,2)=ARQNum(FrameOrder,2)+1;
end
end
%%将ACK重传至发送端
ACKQueue=QueueIn(ACKQueue,ACK);
end