public class SlidingWindowReceiverBsp { /* Buffer for packet data. */ Object[] buf; /* Receiver window size. */ int rws; /* Sender window size. */ int sws; /* Range of sequence numbers: Sequence numbers s * with 0 <= s < seqNrRange are valid. */ int seqNrRange; /* Sequence number of the next frame expected. */ int nfe = 0; /* Buffer index at which the nfe-Paket is (or will be) stored. */ int nfeIndex = 0; /* Create a sliding window receiver with the specified window sizes * and sequence number range. */ public SlidingWindowReceiverBsp(int rws, int sws, int snr) { this.rws = rws; this.sws = sws; seqNrRange = snr; buf = new Object[rws]; } private int nextBufferIndex(int index) { return (index + 1) % rws; } private int nextSeqNr(int seqNr) { return (seqNr + 1) % seqNrRange; } /* Return the next packet in sequence. If no packet is available, * null will be returned. This method is called by the layer above. */ public Object getNextPacket() { if (buf[nfeIndex] != null) { // There is a packet at nfeIndex. Object data = buf[nfeIndex]; buf[nfeIndex] = null; // Free its slot. nfe = nextSeqNr(nfe); // Next nfe sequence number. nfeIndex = nextBufferIndex(nfeIndex); // Next nfe index. return data; } else { return null; } } /* Handle a packet delivered by the layer below. Return the * sequence number of the acknowledgement to be sent back. If no * acknowledgement is to be sent, return -1. */ public int handlePacket(int seqNr, Object data) { if (seqNr < 0 || seqNr >= seqNrRange) { // Sequence number out of range. // Do not store packet. Do not send an ACK. return -1; } int diff = (seqNr + seqNrRange - nfe) % seqNrRange; if (diff < rws) { // "Present" packet (inside receiver window) // convert sequence number to buffer index int sIndex = (diff + nfeIndex) % rws; // Store data and send ACK. buf[sIndex] = data; // store data return seqNr; // return sequence number for ACK. } else if (diff < rws + sws) { // "Future" packet (right of receiver window) // Do not store data. Do not send an ACK. return -1; } else { // "Past" packet (left of receiver window) // Packet already received. Just send ACK. return seqNr; } } private int step = 0; public String show() { step++; String s = (step<10? " ":"") + step + ": "; for (int i = 0; i < rws; i++) { s = s + ((i == nfeIndex)? "|" : " "); int seqNr = (((i + rws - nfeIndex) % rws) + nfe) % seqNrRange; if (buf[i] != null) { s = s + (seqNr<10? " [":"[") + seqNr + "] "; } else { s = s + " . "; } } return s; } }