Network programming assignment for University
25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.
 
 
 
 

155 satır
5.4 KiB

  1. /**
  2. * @file ARQ.java
  3. *
  4. * @author Christos Choutouridis AEM:8997
  5. * @email cchoutou@ece.auth.gr
  6. */
  7. package net.hoo2.auth.vmodem;
  8. /** @name imports */
  9. /** @{ */
  10. import java.util.*;
  11. /** @} */
  12. /**
  13. * @class ARQ
  14. *
  15. * Class to used for the ACK-NACK sequence
  16. */
  17. class ARQ {
  18. static final int ARQ_DURATION_DEFAULT = 240; /** Default duration for the sequence */
  19. static final int ARQ_BUFFER_SIZE = 256; /** ARQ buffer size */
  20. static final String ARQ_BEGIN = "PSTART"; /** Begin pattern of the response */
  21. static final String ARQ_END = "PSTOP"; /** End pattern of the response */
  22. static final int ARQ_SEQUENCE_BEGIN = 31; /** The response sequence string position */
  23. static final int ARQ_SEQUENCE_END = 47; /** The end of response sequence string position */
  24. static final int ARQ_CRC_BEGIN = 49; /** The response crc string position */
  25. static final int ARQ_CRC_END = 52; /** The end of response crc string position */
  26. private Com com_; /** Reference to communication module */
  27. private Log log_; /** Reference to logging module */
  28. private Transaction transaction_; /** A transaction object to used as a buffer for all requests */
  29. private int duration_; /** The desired duration for the session */
  30. private byte[] ack_; /** The desired ACK code for the session */
  31. private byte[] nack_; /** The desired NACK code for the session */
  32. /**
  33. * Basic constructor
  34. * @param com The Com module to use
  35. * @param log The Log module to use
  36. * @param ack The desired ACK code
  37. * @param nack The desired NACK code
  38. * @param duration The desired duration for the session
  39. */
  40. ARQ (Com com, Log log, byte[] ack, byte[] nack, int duration) {
  41. com_ = com;
  42. log_ = log;
  43. duration_ = duration;
  44. transaction_= new Transaction(null, new byte[ARQ_BUFFER_SIZE]);
  45. ack_ = ack;
  46. nack_ = nack;
  47. }
  48. /**
  49. * Functionality to drain the response buffer for the welcome message
  50. * from the server
  51. * @param ack The ack code that we will use (for printing, not sending)
  52. * @param nack The nack code that we will use (for printing, not sending)
  53. */
  54. void caption (byte[] ack, byte[] nack) {
  55. String line;
  56. line = "Running ARQ with: " + new String(ack) + "/" + new String(nack);
  57. log_.write(line, true);
  58. transaction_ = com_.request (transaction_, null, null, null, false);
  59. line = new String(transaction_.getResponse());
  60. log_.out(line);
  61. }
  62. /**
  63. * Main transaction loop. It send requests to server, get the response
  64. * and log the procedure while doing it.
  65. */
  66. void run () {
  67. long start;
  68. long now;
  69. long mark =0, tr =0, ts =0, tt =0;
  70. String line;
  71. int errors = 0;
  72. boolean good = true;
  73. start = System.currentTimeMillis();
  74. do {
  75. // Check if the previous transaction was error-free
  76. if (good)
  77. transaction_ = com_.request(transaction_, ack_, ARQ_BEGIN.getBytes(), ARQ_END.getBytes(), false);
  78. else
  79. transaction_ = com_.request(transaction_, nack_, ARQ_BEGIN.getBytes(), ARQ_END.getBytes(), false);
  80. good = (_crc_check(transaction_.response)) ? true : false; // crc check the response
  81. // time calculations
  82. tr = transaction_.arrival - transaction_.departure;
  83. tt = 0;
  84. if ((errors == 0) && good) {
  85. tt = ts = tr;
  86. }
  87. if ((errors == 0) && !good) {
  88. mark = transaction_.departure;
  89. ts = tr;
  90. }
  91. if ((errors != 0) && good) {
  92. tt = transaction_.arrival - mark;
  93. ts += tr;
  94. }
  95. if ((errors !=0) && !good) {
  96. ts += tr;
  97. }
  98. errors = (good) ? 0 : errors+1; // update the error strike
  99. line = new String(transaction_.code) + ": "
  100. + new String(transaction_.getResponse())
  101. + " Er: " + errors
  102. + " Tr= " + tr + " [msec]";
  103. if (errors !=0)
  104. line += " Ts= 0 [msec] Tt= 0 [msec]";
  105. else
  106. line += " Ts= " + ts + " [msec]" + " Tt= " + tt + " [msec]";
  107. log_.write(line);
  108. now = System.currentTimeMillis();
  109. } while (now - start < duration_*1000);
  110. }
  111. /** @name private helper API */
  112. /**@{ */
  113. /**
  114. * A CRC check functionality
  115. * @param data The data to check for validity
  116. * @return The check result
  117. */
  118. private boolean _crc_check (byte[] data) {
  119. byte[] seq = Arrays.copyOfRange(data, ARQ_SEQUENCE_BEGIN, ARQ_SEQUENCE_END);
  120. int crc = Integer.valueOf(
  121. new String(Arrays.copyOfRange(data, ARQ_CRC_BEGIN, ARQ_CRC_END))
  122. );
  123. return (crc == _crc(seq)) ? true : false;
  124. }
  125. /**
  126. * A CRC calculation function. This primitive CRC calculator
  127. * does not use any known CRC polynomial. It just uses XOR
  128. * @param data Reference to buffer
  129. * @return The CRC result
  130. */
  131. private int _crc (byte[] data) {
  132. int calc =0;
  133. for (int i=0 ; i<data.length ; ++i)
  134. calc ^= data[i];
  135. return calc;
  136. }
  137. /**@} */
  138. }