You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

93 lines
3.9 KiB

  1. package verteiltesysteme.socket.timecounter;
  2. import java.io.BufferedReader;
  3. import java.io.InputStreamReader;
  4. import java.net.DatagramPacket;
  5. import java.net.DatagramSocket;
  6. import java.net.InetAddress;
  7. import java.text.DateFormat;
  8. import java.text.SimpleDateFormat;
  9. import java.util.Date;
  10. class UDPTimeCounterClient {
  11. /**
  12. * Gibt einen Zeitstempel (timestamp) formatiert auf der Konsole aus. Der
  13. * Zeitstempel wird in aktuellen Millisekunden seit 1.1.1970 (UTC) und als
  14. * formatiertes Datum inkl. Uhrzeit ausgegeben. Der Ausgabe wird der bergebene
  15. * String outputPrefix vorangestellt.
  16. *
  17. * @param outputPrefix
  18. * String der als Beschreibung des Zeitpunkts vor die Ausgabe des
  19. * timestamp gestellt wird.
  20. * @param timestamp
  21. * Zeitstempel basierend auf System.currentTimeMillis()
  22. */
  23. private static void printFormattedTimestamp(String outputPrefix, long timestamp) {
  24. DateFormat df = new SimpleDateFormat("dd.MM.yyyy HH:mm:ss");
  25. System.out.println(outputPrefix + " = " + timestamp + " ms, " + df.format(new Date(timestamp)));
  26. }
  27. public static void main(String args[]) throws Exception {
  28. String hostname = "";
  29. int udpPort = 36038;
  30. BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));
  31. byte[] sendData = new byte[1024];
  32. byte[] receiveData = new byte[1024];
  33. long timestampStart, timestampSent, timestampEnd, delay;
  34. // Socket erzeugen
  35. DatagramSocket clientSocket = new DatagramSocket();
  36. // Hostname vom Benutzer anfragen auf dem der Server l�uft
  37. System.out.println("Bitte geben Sie die Server-Adresse ein: ");
  38. hostname = inFromUser.readLine();
  39. InetAddress IPAddress = InetAddress.getByName(hostname);
  40. // Zahl vom Benutzer abfragen, die dann vom Server auf den aktuellen Z�hlerstand
  41. // addiert wird
  42. System.out.println("Bitte geben Sie eine Zahl ein: ");
  43. Long number = new Long(inFromUser.readLine());
  44. sendData = number.toString().getBytes();
  45. // Zahl an Server senden
  46. System.out.println(System.lineSeparator());
  47. timestampStart = System.currentTimeMillis();
  48. printFormattedTimestamp("Zeit vor Versand", timestampStart);
  49. DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, udpPort);
  50. clientSocket.send(sendPacket);
  51. timestampSent = System.currentTimeMillis();
  52. printFormattedTimestamp("Zeit nach Versand", timestampSent);
  53. // Antwort mit neuem Z�hlerstand und Timestamp vom Server empfangen
  54. DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
  55. clientSocket.receive(receivePacket);
  56. timestampEnd = System.currentTimeMillis();
  57. printFormattedTimestamp("Zeit nach Empfang", timestampEnd);
  58. // Delay als Zeit zwischen timestampSent und timestampEnd berechnen und
  59. // ausgeben
  60. delay = timestampEnd - timestampStart;
  61. System.out.println("�bertragungsdauer = " + delay + " ms");
  62. System.out.println(System.lineSeparator());
  63. // Antwort vom Server auswerten und ausgeben
  64. String result = new String(receivePacket.getData());
  65. System.out.println("Ausgabe vom Server:" + System.lineSeparator() + result);
  66. // Vom Server �bergebenen Zeitstempel aus der Antwort herausschneiden
  67. //
  68. // Format Ausgabe vom Server "<Z�hlerstand> Zeit: <Zeitstempel> <Datum/Uhrzeit>"
  69. // Beispiel: 60 Zeit: 1510735274021 15.11.2017 08:41:14
  70. long timestampServer = new Long(result.split(" ")[2]).longValue();
  71. // One-Way-Delay (Bitverz�gerung) aus Rount-Trip-Time (RTT) ermitteln
  72. float oneWayDelayEstimate = (timestampEnd - timestampSent) / 2;
  73. // Zeitabweichung zwischen Client und Server ermitteln (Zeitstempel vom Server
  74. // minus Zeitstempel bei Versand am Client minus One-Way-Delay)
  75. float timestampSkew = timestampServer - timestampSent - oneWayDelayEstimate;
  76. System.out.println("Zeitversatz zwischen Server und Client ca. = " + timestampSkew + " ms");
  77. System.out.println(System.lineSeparator());
  78. // Socket schlie�en
  79. clientSocket.close();
  80. }
  81. }