//----------------------------------------------------------------- // CSE 461 Project 1: Provided client code // // receiver.java: implementation of the receiver algorithm //----------------------------------------------------------------- import java.io.*; import java.util.*; //----------------------------------------------------------------- // Project1Receiver // // Provided implementation shows stop-and-wait protocol, // plus all the general setup and use of the SendBuffer // // This implementation uses both the ReceiveBuffer and // NetworkInterface classes. You are not required to use // these, but they simplify interaction with the timer and // the underlying network. If you want to modify or replace // them, be sure to understand them first. //----------------------------------------------------------------- class Project1Receiver implements PacketReceiver { // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Standard constructor for a node. Takes the global timer, // the link to receive from, and the address of this node. // Sets up the receive buffer, you will probably have to adjust // the size. // // This constructor also sets up a new NetworkInterface // object to buffer between the send algorithm and the actual // transmission delays on the network // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - public Project1Receiver (Timer timer, Link link, Address address) { this.timer = timer; this.address = address; buffer = new ReceiveBuffer (timer, 50 * link.MTU ()); network = new NetworkInterface (timer, link, this, address); // The following is for stop-and-wait, feel free to remove currentSequenceNum = 1; } private Timer timer; private NetworkInterface network; private Address address; private ReceiveBuffer buffer; private int currentSequenceNum; // for stop-and-wait // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Send: external interface to remove data from the receive stream. // This operation may block because of the call to // ReceiveBuffer.RemoveBytes. // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - public byte[] Receive (int numBytes) { return buffer.RemoveBytes (numBytes); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // PacketArrived: processing that happens when we receive a // packet // // For stop-and-wait: ack iff packet is old or can be stored, // advance currentSequenceNum if packet is // new and stored // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - public synchronized void PacketArrived (Packet p) { if (p.sequenceNum > currentSequenceNum) { // System.out.println ("Received future message " + p.sequenceNum); return; } if (p.sequenceNum == currentSequenceNum) { if (!buffer.AppendBytes (p.data)) { System.out.println ("Dropping packet: no space"); return; // no space, cannot ack } ++currentSequenceNum; } // send ack for this packet Packet ack = new Packet (); ack.sourceAddr = address; ack.destinationAddr = p.sourceAddr; ack.sequenceNum = p.sequenceNum; ack.ack = true; ack.data = new byte[0]; network.SendPacket (ack); } } //----------------------------------------------------------------- // ReceiveBuffer: a specialized bounded-buffer for receiving. This // buffer has the semantics that removes will wait // for data to become available but appends will // always return immediately //----------------------------------------------------------------- class ReceiveBuffer { // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Constructor: set up the buffer with the given size. Needs // the global timer to ensure that waiting threads // are properly woken // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - public ReceiveBuffer (Timer timer, int size) { waitingThread = null; this.timer = timer; buffer = new byte[size]; numBytes = 0; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // AppendBytes: append data to the end of the buffer/queue. // If there is no room, then fail and return false // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - public synchronized boolean AppendBytes (byte[] data) { boolean retval = true; if (numBytes + data.length < buffer.length) { for (int i=0; i numBytes) try { waitingThread = Thread.currentThread (); timer.UnregisterThread (waitingThread); wait (); } catch (InterruptedException e) { } byte[] retval = new byte[maxBytes]; for (int i=0; i