基本要求
滑动窗口协议以基于分组的数据传输协议为特征,该协议适用于在数据链路层以及传输层中对按
顺序传送分组的可靠性要求较高的环境。在长管道传输过程(特别是无线环境)中,相应的滑动窗口协议可实现高效的重传恢复。
Frame.java
class Frame {
int sequenceNumber;
Frame(int sequenceNumber) {
this.sequenceNumber = sequenceNumber;
}
}
SlidingWindowSimulation.java
class SlidingWindow { private Queue<Frame> sentFrames; private int windowSize; private int base; private int nextSequenceNumber; private final int maxSequenceNumber; private boolean[] ackReceived; SlidingWindow(int windowSize, int maxSequenceNumber) { this.windowSize = windowSize; this.maxSequenceNumber = maxSequenceNumber; this.sentFrames = new LinkedList<>(); this.ackReceived = new boolean[maxSequenceNumber]; this.base = 0; this.nextSequenceNumber = 0; } public void sendFrame() { if (nextSequenceNumber < base + windowSize && nextSequenceNumber < maxSequenceNumber) { Frame frame = new Frame(nextSequenceNumber); sentFrames.add(frame); ackReceived[nextSequenceNumber] = false; System.out.println("Sent Frame: " + frame.sequenceNumber); nextSequenceNumber++; } else { System.out.println("Window is full or sequence number limit reached."); } } public void receiveAck(int ackNumber) { if (ackNumber < maxSequenceNumber) { ackReceived[ackNumber] = true; System.out.println("Received ACK for Frame: " + ackNumber); while (!sentFrames.isEmpty() && ackReceived[sentFrames.peek().sequenceNumber]) { sentFrames.remove(); base++; } } } public void retransmitFrame() { for (Frame frame : sentFrames) { System.out.println("Retransmitting Frame: " + frame.sequenceNumber); } } public void printStatus() { System.out.println("Current Window: " + base + " to " + (base + windowSize - 1)); System.out.println("Frames in Window: "); for (Frame frame : sentFrames) { System.out.println("Frame " + frame.sequenceNumber + ", ACK received: " + ackReceived[frame.sequenceNumber]); } } }
SlidingWindowSimulation.java
public class SlidingWindowSimulation {
public static void main(String[] args) throws InterruptedException {
int windowSize = 4;
int maxSequenceNumber = 10;
SlidingWindow slidingWindow = new SlidingWindow(windowSize, maxSequenceNumber);
// Simulate sending frames
for (int i = 0; i < 8; i++) {
slidingWindow.sendFrame();
Thread.sleep(500); // Simulate time delay
}
slidingWindow.printStatus();
// Simulate receiving acknowledgements
slidingWindow.receiveAck(2);
slidingWindow.receiveAck(3);
Thread.sleep(500);
slidingWindow.printStatus();
// Simulate frame loss and retransmission
slidingWindow.retransmitFrame();
slidingWindow.printStatus();
}
}
完整代码
import java.util.LinkedList;
import java.util.Queue;
class Frame {
int sequenceNumber;
Frame(int sequenceNumber) {
this.sequenceNumber = sequenceNumber;
}
}
class SlidingWindow {
private Queue<Frame> sentFrames;
private int windowSize;
private int base;
private int nextSequenceNumber;
private final int maxSequenceNumber;
private boolean[] ackReceived;
SlidingWindow(int windowSize, int maxSequenceNumber) {
this.windowSize = windowSize;
this.maxSequenceNumber = maxSequenceNumber;
this.sentFrames = new LinkedList<>();
this.ackReceived = new boolean[maxSequenceNumber];
this.base = 0;
this.nextSequenceNumber = 0;
}
public void sendFrame() {
if (nextSequenceNumber < base + windowSize && nextSequenceNumber < maxSequenceNumber) {
Frame frame = new Frame(nextSequenceNumber);
sentFrames.add(frame);
ackReceived[nextSequenceNumber] = false;
System.out.println("Sent Frame: " + frame.sequenceNumber);
nextSequenceNumber++;
} else {
System.out.println("Window is full or sequence number limit reached.");
}
}
public void receiveAck(int ackNumber) {
if (ackNumber < maxSequenceNumber) {
ackReceived[ackNumber] = true;
System.out.println("Received ACK for Frame: " + ackNumber);
while (!sentFrames.isEmpty() && ackReceived[sentFrames.peek().sequenceNumber]) {
sentFrames.remove();
base++;
}
}
}
public void retransmitFrame() {
for (Frame frame : sentFrames) {
System.out.println("Retransmitting Frame: " + frame.sequenceNumber);
}
}
public void printStatus() {
System.out.println("Current Window: " + base + " to " + (base + windowSize - 1));
System.out.println("Frames in Window: ");
for (Frame frame : sentFrames) {
System.out.println("Frame " + frame.sequenceNumber + ", ACK received: " + ackReceived[frame.sequenceNumber]);
}
}
}
public class SlidingWindowSimulation {
public static void main(String[] args) throws InterruptedException {
int windowSize = 4;
int maxSequenceNumber = 10;
SlidingWindow slidingWindow = new SlidingWindow(windowSize, maxSequenceNumber);
// Simulate sending frames
for (int i = 0; i < 8; i++) {
slidingWindow.sendFrame();
Thread.sleep(500); // Simulate time delay
}
slidingWindow.printStatus();
// Simulate receiving acknowledgements
slidingWindow.receiveAck(2);
slidingWindow.receiveAck(3);
Thread.sleep(500);
slidingWindow.printStatus();
// Simulate frame loss and retransmission
slidingWindow.retransmitFrame();
slidingWindow.printStatus();
}
}
运行结果