-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgbnExample.java
More file actions
151 lines (133 loc) · 3.6 KB
/
gbnExample.java
File metadata and controls
151 lines (133 loc) · 3.6 KB
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
/**
* A go-back n type sliding window protocol
*/
//https://www.macs.hw.ac.uk/~pjbk/nets/GoBackN.java
public class GoBackN
extends datalink.Protocol
{
int nextBufferToSend; // buffer to be sent when channel is idle
int firstFreeBufferIndex; // buffer in which to store next packet
int nextSequenceNumberExpected; // sequence number expected
int firstUnAcknowledged; // last unacknowledged frame
final int maximumSequenceNumber;
int numberOfPacketsStored;
final int windowSize;
datalink.Packet[] buffer;
double timer;
public GoBackN(int windowSize, double timer)
{
super( windowSize, timer);
numberOfPacketsStored = 0;
nextBufferToSend = 0;
firstFreeBufferIndex= 0;
nextSequenceNumberExpected = 0;
firstUnAcknowledged = 0;
maximumSequenceNumber = windowSize;
this.windowSize = windowSize;
this.timer = timer;
buffer = new datalink.Packet[windowSize+1];
}
public void FrameArrival( Object frame)
{
DataFrame f = (DataFrame) frame;
// a frame has arrived from the physical layer
// check that it is the one that is expected
if (f.sequenceNumber == nextSequenceNumberExpected)
{
sendPacket(f.info); // valid frame, so send it
// to the network layer
nextSequenceNumberExpected = inc( nextSequenceNumberExpected);
}
// if frame n is ACKed then that implies n-1, n-2 etc
// have also been
// ACKed, so stop associated timers.
while ( between( firstUnAcknowledged,
f.acknowledgment,
nextBufferToSend) )
{
numberOfPacketsStored--;
stopTimer(firstUnAcknowledged);
firstUnAcknowledged = inc( firstUnAcknowledged);
}
if ( numberOfPacketsStored < windowSize )
enableNetworkLayer();
}
public void PacketArrival( datalink.Packet p)
{
buffer[firstFreeBufferIndex] = p;
numberOfPacketsStored++; // buffer packet
if ( numberOfPacketsStored >= windowSize )
disableNetworkLayer();
if ( isChannelIdle() )
{
transmit_frame( nextBufferToSend);
nextBufferToSend = inc( nextBufferToSend);
}
firstFreeBufferIndex = inc( firstFreeBufferIndex);
}
public void TimeOut( int code)
{
int seq = inc(code);
while ( seq != nextBufferToSend )
{ // cancel outstanding timers
stopTimer(seq);
seq = inc( seq);
}
nextBufferToSend = firstUnAcknowledged;
if ( isChannelIdle() )
{
transmit_frame( nextBufferToSend);
nextBufferToSend = inc( nextBufferToSend);
}
}
public void CheckSumError()
{
}
public void ChannelIdle()
{
if ( nextBufferToSend != firstFreeBufferIndex )
{
transmit_frame( nextBufferToSend);
nextBufferToSend = inc( nextBufferToSend);
}
}
private boolean between( int a, int b, int c)
{ // calculate if a<=b<c circularly
if(((a<=b) && (b<c))
|| ((c<a) && (a<=b))
|| ((b<c) && (c<a)))
return true;
else
return false;
}
private int inc ( int a)
{ // increment modulo maximum_sequence_number + 1
a++;
a %= maximumSequenceNumber+1;
return a;
}
private void transmit_frame( int sequenceNumber)
{
int acknowledgement;
// piggyback acknowledge of last frame receieved
acknowledgement = (nextSequenceNumberExpected+maximumSequenceNumber)
% (maximumSequenceNumber+1);
// send it to physical layer
sendFrame( new DataFrame( sequenceNumber,
acknowledgement,
buffer[sequenceNumber]));
startTimer( sequenceNumber, timer);
}
}
class DataFrame
{ /* frame structure */
int sequenceNumber;
int acknowledgment;
datalink.Packet info;
DataFrame ( int s, int a, datalink.Packet p)
{
info = p;
sequenceNumber = s;
acknowledgment = a;
}
}