From 47b6db17451119214aeb3458ea0991be4d9af806 Mon Sep 17 00:00:00 2001 From: Sebastian Rieger Date: Wed, 24 Jan 2018 18:12:49 +0100 Subject: [PATCH] Initial version of TCP Counter Server an Client --- .../aws/TCPTimeCounterClient.java | 89 +++++++++++++++++++ .../aws/TCPTimeCounterServer.java | 57 ++++++++++++ 2 files changed, 146 insertions(+) create mode 100644 VerteilteSysteme-Examples/src/verteiltesysteme/aws/TCPTimeCounterClient.java create mode 100644 VerteilteSysteme-Examples/src/verteiltesysteme/aws/TCPTimeCounterServer.java diff --git a/VerteilteSysteme-Examples/src/verteiltesysteme/aws/TCPTimeCounterClient.java b/VerteilteSysteme-Examples/src/verteiltesysteme/aws/TCPTimeCounterClient.java new file mode 100644 index 0000000..c0e8ebf --- /dev/null +++ b/VerteilteSysteme-Examples/src/verteiltesysteme/aws/TCPTimeCounterClient.java @@ -0,0 +1,89 @@ +package verteiltesysteme.aws; + +import java.io.BufferedReader; +import java.io.DataOutputStream; +import java.io.InputStreamReader; +import java.net.Socket; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; + +class TCPTimeCounterClient { + + /** + * Gibt einen Zeitstempel (timestamp) formatiert auf der Konsole aus. Der + * Zeitstempel wird in aktuellen Millisekunden seit 1.1.1970 (UTC) und als + * formatiertes Datum inkl. Uhrzeit ausgegeben. Der Ausgabe wird der übergebene + * String outputPrefix vorangestellt. + * + * @param outputPrefix + * String der als Beschreibung des Zeitpunkts vor die Ausgabe des + * timestamp gestellt wird. + * @param timestamp + * Zeitstempel basierend auf System.currentTimeMillis() + */ + private static void printFormattedTimestamp(String outputPrefix, long timestamp) { + DateFormat df = new SimpleDateFormat("dd.MM.yyyy HH:mm:ss"); + System.out.println(outputPrefix + " = " + timestamp + " ms, " + df.format(new Date(timestamp))); + } + + public static void main(String args[]) throws Exception { + String hostname = ""; + int tcpPort = 36038; + BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in)); + long timestampStart, timestampSent, timestampEnd, delay; + + // Hostname vom Benutzer anfragen auf dem der Server läuft + System.out.println("Bitte geben Sie die Server-Adresse ein: "); + hostname = inFromUser.readLine(); + + // Socket erzeugen + Socket clientSocket = new Socket(hostname, tcpPort); + + // Zahl vom Benutzer abfragen, die dann vom Server auf den aktuellen Zählerstand + // addiert wird + System.out.println("Bitte geben Sie eine Zahl ein: "); + Long number = new Long(inFromUser.readLine()); + + // Zahl an Server senden + System.out.println(System.lineSeparator()); + timestampStart = System.currentTimeMillis(); + printFormattedTimestamp("Zeit vor Versand", timestampStart); + + DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream()); + BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); + outToServer.writeBytes(number.toString() + '\n'); + + timestampSent = System.currentTimeMillis(); + printFormattedTimestamp("Zeit nach Versand", timestampSent); + + // Antwort mit neuem Zählerstand und Timestamp vom Server empfangen + String result = inFromServer.readLine(); + timestampEnd = System.currentTimeMillis(); + printFormattedTimestamp("Zeit nach Empfang", timestampEnd); + + // Delay als Zeit zwischen timestampSent und timestampEnd berechnen und + // ausgeben + delay = timestampEnd - timestampStart; + System.out.println("Übertragungsdauer = " + delay + " ms"); + System.out.println(System.lineSeparator()); + + // Antwort vom Server auswerten und ausgeben + System.out.println("Ausgabe vom Server:" + System.lineSeparator() + result); + // Vom Server übergebenen Zeitstempel aus der Antwort herausschneiden + // + // Format Ausgabe vom Server " Zeit: " + // Beispiel: 60 Zeit: 1510735274021 15.11.2017 08:41:14 + long timestampServer = new Long(result.split(" ")[2]).longValue(); + // One-Way-Delay (Bitverzögerung) aus Rount-Trip-Time (RTT) ermitteln + float oneWayDelayEstimate = (timestampEnd - timestampSent) / 2; + // Zeitabweichung zwischen Client und Server ermitteln (Zeitstempel vom Server + // minus Zeitstempel bei Versand am Client minus One-Way-Delay) + float timestampSkew = timestampServer - timestampSent - oneWayDelayEstimate; + System.out.println("Zeitversatz zwischen Server und Client ca. = " + timestampSkew + " ms"); + System.out.println(System.lineSeparator()); + + // Socket schließen + clientSocket.close(); + } +} diff --git a/VerteilteSysteme-Examples/src/verteiltesysteme/aws/TCPTimeCounterServer.java b/VerteilteSysteme-Examples/src/verteiltesysteme/aws/TCPTimeCounterServer.java new file mode 100644 index 0000000..ee4b31c --- /dev/null +++ b/VerteilteSysteme-Examples/src/verteiltesysteme/aws/TCPTimeCounterServer.java @@ -0,0 +1,57 @@ +package verteiltesysteme.aws; + +import java.io.BufferedReader; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.ServerSocket; +import java.net.Socket; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; + +class TCPTimeCounterServer { + // Variable für Zählerstand des Servers, dieser Zähler wird durch Anfragen der + // Clients erhöht + private static long counter = 0; + + public static void main(String args[]) throws Exception { + int tcpPort = 36038; + DateFormat df = new SimpleDateFormat("dd.MM.yyyy HH:mm:ss"); + + // Socket erzeugen + // Warnung, dass Socket nicht geschlossen wird unterdrücken ;) + @SuppressWarnings("resource") + ServerSocket serverSocket = new ServerSocket(tcpPort); + System.out.println("TCP Time Counter Server ready... waiting for packets..."); + + while (true) { + // Auf Anfrage vom Client warten + Socket connectionSocket = serverSocket.accept(); + + // Anfrage vom Client empfangen + BufferedReader inFromClient = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream())); + DataOutputStream outToClient = new DataOutputStream(connectionSocket.getOutputStream()); + + // Vom Client gesendete Zahl einlesen und auf aktuellen Zählerstand addieren + long number = new Long(new String(inFromClient.readLine())); + counter += number; + + System.out.println("Anfrage von Client " + connectionSocket.getInetAddress() + ":" + connectionSocket.getPort() + " Zahl: " + number + " Zählerstand: " + counter); + + // Try/Catch hinzugefügt, nachdem bei Einsatz Amazon AWS (Healthcheck des ELB) clientSentence null war + try { + // Antwort vom Server senden + String output = (Long.toString(counter) + " Zeit: " + System.currentTimeMillis() + " " + + df.format(new Date(System.currentTimeMillis()))); + System.out.println("Antwort des Servers: " + output); + // Zeilenumbruch anfügen, da Client mit readLine auf komplette Zeile wartet + outToClient.writeBytes(output + '\n'); + } catch (IOException ioe) { + ioe.printStackTrace(); + } catch (NullPointerException npe) { + npe.printStackTrace(); + } + } + } +}