Advertisement
Guest User

Untitled

a guest
Mar 26th, 2017
72
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.73 KB | None | 0 0
  1.  
  2. import java.util.ArrayList;
  3.  
  4. public class StudentNetworkSimulator extends NetworkSimulator
  5. {
  6. /*
  7. * Predefined Constants (static member variables):
  8. *
  9. * int MAXDATASIZE : the maximum size of the Message data and Packet payload
  10. *
  11. * int A : a predefined integer that represents entity A int B : a predefined integer that represents entity B
  12. *
  13. *
  14. * Predefined Member Methods:
  15. *
  16. * void stopTimer(int entity): Stops the timer running at "entity" [A or B] void startTimer(int entity, double
  17. * increment): Starts a timer running at "entity" [A or B], which will expire in "increment" time units, causing the
  18. * interrupt handler to be called. You should only call this with A. void toLayer3(int callingEntity, Packet p) Puts
  19. * the packet "p" into the network from "callingEntity" [A or B] void toLayer5(int entity, String dataSent) Passes
  20. * "dataSent" up to layer 5 from "entity" [A or B] double getTime() Returns the current time in the simulator. Might
  21. * be useful for debugging. void printEventList() Prints the current event list to stdout. Might be useful for
  22. * debugging, but probably not.
  23. *
  24. *
  25. * Predefined Classes:
  26. *
  27. * Message: Used to encapsulate a message coming from layer 5 Constructor: Message(String inputData): creates a new
  28. * Message containing "inputData" Methods: boolean setData(String inputData): sets an existing Message's data to
  29. * "inputData" returns true on success, false otherwise String getData(): returns the data contained in the message
  30. * Packet: Used to encapsulate a packet Constructors: Packet (Packet p): creates a new Packet that is a copy of "p"
  31. * Packet (int seq, int ack, int check, String newPayload) creates a new Packet with a sequence field of "seq", an
  32. * ack field of "ack", a checksum field of "check", and a payload of "newPayload" Packet (int seq, int ack, int
  33. * check) chreate a new Packet with a sequence field of "seq", an ack field of "ack", a checksum field of "check",
  34. * and an empty payload Methods: boolean setSeqnum(int n) sets the Packet's sequence field to "n" returns true on
  35. * success, false otherwise boolean setAcknum(int n) sets the Packet's ack field to "n" returns true on success,
  36. * false otherwise boolean setChecksum(int n) sets the Packet's checksum to "n" returns true on success, false
  37. * otherwise boolean setPayload(String newPayload) sets the Packet's payload to "newPayload" returns true on
  38. * success, false otherwise int getSeqnum() returns the contents of the Packet's sequence field int getAcknum()
  39. * returns the contents of the Packet's ack field int getChecksum() returns the checksum of the Packet int
  40. * getPayload() returns the Packet's payload
  41. *
  42. */
  43.  
  44. // Add any necessary class variables here. Remember, you cannot use
  45. // these variables to send messages error free! They can only hold
  46. // state information for A or B.
  47. // Also add any necessary methods (e.g. checksum of a String)
  48. public int a_seqNum = 0;
  49. public int a_ackNum = 0;
  50. public int a_last_ack = 0;
  51. public int b_ack_num = 0;
  52. public Packet a_currentPacket, b_current_packet;
  53. public int count = 0;
  54. public int b_count = 1;
  55. private ArrayList<Packet> q;
  56. private int timer_interval = 30;
  57. private int max_window_size = 8;
  58. /** number of packets in the window which have been processed, this is different than max_window_size*/
  59. private int packets_in_window = 0;
  60. private int duplicate_acks = 0;
  61. /** lower bound of our window */
  62. private int lowest_index = 0;
  63.  
  64. // variables used to determine statistics.
  65. private double initialTime = -1;
  66. private int sent_app = 0;
  67. private int received_app = 0;
  68. private int sent = 0;
  69. private int received = 0;
  70. private int lost_plus_corrupt = 0;
  71. private int corrupt = 0;
  72. private int acks_sent = 0;
  73. private int acks_received = 0;
  74. private double avg_rtt = 0;
  75.  
  76. private int checksum (String message, int seqnum, int acknum)
  77. {
  78. String checksum = message + "" + seqnum + "" + acknum;
  79. return checksum.hashCode();
  80. }
  81.  
  82. private void sendPacket (Packet packet)
  83. {
  84. startTimer(A, timer_interval);
  85. toLayer3(A, packet);
  86. }
  87.  
  88. // Returns the statistics required for this assignment.
  89. private String getStatistics ()
  90. {
  91. double total_time = getTime() - initialTime;
  92. avg_rtt = total_time / received_app;
  93.  
  94. return "Stats:\nPackets sent by the application: " + sent_app + "\n" + "Packets received by the application: "
  95. + received_app + "\n" + "Packets sent by our transport protocol: " + sent + "\n"
  96. + "Packets received by our transport protocol: " + received + "\n" + "Packets lost: "
  97. + (lost_plus_corrupt - corrupt) + "\n" + "Loss rate: "
  98. + ((double) lost_plus_corrupt - corrupt) / ((double) sent + received) + "\n" + "Packets corrupt: "
  99. + corrupt + "\n" + "Corruption rate: " + (double) corrupt / ((double) sent + received) + "\n"
  100. + "Acks sent: " + acks_sent + "\n" + "Acks received: " + acks_received + "\n" + "Average RTT: "
  101. + avg_rtt + " ns per message\n";
  102. }
  103.  
  104. // This is the constructor. Don't touch!
  105. public StudentNetworkSimulator (int numMessages, double loss, double corrupt, double avgDelay, int trace, long seed)
  106. {
  107. super(numMessages, loss, corrupt, avgDelay, trace, seed);
  108. }
  109.  
  110. // This routine will be called whenever the upper layer at the sender [A]
  111. // has a message to send. It is the job of your protocol to insure that
  112. // the data in such a message is delivered in-order, and correctly, to
  113. // the receiving upper layer.
  114. protected void aOutput (Message message)
  115. {
  116. a_currentPacket = new Packet(a_seqNum, a_ackNum, checksum(message.getData(), a_seqNum, a_ackNum),
  117. message.getData());
  118. a_seqNum++;
  119.  
  120. if (q.size() <= 50)// only buffer up to 50 packets, drop the rest.
  121. {
  122. q.add(a_currentPacket);
  123.  
  124. // only send the packet if we are within our window_size
  125. if (packets_in_window <= max_window_size)
  126. {
  127. sendPacket(a_currentPacket);
  128. System.out.println(a_currentPacket.getSeqnum() + " Packet sent from A");
  129.  
  130. packets_in_window++;
  131. }
  132.  
  133. }
  134. else
  135. {
  136. System.out.println(a_currentPacket.getSeqnum() + " Packet not sent from A");
  137. }
  138. }
  139.  
  140. // This routine will be called whenever a packet sent from the B-side
  141. // (i.e. as a result of a toLayer3() being done by a B-side procedure)
  142. // arrives at the A-side. "packet" is the (possibly corrupted) packet
  143. // sent from the B-side.
  144. protected void aInput (Packet packet)
  145. {
  146. System.out.println("Ack " + (packet.getAcknum() - 1) + " recieved by A\n");
  147.  
  148. // check for corruption
  149. if (checksum(packet.getPayload(), packet.getSeqnum(), packet.getAcknum()) == packet.getChecksum())
  150. {
  151. if (a_last_ack == packet.getAcknum())
  152. {
  153. duplicate_acks++;
  154. }
  155.  
  156. stopTimer(A);
  157.  
  158. if (duplicate_acks == 3)
  159. {
  160. send_window();
  161. }
  162. else
  163. {
  164. a_last_ack = packet.getAcknum();
  165. shift_window_down();
  166. }
  167. }
  168. else
  169. {
  170. System.out.println("Ack corrupt between B and A");
  171. }
  172. }
  173.  
  174. /**
  175. * Shifts the window down, and sends the new packets which have just entered our window.
  176. */
  177. private void shift_window_down ()
  178. {
  179. int index = lowest_index;
  180.  
  181. // shift the window down
  182. while ((index < q.size()) && (q.get(index).getAcknum() != a_last_ack + 1))
  183. {
  184. lowest_index++;
  185. packets_in_window--;
  186. index++;
  187. }
  188.  
  189. // send the new packets in the window
  190. if (q.size() > lowest_index)
  191. {
  192. // already sent packets
  193. index = packets_in_window - 1;
  194.  
  195. // Our index is valid and we are less than the window size.
  196. while ((index >= q.size() == false) && (packets_in_window <= max_window_size))
  197. {
  198. // ensure that if the timer is still going we stop it before starting it again.
  199. stopTimer(A);
  200.  
  201. sendPacket(q.get(index));
  202. index++;
  203. packets_in_window++;
  204.  
  205. System.out.println(q.get(q.size() - 1).getSeqnum() + " Packet sent from A's q");
  206. }
  207. }
  208. }
  209.  
  210. /**
  211. * Sends the next packets in the queue from the start to the window size.
  212. */
  213. private void send_window ()
  214. {
  215. if (q.size() > lowest_index)
  216. {
  217. int index = lowest_index;
  218.  
  219. // Our index is valid and we are less than the window size.
  220. while ((index >= q.size() == false) && (packets_in_window <= max_window_size))
  221. {
  222. // ensure that if the timer is still going we stop it before starting it again.
  223. stopTimer(A);
  224.  
  225. sendPacket(q.get(index));
  226. index++;
  227. packets_in_window++;
  228.  
  229. System.out.println(q.get(q.size() - 1).getSeqnum() + " Packet sent from A's q");
  230. }
  231. }
  232. }
  233.  
  234. // This routine will be called when A's timer expires (thus generating a
  235. // timer interrupt). You'll probably want to use this routine to control
  236. // the retransmission of packets. See startTimer() and stopTimer(), above,
  237. // for how the timer is started and stopped.
  238. protected void aTimerInterrupt ()
  239. {
  240. System.out.println("Packet loss or corruption (timer interrupt).");
  241.  
  242. // Re-send all of the packets in the window.
  243. send_window();
  244. }
  245.  
  246. // This routine will be called once, before any of your other A-side
  247. // routines are called. It can be used to do any required
  248. // initialization (e.g. of member variables you add to control the state
  249. // of entity A).
  250. protected void aInit ()
  251. {
  252. q = new ArrayList<>();
  253. }
  254.  
  255. // This routine will be called whenever a packet sent from the B-side
  256. // (i.e. as a result of a toLayer3() being done by an A-side procedure)
  257. // arrives at the B-side. "packet" is the (possibly corrupted) packet
  258. // sent from the A-side.
  259. protected void bInput (Packet packet)
  260. {
  261. System.out.println(packet.getSeqnum() + " packet recieved by B");
  262.  
  263. // ensure the packet is not corrupt.
  264. if (checksum(packet.getPayload(), packet.getSeqnum(), packet.getAcknum()) == packet.getChecksum())
  265. {
  266. int b_ack = packet.getSeqnum() + 1;
  267. int b_seq = packet.getSeqnum();
  268. String b_message = packet.getPayload();
  269. int b_cksum = checksum(b_message, b_seq, b_ack);
  270.  
  271. // Acks the packet it expects to get next.
  272. b_current_packet = new Packet(b_seq, b_ack, b_cksum, b_message);
  273.  
  274. toLayer3(B, b_current_packet);
  275. System.out.println("Ack " + (b_ack - 1) + " sent from B");
  276. toLayer5(B, packet.getPayload());
  277. }
  278. else
  279. {
  280. System.out.println("Packet corrupt between A and B");
  281. }
  282. }
  283.  
  284. // This routine will be called once, before any of your other B-side
  285. // routines are called. It can be used to do any required
  286. // initialization (e.g. of member variables you add to control the state
  287. // of entity B).
  288. protected void bInit ()
  289. {
  290. }
  291. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement