实验二Omnet++停等式ARQ模型仿真实验
一.实验目的
1.熟悉omnet++软件使用。
2.对停等式ARQ模型进行更形象的分析与学习,了解此协议的思想。二.实验工具
Omnet++软件
三.实验步骤
1.用omnet++软件,创建一个arq.ned文件,编写代码,建立两个具有
收发功能的节点并连接,传输延迟设置为100ms。代码如下:
simplesender
{
parameters:
@display("i=block/process");
gates:
inputin;
outputout;
}
simplereciever
{
parameters:
@display("i=block/process");
gates:
inputin;
outputout;
}
networkArq
{
submodules:
sender:sender{
parameters:
@display("i=,cyan");
}
reciever:reciever{
parameters:
@display("i=,gold");
}
connections:
sender.out-->{delay=100ms;}-->reciever.in;
sender.in<--{delay=100ms;}<--reciever.out;
}
图形如下图所示:
2.对停等式ARQ协议进行编程实现。
在发送端设置定时器,当超出一定时间未收到接收端返回的ACK就认为所发message丢失,再次发送相同message。按时接到相对应的ACK后,
定时器重启。
模块声明及初始化代码如下:
classsender:publiccSimpleModule
{
private:
simtime_ttimeout;//timeout
cMessage*timeoutEvent;//holdspointertothetimeoutself-message
intseq;//messagesequencenumber
cMessage*message;//messagethathastobere-sentontimeout
public:
sender();
virtual~sender();
protected:
virtualcMessage*generateNewMessage();
virtualvoidsendCopyOf(cMessage*msg);
virtualvoidinitialize();
virtualvoidhandleMessage(cMessage*msg);
};
Define_Module(sender);
sender::sender()
{
timeoutEvent=message=NULL;
}
sender::~sender()
{
cancelAndDelete(timeoutEvent);
deletemessage;
}
voidsender::initialize()
{
//Initializevariables.
seq=0;
timeout=1.0;
timeoutEvent=newcMessage("timeoutEvent");
//Generateandsendinitialmessage.
EV<<"Sendinginitialmessage\n";
message=generateNewMessage();
sendCopyOf(message);
scheduleAt(simTime()+timeout,timeoutEvent);
}
我们在设定发送端sender的时候,考虑到如果接收端reciever没有接到,sender的上一个message不能被清除,则规定接到相对应的ACK
后,
将刚刚发送的message清除,否则重发。
发送端规则及对message编号的代码如下:
voidsender::handleMessage(cMessage*msg)
{
if(msg==timeoutEvent)
{
//Ifwereceivethetimeoutevent,thatmeansthepackethasn't
//arrivedintimeandwehavetore-sendit.
EV<<"Timeoutexpired,resendingmessageandrestartingtimer\n";
sendCopyOf(message);
scheduleAt(simTime()+timeout,timeoutEvent);
}
else//messagearrived
{
//Acknowledgementreceived!
EV<<"Received:"<
deletemsg;
//Alsodeletethestoredmessageandcancelthetimeoutevent.
EV<<"Timercancelled.\n";
cancelEvent(timeoutEvent);
deletemessage;
//Readytosendanotherone.
message=generateNewMessage();
sendCopyOf(message);
scheduleAt(simTime()+timeout,timeoutEvent);
}
}
cMessage*sender::generateNewMessage()
{
//Generateamessagewithadifferentnameeverytime.
charmsgname[20];
sprintf(msgname,"send-%d",++seq);
cMessage*msg=newcMessage(msgname);
returnmsg;
}
在接收端我们需要做的就是将丢包情况考虑进去,设置随机丢包的情况。如果message丢失,那么打印出丢失的字样,收到message,就返回
一个相同编号的ACK。
代码如下:
classreciever:publiccSimpleModule
{
protected:
virtualvoidhandleMessage(cMessage*msg);
};
Define_Module(reciever);
voidreciever::handleMessage(cMessage*msg)
{
if(uniform(0,1)<0.1)
{
EV<<"\"Losing\"message"< bubble("messagelost"); deletemsg; } else { EV< deletemsg; send(newcMessage("ack"),"out"); } } 3.运行仿真程序并记录结果。 4.对实验结果进行分析总结。 实验结果及分析 这是13号message发送的全过程,包被接收端接收后,将接到一个ACK,然后定时器重启。 如果包丢失,则会出现如下图的情况: 发送端收到ACK时间超时,认为数据丢失,再次发送send—16,直到收到ACK为止。 在停等式ARQ中,数据报文发送完成之后,发送方等待接收方的状态报告,如果状态报告报文发送成功,发送后续的数据报文,否则重传该报文。 停等式ARQ,发送窗口和接收窗口大小均为1,发送方每发送一帧之后就必须停下来等待接收方的确认返回,仅当接收方确认正确接收后再继续发送下一帧。该方法所需要的缓冲存储空间最小,缺点是信道效率很低。但它对后续的高级ARQ协议有着指导意义。