-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSRRdtSender.cpp
170 lines (138 loc) · 4.51 KB
/
SRRdtSender.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
#include "stdafx.h"
#include "Global.h"
#include "SRRdtSender.h"
SRRdtSender::SRRdtSender() :WindowsSize(4), SeqSize(8), expectSequenceNumberSend(0), waitingState(false), base(0)
{
//PackWindow = std::vector<Packet>(WindowsSize);
file.open("SRwindows1.txt",ofstream::out);
}
SRRdtSender::~SRRdtSender()
{}
bool SRRdtSender::send(Message &message)
{
if (waitingState)
{
Packet ErrorPacket;
memcpy(ErrorPacket.payload, message.data, sizeof(message.data));
pUtils->printPacket("\n发送错误", ErrorPacket);
return false;
}
this->packetWaitingAck.acknum = expectSequenceNumberSend; //忽略该字段
this->packetWaitingAck.seqnum = this->expectSequenceNumberSend;
this->packetWaitingAck.checksum = 0;
memcpy(this->packetWaitingAck.payload, message.data, sizeof(message.data));
this->packetWaitingAck.checksum = pUtils->calculateCheckSum(this->packetWaitingAck);
pUtils->printPacket("发送方发送报文", this->packetWaitingAck);
pns->startTimer(SENDER, Configuration::TIME_OUT, this->packetWaitingAck.seqnum); //启动发送方定时器
pns->sendToNetworkLayer(RECEIVER, this->packetWaitingAck); //调用模拟网络环境的sendToNetworkLayer,通过网络层发送到对方
PacketWindows.push_back(packetWaitingAck);
AckWindows.push_back(0);
streambuf *backup;
backup = cout.rdbuf(); // back up cin's streambuf
cout.rdbuf(file.rdbuf()); // assign file's streambuf to cin
// ... cin will read from file
cout << "发送方发送分组:";
packetWaitingAck.print();
cout << "窗口内容:\n";
for (int pi = 0; pi < PacketWindows.size(); ++pi)
{
cout << "序号:" << PacketWindows[pi].seqnum << " ";
PacketWindows[pi].print();
}
cout << "\n";
cout.rdbuf(backup);
//if (base == expectSequenceNumberSend)
// pns->startTimer(SENDER, Configuration::TIME_OUT, this->packetWaitingAck.seqnum); //重新启动发送方定时器
expectSequenceNumberSend = (expectSequenceNumberSend + 1) % SeqSize;
if ((int)PacketWindows.size() == WindowsSize)
waitingState = true;
return true;
}
//接受确认Ack,将被NetworkServiceSimulator调用
void SRRdtSender::receive(Packet &ackPkt)
{
int checkSum = pUtils->calculateCheckSum(ackPkt);
//ackPkt.acknum == this->PacketWindows[0].seqnum
//如果校验和正确,并且确认序号=发送方已发送并等待确认的数据包序号
if (checkSum == ackPkt.checksum)
{
//this->expectSequenceNumberSend = (this->expectSequenceNumberSend) % SeqSize; //下一个发送序号在0-1之间切换
int i;
for (i = 0; i < (int)PacketWindows.size(); ++i)
{
if (PacketWindows[i].seqnum == ackPkt.acknum)
break;
}
//未确认窗口含有该序号
if (i != PacketWindows.size())
{
pUtils->printPacket("发送方正确收到确认", ackPkt);
//该序号未确认
if (AckWindows[i] == 0)
{
pns->stopTimer(SENDER, ackPkt.acknum); //关闭定时器
AckWindows[i] = 1;
if (i == 0)
{
int changeflag = 0;
while (PacketWindows.size()>0)
{
if (AckWindows[0] == 1)
{
PacketWindows.erase(PacketWindows.begin(), PacketWindows.begin() + 1);
AckWindows.erase(AckWindows.begin(), AckWindows.begin() + 1);
base = (ackPkt.acknum + 1) % SeqSize;
changeflag = 1;
}
else
break;
}
if (changeflag == 1)
{
streambuf *backup;
backup = cout.rdbuf(); // back up cin's streambuf
cout.rdbuf(file.rdbuf()); // assign file's streambuf to cin
cout << "发送方收到确认";
ackPkt.print();
cout << "\n发送发窗口移动:剩余" << PacketWindows.size() << "个未确认元素\n";
cout << "剩余元素为:\n";
for (int i = 0; i <(int)PacketWindows.size(); ++i)
{
cout << "序号:" << PacketWindows[i].seqnum << " ";
PacketWindows[i].print();
}
cout << endl;
cout.rdbuf(backup);
}
}
//判断窗口是否满
if (PacketWindows.size() != WindowsSize)
waitingState = false;
}
}
else
pUtils->printPacket("发送方正确收到确认包,但序号错误", ackPkt);
}
else pUtils->printPacket("\n发送方错误收到确认", ackPkt);
}
//Timeout handler,将被NetworkServiceSimulator调用
void SRRdtSender::timeoutHandler(int seqNum)
{
int i;
for (i = 0; i < (int)PacketWindows.size(); ++i)
{
if (PacketWindows[i].seqnum == seqNum)
break;
}
if (i != PacketWindows.size())
{
pUtils->printPacket("发送方定时器时间到,重发超时的报文", PacketWindows[i]);
pns->stopTimer(SENDER, seqNum); //首先关闭定时器
pns->startTimer(SENDER, Configuration::TIME_OUT, seqNum); //重新启动发送方定时器
pns->sendToNetworkLayer(RECEIVER, PacketWindows[i]); //重新发送数据包
}
}
bool SRRdtSender::getWaitingState()
{
return waitingState;
}