0% found this document useful (0 votes)
4 views7 pages

GOBACKN

The document contains the implementation of a Go-Back-N ARQ protocol in OMNeT++ using two modules: Tic (sender) and Toc (receiver). The Tic module handles message generation, sending, and retransmission upon timeout, while the Toc module manages message reception, acknowledgment, and potential message loss. The configuration files define the network structure and parameters for the simulation, including window size and data rates.

Uploaded by

mlin41088
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
4 views7 pages

GOBACKN

The document contains the implementation of a Go-Back-N ARQ protocol in OMNeT++ using two modules: Tic (sender) and Toc (receiver). The Tic module handles message generation, sending, and retransmission upon timeout, while the Toc module manages message reception, acknowledgment, and potential message loss. The configuration files define the network structure and parameters for the simulation, including window size and data rates.

Uploaded by

mlin41088
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 7

// Sender.

cc (Tic)
#include<stdio.h>
#include<string.h>
#include<omnetpp.h>

using namespace omnetpp;

class Tic: public cSimpleModule


{
private:
simtime_t timeout;
cMessage *timeoutEvent;
int counter = 3;
int init_msg_flag = 0;
int seq_count = 0;
int win_size = 0;
int N = 0;
std::vector<int> unacknowledged_packets; // 存储未确认的数据包序列号
public:
Tic();
virtual ~Tic();
protected:
void generateMessage();
void sendMessage(cMessage *msg);
void receivedMessage(cMessage *msg);
void initialize() override;
void handleMessage(cMessage *msg) override;
};

Define_Module(Tic);

Tic::Tic()
{
timeoutEvent = nullptr;
}

Tic::~Tic()
{
cancelAndDelete(timeoutEvent);
}
void Tic:: initialize() {
timeout = 5.0;
timeoutEvent = new cMessage("timeoutEvent");
generateMessage();
EV << "start timer\n";
scheduleAt(simTime()+timeout, timeoutEvent);
}

void Tic:: handleMessage(cMessage *msg) {

if(msg == timeoutEvent) {
if(counter) {
counter --;
EV << "Timeout expired re-sending message\n";
bubble("retransmission");
generateMessage(); // 重发所有未确认的数据包
scheduleAt(simTime()+timeout, timeoutEvent);
} else {
EV << "No response from toc Exiting the program\n";
}
} else {
receivedMessage(msg);
EV << "timer cancelled";
cancelEvent(timeoutEvent);
counter = 3;
generateMessage();
scheduleAt(simTime()+timeout, timeoutEvent);
}
}

void Tic::generateMessage()
{
char msgname[20];
if(!init_msg_flag) { // 发送初始消息获取窗口大小
init_msg_flag = 1;
strcpy(msgname, "init_packet");
cMessage *msg = new cMessage(msgname);
msg->addPar("seq_no");
msg->par("seq_no").setLongValue(seq_count);
sendMessage(msg);
} else { // 开始数据包传输
for(int i = 0; i < win_size; i++) {
cMessage *msg = new cMessage("Packet from tic");
seq_count = (seq_count + 1) % 256;
msg->addPar("seq_no");
msg->par("seq_no").setLongValue(seq_count);
sendMessage(msg);
unacknowledged_packets.push_back(seq_count);

if (seq_count >= 255) {


seq_count = 0;
}
}
}
return;
}

void Tic::sendMessage(cMessage *msg) {


send(msg, "out");
}

void Tic::receivedMessage(cMessage *msg) {


if(msg->par("ack_no").longValue() == 0) {
// 设置窗口大小
EV << "Message received from: " << msg->getName() << "\n" <<
"ackno = " << msg->par("ack_no").longValue() << "\n";
win_size = msg->par("win_size").longValue();
delete msg;
} else {
EV << "Message received from: " << msg->getName() << "\n" <<
"ackno = " << msg->par("ack_no").longValue() << "\n";
int ack_no = msg->par("ack_no").longValue();

// 删除已确认的包
unacknowledged_packets.erase(std::remove(unacknowledged_packets.b
egin(), unacknowledged_packets.end(), ack_no),
unacknowledged_packets.end());

seq_count = ack_no;
if (seq_count >= 255) {
seq_count = 0;
}
delete msg;
}
}

// Receiver.cc (Toc)
#include<stdio.h>
#include<string.h>
#include<omnetpp.h>
using namespace omnetpp;

class Toc: public cSimpleModule


{
private:
cQueue buffer;
int counter = 0;
int seq_count = 0;
int seq_count_copy = 0;
int window = 0;
int init_msg_flag = 0;
int lost_pkt_flag = 0;
int multiple_lost_pkt_flag = 1;
int repeat_seq_flag = 0;
double loss_rate;
protected:
void handleMessage(cMessage *msg) override;
void generateMessage();
void receivedMessage(cMessage *msg);
void sendMessage(cMessage *msg);
void initialize() override;
};

Define_Module(Toc);

void Toc::initialize() {
loss_rate = exponential(0.1); // 使用指数分布生成丢包率
}

void Toc:: handleMessage(cMessage *msg) {

if (uniform(0, 1) < loss_rate) {


EV << "Losing message\n";
bubble("message lost");

lost_pkt_flag = 1;
delete msg;
} else {
receivedMessage(msg);
generateMessage();
}
}

void Toc:: generateMessage()


{
char msgname[20];
cMessage *msg;

if(!init_msg_flag) { // 生成初始消息并发送窗口大小
strcpy(msgname, "Init_toc_msg");
init_msg_flag = 1;

msg = new cMessage(msgname);


msg->addPar("ack_no");
msg->addPar("win_size");
msg->par("ack_no").setLongValue(seq_count);
msg->par("win_size").setLongValue(window);
send(msg, "out");
} else {
// 根据情况发送 RR 或 RNR 消息
if (buffer.getLength() < window) {
strcpy(msgname, "RR_message");
} else {
strcpy(msgname, "RNR_message");
}
sendMessage(msg);
}
}

void Toc::sendMessage(cMessage *msg) {


msg->addPar("ack_no");
msg->par("ack_no").setLongValue(seq_count);
send(msg, "out");
}

void Toc::receivedMessage(cMessage *msg)


{
if(msg->par("seq_no").longValue() == 0) {
// 设置窗口大小
EV << "'Message received from: " << msg->getName() << "\n";
window = par("win_size");
delete msg;
} else {
// 接收数据包
EV << "'Message received from: " << msg->getName() << "\n";
seq_count_copy = msg->par("seq_no").longValue();

if (buffer.getLength() < window) {


buffer.insert(msg);
seq_count = seq_count_copy;
} else {
EV << "Buffer full, discarding packet\n";
delete msg;
}

if (seq_count_copy == 1 && repeat_seq_flag) {


repeat_seq_flag = 0;
seq_count = 0;
}
}
}

GoBackN.ned
simple Tic
{
parameters:
@display("i=block/routing");
//volatile int data_rate @unit(Mbps);
gates:
input in;
output out;
}

simple Toc
{
parameters:
@display("i=block/routing");
int win_size;
int N;
gates:
input in;
output out;
}

network Tictoc
{
@display("bgb=298,347");
submodules:
tic: Tic {
@display("i=,cyan;p=75,72");
}
toc: Toc {
@display("i=,gold;p=208,185");
}
connections:
tic.out -->{ delay = 100ms; datarate = 100Mbps; }--> toc.in;
tic.in <-- { delay = 100ms; datarate = 100Mbps; }<-- toc.out;
}

GoBackN.ini
[General]
network = Tictoc
**.win_size = 4

You might also like