From ea830e85bdb562c024ff5e2b0b0b8ddf6acf347d Mon Sep 17 00:00:00 2001 From: "Claudio Maggioni (maggicl)" Date: Thu, 7 May 2020 17:08:12 +0200 Subject: [PATCH] hw2: completed but untested --- hw2/src/GBNTReceiver.java | 65 +++++++++++++++++++++++++++++++++++++-- hw2/src/GBNTSender.java | 9 ++++-- 2 files changed, 69 insertions(+), 5 deletions(-) diff --git a/hw2/src/GBNTReceiver.java b/hw2/src/GBNTReceiver.java index bf3cf83..363f781 100644 --- a/hw2/src/GBNTReceiver.java +++ b/hw2/src/GBNTReceiver.java @@ -2,13 +2,72 @@ import transport.Receiver; import transport.TimeoutAction; public class GBNTReceiver extends Receiver implements TimeoutAction { + + private char sequence; + boolean firstPacket = true; + private static final int RECEIVER_TIMEOUT_MS = 1000; + private State state = State.SETUP; + + enum State { + SETUP, + RECEIVING + } + + private static byte[] generateACK(char sequence) { + byte[] dest = new byte[2]; + dest[0] = (byte) ((sequence >> 8) & 0xFF); + dest[1] = (byte) (sequence & 0xFF); + return dest; + } + + private static char readBigEndianChar(byte[] src, int offset) { + return (char) (src[offset] << 8 + src[offset + 1]); + } + + private static char incrementAndRollover(char c) { + return (char) ((c + 1) % 65536); + } + @Override public void timeoutAction() { - + try { + disconnect(); + } catch (java.lang.InterruptedException ex) { + System.out.println("Thread interrupted. Exiting directly."); + System.exit(0); + } } @Override - protected void unreliableReceive(byte[] bytes, int i, int i1) { - + protected void unreliableReceive(byte[] bytes, int offset, int length) { + switch(this.state) { + case SETUP: + if (length != 2) { + if (firstPacket) return; + else { + state = State.RECEIVING; + this.unreliableReceive(bytes, offset, length); + } + } + sequence = readBigEndianChar(bytes, 0); + unreliableSend(bytes, offset, 2); + firstPacket = false; + break; + case RECEIVING: + if (length == 2) { // if packet is a close packet + if (incrementAndRollover(this.sequence) != readBigEndianChar(bytes, offset)) return; // ignore if not synchronized + this.unreliableSend(bytes, offset, 2); + timeoutAction(); + } + if (length < 3) return; + char seq = readBigEndianChar(bytes, 0); + if (seq != incrementAndRollover(sequence)) return; //drop the packet + else { + this.unreliableReceive(bytes, offset + 2, length); + sequence = incrementAndRollover(sequence); + this.unreliableSend(generateACK(sequence), 0, 2); + } + break; + } } } diff --git a/hw2/src/GBNTSender.java b/hw2/src/GBNTSender.java index 06fa398..612c26c 100644 --- a/hw2/src/GBNTSender.java +++ b/hw2/src/GBNTSender.java @@ -13,6 +13,10 @@ public class GBNTSender extends transport.Sender implements TimeoutAction { return (char) (src[offset] << 8 + src[offset + 1]); } + private static char addAndRollover(char c, char i) { + return (char) ((c + i) % 65536); + } + private static char incrementAndRollover(char c) { return (char) ((c + 1) % 65536); } @@ -57,7 +61,7 @@ public class GBNTSender extends transport.Sender implements TimeoutAction { private static final char W = 10; private char base = (char) (new Random().nextInt() % 65536); private char waitingACK = 0; - private int timeoutMs = 1000; + private int timeoutMs = 500; private double rttEWMA = 0; private double devRttEWMA = 0; @@ -107,7 +111,7 @@ public class GBNTSender extends transport.Sender implements TimeoutAction { protected int reliableSend(byte[] bytes, int offset, int length) { if (state != State.SENDING) throw new IllegalStateException(); - Packet p = new Packet(base, bytes, offset, length); + Packet p = new Packet(addAndRollover(base, waitingACK), bytes, offset, length); waitingACK++; packets.add(p); p.send(); @@ -142,6 +146,7 @@ public class GBNTSender extends transport.Sender implements TimeoutAction { byte[] expected = createSetupPacket(); if (bytes[offset] == expected[0] && bytes[1] == expected[offset + 1]) { state = State.SENDING; + base = incrementAndRollover(base); resumeSender(); } else { sendSetup();