Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import java.util.ArrayList;
- public class StudentNetworkSimulator extends NetworkSimulator
- {
- /*
- * Predefined Constants (static member variables):
- *
- * int MAXDATASIZE : the maximum size of the Message data and Packet payload
- *
- * int A : a predefined integer that represents entity A int B : a predefined integer that represents entity B
- *
- *
- * Predefined Member Methods:
- *
- * void stopTimer(int entity): Stops the timer running at "entity" [A or B] void startTimer(int entity, double
- * increment): Starts a timer running at "entity" [A or B], which will expire in "increment" time units, causing the
- * interrupt handler to be called. You should only call this with A. void toLayer3(int callingEntity, Packet p) Puts
- * the packet "p" into the network from "callingEntity" [A or B] void toLayer5(int entity, String dataSent) Passes
- * "dataSent" up to layer 5 from "entity" [A or B] double getTime() Returns the current time in the simulator. Might
- * be useful for debugging. void printEventList() Prints the current event list to stdout. Might be useful for
- * debugging, but probably not.
- *
- *
- * Predefined Classes:
- *
- * Message: Used to encapsulate a message coming from layer 5 Constructor: Message(String inputData): creates a new
- * Message containing "inputData" Methods: boolean setData(String inputData): sets an existing Message's data to
- * "inputData" returns true on success, false otherwise String getData(): returns the data contained in the message
- * Packet: Used to encapsulate a packet Constructors: Packet (Packet p): creates a new Packet that is a copy of "p"
- * Packet (int seq, int ack, int check, String newPayload) creates a new Packet with a sequence field of "seq", an
- * ack field of "ack", a checksum field of "check", and a payload of "newPayload" Packet (int seq, int ack, int
- * check) chreate a new Packet with a sequence field of "seq", an ack field of "ack", a checksum field of "check",
- * and an empty payload Methods: boolean setSeqnum(int n) sets the Packet's sequence field to "n" returns true on
- * success, false otherwise boolean setAcknum(int n) sets the Packet's ack field to "n" returns true on success,
- * false otherwise boolean setChecksum(int n) sets the Packet's checksum to "n" returns true on success, false
- * otherwise boolean setPayload(String newPayload) sets the Packet's payload to "newPayload" returns true on
- * success, false otherwise int getSeqnum() returns the contents of the Packet's sequence field int getAcknum()
- * returns the contents of the Packet's ack field int getChecksum() returns the checksum of the Packet int
- * getPayload() returns the Packet's payload
- *
- */
- // Add any necessary class variables here. Remember, you cannot use
- // these variables to send messages error free! They can only hold
- // state information for A or B.
- // Also add any necessary methods (e.g. checksum of a String)
- public int a_seqNum = 0;
- public int a_ackNum = 0;
- public int a_last_ack = 0;
- public int b_ack_num = 0;
- public Packet a_currentPacket, b_current_packet;
- public int count = 0;
- public int b_count = 1;
- private ArrayList<Packet> q;
- private int timer_interval = 30;
- private int max_window_size = 8;
- /** number of packets in the window which have been processed, this is different than max_window_size*/
- private int packets_in_window = 0;
- private int duplicate_acks = 0;
- /** lower bound of our window */
- private int lowest_index = 0;
- // variables used to determine statistics.
- private double initialTime = -1;
- private int sent_app = 0;
- private int received_app = 0;
- private int sent = 0;
- private int received = 0;
- private int lost_plus_corrupt = 0;
- private int corrupt = 0;
- private int acks_sent = 0;
- private int acks_received = 0;
- private double avg_rtt = 0;
- private int checksum (String message, int seqnum, int acknum)
- {
- String checksum = message + "" + seqnum + "" + acknum;
- return checksum.hashCode();
- }
- private void sendPacket (Packet packet)
- {
- startTimer(A, timer_interval);
- toLayer3(A, packet);
- }
- // Returns the statistics required for this assignment.
- private String getStatistics ()
- {
- double total_time = getTime() - initialTime;
- avg_rtt = total_time / received_app;
- return "Stats:\nPackets sent by the application: " + sent_app + "\n" + "Packets received by the application: "
- + received_app + "\n" + "Packets sent by our transport protocol: " + sent + "\n"
- + "Packets received by our transport protocol: " + received + "\n" + "Packets lost: "
- + (lost_plus_corrupt - corrupt) + "\n" + "Loss rate: "
- + ((double) lost_plus_corrupt - corrupt) / ((double) sent + received) + "\n" + "Packets corrupt: "
- + corrupt + "\n" + "Corruption rate: " + (double) corrupt / ((double) sent + received) + "\n"
- + "Acks sent: " + acks_sent + "\n" + "Acks received: " + acks_received + "\n" + "Average RTT: "
- + avg_rtt + " ns per message\n";
- }
- // This is the constructor. Don't touch!
- public StudentNetworkSimulator (int numMessages, double loss, double corrupt, double avgDelay, int trace, long seed)
- {
- super(numMessages, loss, corrupt, avgDelay, trace, seed);
- }
- // This routine will be called whenever the upper layer at the sender [A]
- // has a message to send. It is the job of your protocol to insure that
- // the data in such a message is delivered in-order, and correctly, to
- // the receiving upper layer.
- protected void aOutput (Message message)
- {
- a_currentPacket = new Packet(a_seqNum, a_ackNum, checksum(message.getData(), a_seqNum, a_ackNum),
- message.getData());
- a_seqNum++;
- if (q.size() <= 50)// only buffer up to 50 packets, drop the rest.
- {
- q.add(a_currentPacket);
- // only send the packet if we are within our window_size
- if (packets_in_window <= max_window_size)
- {
- sendPacket(a_currentPacket);
- System.out.println(a_currentPacket.getSeqnum() + " Packet sent from A");
- packets_in_window++;
- }
- }
- else
- {
- System.out.println(a_currentPacket.getSeqnum() + " Packet not sent from A");
- }
- }
- // This routine will be called whenever a packet sent from the B-side
- // (i.e. as a result of a toLayer3() being done by a B-side procedure)
- // arrives at the A-side. "packet" is the (possibly corrupted) packet
- // sent from the B-side.
- protected void aInput (Packet packet)
- {
- System.out.println("Ack " + (packet.getAcknum() - 1) + " recieved by A\n");
- // check for corruption
- if (checksum(packet.getPayload(), packet.getSeqnum(), packet.getAcknum()) == packet.getChecksum())
- {
- if (a_last_ack == packet.getAcknum())
- {
- duplicate_acks++;
- }
- stopTimer(A);
- if (duplicate_acks == 3)
- {
- send_window();
- }
- else
- {
- a_last_ack = packet.getAcknum();
- shift_window_down();
- }
- }
- else
- {
- System.out.println("Ack corrupt between B and A");
- }
- }
- /**
- * Shifts the window down, and sends the new packets which have just entered our window.
- */
- private void shift_window_down ()
- {
- int index = lowest_index;
- // shift the window down
- while ((index < q.size()) && (q.get(index).getAcknum() != a_last_ack + 1))
- {
- lowest_index++;
- packets_in_window--;
- index++;
- }
- // send the new packets in the window
- if (q.size() > lowest_index)
- {
- // already sent packets
- index = packets_in_window - 1;
- // Our index is valid and we are less than the window size.
- while ((index >= q.size() == false) && (packets_in_window <= max_window_size))
- {
- // ensure that if the timer is still going we stop it before starting it again.
- stopTimer(A);
- sendPacket(q.get(index));
- index++;
- packets_in_window++;
- System.out.println(q.get(q.size() - 1).getSeqnum() + " Packet sent from A's q");
- }
- }
- }
- /**
- * Sends the next packets in the queue from the start to the window size.
- */
- private void send_window ()
- {
- if (q.size() > lowest_index)
- {
- int index = lowest_index;
- // Our index is valid and we are less than the window size.
- while ((index >= q.size() == false) && (packets_in_window <= max_window_size))
- {
- // ensure that if the timer is still going we stop it before starting it again.
- stopTimer(A);
- sendPacket(q.get(index));
- index++;
- packets_in_window++;
- System.out.println(q.get(q.size() - 1).getSeqnum() + " Packet sent from A's q");
- }
- }
- }
- // This routine will be called when A's timer expires (thus generating a
- // timer interrupt). You'll probably want to use this routine to control
- // the retransmission of packets. See startTimer() and stopTimer(), above,
- // for how the timer is started and stopped.
- protected void aTimerInterrupt ()
- {
- System.out.println("Packet loss or corruption (timer interrupt).");
- // Re-send all of the packets in the window.
- send_window();
- }
- // This routine will be called once, before any of your other A-side
- // routines are called. It can be used to do any required
- // initialization (e.g. of member variables you add to control the state
- // of entity A).
- protected void aInit ()
- {
- q = new ArrayList<>();
- }
- // This routine will be called whenever a packet sent from the B-side
- // (i.e. as a result of a toLayer3() being done by an A-side procedure)
- // arrives at the B-side. "packet" is the (possibly corrupted) packet
- // sent from the A-side.
- protected void bInput (Packet packet)
- {
- System.out.println(packet.getSeqnum() + " packet recieved by B");
- // ensure the packet is not corrupt.
- if (checksum(packet.getPayload(), packet.getSeqnum(), packet.getAcknum()) == packet.getChecksum())
- {
- int b_ack = packet.getSeqnum() + 1;
- int b_seq = packet.getSeqnum();
- String b_message = packet.getPayload();
- int b_cksum = checksum(b_message, b_seq, b_ack);
- // Acks the packet it expects to get next.
- b_current_packet = new Packet(b_seq, b_ack, b_cksum, b_message);
- toLayer3(B, b_current_packet);
- System.out.println("Ack " + (b_ack - 1) + " sent from B");
- toLayer5(B, packet.getPayload());
- }
- else
- {
- System.out.println("Packet corrupt between A and B");
- }
- }
- // This routine will be called once, before any of your other B-side
- // routines are called. It can be used to do any required
- // initialization (e.g. of member variables you add to control the state
- // of entity B).
- protected void bInit ()
- {
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement