From fdba979a0fa8c0c5ccb0b4c52c699d1097646159 Mon Sep 17 00:00:00 2001 From: Sebastian Rieger Date: Sun, 2 Jun 2019 22:22:05 +0200 Subject: [PATCH] initial version --- .classpath | 6 ++++ .gitignore | 1 + .project | 17 +++++++++ build/Server1.jar | Bin 0 -> 13608 bytes build/Server2.jar | Bin 0 -> 13608 bytes build/TCPPerfServer.jar | Bin 0 -> 13610 bytes build/UDPPerfServer.jar | Bin 0 -> 13610 bytes build/build-server-jars.xml | 53 +++++++++++++++++++++++++++ src/perf/TCPPerfClient.java | 59 ++++++++++++++++++++++++++++++ src/perf/TCPPerfServer.java | 55 ++++++++++++++++++++++++++++ src/perf/UDPPerfClient.java | 70 ++++++++++++++++++++++++++++++++++++ src/perf/UDPPerfServer.java | 58 ++++++++++++++++++++++++++++++ src/socket/Client1.java | 43 ++++++++++++++++++++++ src/socket/Client2.java | 37 +++++++++++++++++++ src/socket/Server1.java | 42 ++++++++++++++++++++++ src/socket/Server2.java | 45 +++++++++++++++++++++++ 16 files changed, 486 insertions(+) create mode 100644 .classpath create mode 100644 .gitignore create mode 100644 .project create mode 100644 build/Server1.jar create mode 100644 build/Server2.jar create mode 100644 build/TCPPerfServer.jar create mode 100644 build/UDPPerfServer.jar create mode 100644 build/build-server-jars.xml create mode 100644 src/perf/TCPPerfClient.java create mode 100644 src/perf/TCPPerfServer.java create mode 100644 src/perf/UDPPerfClient.java create mode 100644 src/perf/UDPPerfServer.java create mode 100644 src/socket/Client1.java create mode 100644 src/socket/Client2.java create mode 100644 src/socket/Server1.java create mode 100644 src/socket/Server2.java diff --git a/.classpath b/.classpath new file mode 100644 index 0000000..d171cd4 --- /dev/null +++ b/.classpath @@ -0,0 +1,6 @@ + + + + + + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ae3c172 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/bin/ diff --git a/.project b/.project new file mode 100644 index 0000000..94f2040 --- /dev/null +++ b/.project @@ -0,0 +1,17 @@ + + + kommunikationsnetze-und-protokolle-bsc-ai-examples + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/build/Server1.jar b/build/Server1.jar new file mode 100644 index 0000000000000000000000000000000000000000..532b0ef5826165d8a357508a549f5553a0bd9c63 GIT binary patch literal 13608 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 R6zb~>?hOQre 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 SL7~3B;NCz%VF3R4_WuBhtKK^R literal 0 HcmV?d00001 diff --git a/build/UDPPerfServer.jar b/build/UDPPerfServer.jar new file mode 100644 index 0000000000000000000000000000000000000000..026a7461a0d8a9bd7fba6cb90b4c388c9a37c43d GIT binary patch literal 13610 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/perf/TCPPerfClient.java b/src/perf/TCPPerfClient.java new file mode 100644 index 0000000..1362579 --- /dev/null +++ b/src/perf/TCPPerfClient.java @@ -0,0 +1,59 @@ +package perf; + +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 TCPPerfClient { + public static void main(String argv[]) throws Exception { + String hostname = ""; + int tcpPort = 36039; + DateFormat df = new SimpleDateFormat("dd.MM.yyyy HH:mm:ss"); + + //System.out.println("Bitte geben Sie die Server-Adresse ein: "); + //hostname = inFromUser.readLine(); + hostname = "127.0.0.1"; + + while (true ) { + BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in)); + System.out.print("Bitte geben Sie die Anzahl zu übertragender Megabytes ein: "); + Long number = new Long(inFromUser.readLine()); + //Long number = (long)1; + + Socket clientSocket = new Socket(hostname, tcpPort); + + DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream()); + BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); + + long timestampStart = System.currentTimeMillis(); + System.out.println("Zeit vor Versand = " + timestampStart + " ms, " + df.format(new Date(timestampStart))); + outToServer.writeBytes(number.toString() + "\n"); + + if (number == 0) { + break; + } + + char[] buffer = new char[1024 * 1024]; + long totalBytesReceived = 0; + int charsRead = inFromServer.read(buffer); + while (charsRead != -1) + { + totalBytesReceived += charsRead; + charsRead = inFromServer.read(buffer); + } + + long timestampEnd = System.currentTimeMillis(); + System.out.println("Zeit nach Empfang = " + timestampEnd + " ms, " + df.format(new Date(timestampEnd))); + long duration = timestampEnd - timestampStart; + System.out.println("Delay = " + duration + " ms"); + double seconds = (duration / 1000.0); + double throughput = (totalBytesReceived / seconds); + System.out.println("Rate = " + (long)throughput + " B/s"); + clientSocket.close(); + } + } +} diff --git a/src/perf/TCPPerfServer.java b/src/perf/TCPPerfServer.java new file mode 100644 index 0000000..afc1dd8 --- /dev/null +++ b/src/perf/TCPPerfServer.java @@ -0,0 +1,55 @@ +package perf; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.net.ServerSocket; +import java.net.Socket; + +class TCPPerfServer { + public static void main(String argv[]) throws Exception { + int tcpPort = 36039; + Long clientNumberOfMegabytes; + + ServerSocket serverSocket = new ServerSocket(tcpPort); + + System.out.println("TCPPerfServer gestartet. Warte auf eingehende Requests..."); + + while (true) { + Socket connectionSocket = serverSocket.accept(); + + BufferedReader inFromClient = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream())); + BufferedWriter outToClient = new BufferedWriter(new OutputStreamWriter(connectionSocket.getOutputStream())); + + char[] buffer = new char[1024]; + clientNumberOfMegabytes = new Long(inFromClient.readLine()); + + if (clientNumberOfMegabytes == 0) { + connectionSocket.close(); + break; + } + + System.out.println("Request von TCPPerfClient " + connectionSocket.getInetAddress() + ":" + connectionSocket.getPort() + " empfangen. Erzeuge und sende " + clientNumberOfMegabytes + "MB ..."); + + for (long mb = 0; mb < clientNumberOfMegabytes; mb++) { + long megabyteStartTimeMilli = System.currentTimeMillis(); + for (long segment = 1; segment < 1024; segment++) { + long segmentStartTimeNano = System.nanoTime(); + outToClient.write(buffer); + if (clientNumberOfMegabytes == 1) { + double transferDurationSegment = System.nanoTime() - segmentStartTimeNano; + //System.out.printf("Dauer pro Segment: %.0f ns, Rate: %.0f KByte/s (MB: %d, Segment: %d)\n", transferDurationSegment, (1024 / (transferDurationSegment / 1000000000)), mb, segment); + // CSV Output Excel + System.out.println(mb + "," + segment + "," + transferDurationSegment); + } + } + double transferDurationMB = System.currentTimeMillis() - megabyteStartTimeMilli; + System.out.printf("1 MB (genauer MiB) gesendet in: %.0f ms, Rate: %.0f Bytes/s (MB: %d)\n", transferDurationMB, ((1024 * 1024) / (transferDurationMB / 1000)), mb); + } + System.out.print("\n"); + connectionSocket.close(); + } + serverSocket.close(); + } +} diff --git a/src/perf/UDPPerfClient.java b/src/perf/UDPPerfClient.java new file mode 100644 index 0000000..11e5500 --- /dev/null +++ b/src/perf/UDPPerfClient.java @@ -0,0 +1,70 @@ +package perf; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.InetAddress; +import java.net.SocketTimeoutException; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; + +class UDPPerfClient { + public static void main(String argv[]) throws Exception { + String hostname = ""; + int udpPort = 36039; + DateFormat df = new SimpleDateFormat("dd.MM.yyyy HH:mm:ss"); + + //System.out.println("Bitte geben Sie die Server-Adresse ein: "); + //hostname = inFromUser.readLine(); + hostname = "127.0.0.1"; + InetAddress serverAddress = InetAddress.getByName(hostname); + + while (true) { + BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in)); + System.out.print("Bitte geben Sie die Anzahl zu übertragender Megabytes ein: "); + Long numberOfMegabytes = new Long(inFromUser.readLine()); + //Long number = (long)1; + + DatagramSocket clientSocket = new DatagramSocket(); + clientSocket.setSoTimeout(5000); + + long timestampStart = System.currentTimeMillis(); + System.out.println("Zeit vor Versand = " + timestampStart + " ms, " + df.format(new Date(timestampStart))); + byte[] outbuffer = (new String(numberOfMegabytes + "\n")).getBytes(); + DatagramPacket sendPacket = new DatagramPacket(outbuffer, outbuffer.length, serverAddress, udpPort); + clientSocket.send(sendPacket); + + if (numberOfMegabytes == 0) { + break; + } + + long totalBytesReceived = 0; + while (true) { + byte[] receiveData = new byte[1024]; + DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length); + try { + clientSocket.receive(receivePacket); + } catch (SocketTimeoutException ste) { + System.out.println("Timeout"); + break; + } + + String receivedString = new String(receiveData); + if (receivedString.contains("done")) { + System.out.println("Ende der Übermittlung erkannt."); + break; + } + else + { + totalBytesReceived += receivePacket.getLength(); + System.out.println(totalBytesReceived + " Bytes insgesamt empfangen."); + } + + } + System.out.printf("Insgesamt %d Bytes von %d (%d MB) empfangen.\n", totalBytesReceived - 4, (1024 * 1024) * numberOfMegabytes, numberOfMegabytes); + clientSocket.close(); + } + } +} diff --git a/src/perf/UDPPerfServer.java b/src/perf/UDPPerfServer.java new file mode 100644 index 0000000..d5dc91f --- /dev/null +++ b/src/perf/UDPPerfServer.java @@ -0,0 +1,58 @@ +package perf; + +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.InputStreamReader; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.InetAddress; + +class UDPPerfServer { + public static void main(String argv[]) throws Exception { + int udpPort = 36039; + Long clientNumberOfMegabytes; + + DatagramSocket datagramSocket = new DatagramSocket(udpPort); + + byte[] receiveData = new byte[1024]; + byte[] sendData = new byte[1024]; + + System.out.println("UDPPerfServer gestartet. Warte auf eingehende Requests..."); + + while (true) { + DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length); + datagramSocket.receive(receivePacket); + + InetAddress clientAddress = receivePacket.getAddress(); + int clientSrcPort = receivePacket.getPort(); + + BufferedReader inFromClient = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(receivePacket.getData()))); + + clientNumberOfMegabytes = new Long(inFromClient.readLine()); + + if (clientNumberOfMegabytes == 0) { + break; + } + + for (long mb = 0; mb < clientNumberOfMegabytes; mb++) { + long megabyteStartTimeMilli = System.currentTimeMillis(); + for (long segment = 1; segment < 1024; segment++) { + //long segmentStartTimeNano = System.nanoTime(); + DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, clientAddress, clientSrcPort); + datagramSocket.send(sendPacket); + //double transferDurationSegment = System.nanoTime() - segmentStartTimeNano; + //System.out.printf("Dauer pro Segment: %.0f ns, Rate: %.0f KByte/s (MB: %d, Segment: %d)\n", transferDurationSegment, (1024 / (transferDurationSegment / 1000000000)), mb, segment); + // CSV Output Excel + //System.out.println(mb + "," + segment + "," + transferDurationSegment); + } + double transferDurationMB = System.currentTimeMillis() - megabyteStartTimeMilli; + System.out.printf("1 MB (genauer MiB) gesendet in: %.0f ms, Rate: %.0f Bytes/s (MB: %d)\n", transferDurationMB, ((1024 * 1024) / (transferDurationMB / 1000)), mb); + } + System.out.print("\n"); + byte[] finishLabel = (new String("done")).getBytes(); + DatagramPacket sendPacket = new DatagramPacket(finishLabel, finishLabel.length, clientAddress, clientSrcPort); + datagramSocket.send(sendPacket); + } + datagramSocket.close(); + } +} diff --git a/src/socket/Client1.java b/src/socket/Client1.java new file mode 100644 index 0000000..c5ca1cd --- /dev/null +++ b/src/socket/Client1.java @@ -0,0 +1,43 @@ +/* Angelehnt an Kurose/Ross Computernetzwerke (bis 5e Java, ab 6e Python) */ + +package socket; + +import java.io.*; +import java.net.*; + +class Client1 { + public static void main(String args[]) throws Exception { + String hostname = "localhost"; + int port = 36037; + + BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in)); + DatagramSocket clientSocket = new DatagramSocket(); + + InetAddress serverAddress = InetAddress.getByName(hostname); + byte[] sendData = new byte[1024]; + byte[] receiveData = new byte[1024]; + String message; + String modifiedMessage; + + while (true) + { + System.out.print("Nachricht an Server1: "); + message = inFromUser.readLine(); + + sendData = message.getBytes(); + DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, serverAddress, port); + clientSocket.send(sendPacket); + + if (message.equals("exit")) { + break; + } + + DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length); + clientSocket.receive(receivePacket); + + modifiedMessage = new String(receivePacket.getData()); + System.out.println("Antwort von Server1: " + modifiedMessage); + } + clientSocket.close(); + } +} diff --git a/src/socket/Client2.java b/src/socket/Client2.java new file mode 100644 index 0000000..e208054 --- /dev/null +++ b/src/socket/Client2.java @@ -0,0 +1,37 @@ +/* Angelehnt an Kurose/Ross Computernetzwerke (bis 5e Java, ab 6e Python) */ + +package socket; + +import java.io.*; +import java.net.*; + +class Client2 { + public static void main(String argv[]) throws Exception { + String hostname = "localhost"; + int port = 36037; + + BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in)); + Socket clientSocket = new Socket(hostname, port); + + DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream()); + BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); + String message; + String modifiedMessage; + + while (true) + { + System.out.print("Nachricht an Server2: "); + message = inFromUser.readLine(); + + outToServer.writeBytes(message + '\n'); + + if (message.equals("exit")) { + break; + } + + modifiedMessage = inFromServer.readLine(); + System.out.println("Antwort von Server2: " + modifiedMessage); + } + clientSocket.close(); + } +} diff --git a/src/socket/Server1.java b/src/socket/Server1.java new file mode 100644 index 0000000..3571df5 --- /dev/null +++ b/src/socket/Server1.java @@ -0,0 +1,42 @@ +/* Angelehnt an Kurose/Ross Computernetzwerke (bis 5e Java, ab 6e Python) */ + +package socket; + +import java.net.*; + +class Server1 { + public static void main(String args[]) throws Exception { + int port = 36037; + + DatagramSocket serverSocket = new DatagramSocket(port); + + byte[] receiveData = new byte[1024]; + byte[] sendData = new byte[1024]; + String message; + String modifiedMessage; + + System.out.println("Server1 gestartet. Warte auf eingehende Requests..."); + + while (true) { + DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length); + serverSocket.receive(receivePacket); + message = new String(receivePacket.getData(), 0, receivePacket.getLength()); + + InetAddress clientAddress = receivePacket.getAddress(); + int clientSrcPort = receivePacket.getPort(); + + System.out.println("Request von Client1 " + clientAddress + ":" + clientSrcPort + " empfangen. Erzeuge und sende Antwort..."); + + if (message.equals("exit")) + { + break; + } + + modifiedMessage = message.toUpperCase(); + sendData = modifiedMessage.getBytes(); + DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, clientAddress, clientSrcPort); + serverSocket.send(sendPacket); + } + serverSocket.close(); + } +} diff --git a/src/socket/Server2.java b/src/socket/Server2.java new file mode 100644 index 0000000..3fd7c75 --- /dev/null +++ b/src/socket/Server2.java @@ -0,0 +1,45 @@ +/* Angelehnt an Kurose/Ross Computernetzwerke (bis 5e Java, ab 6e Python) */ + +package socket; + +import java.io.*; +import java.net.*; + +class Server2 { + public static void main(String argv[]) throws Exception { + int port = 36037; + + ServerSocket serverSocket = new ServerSocket(port); + + String message; + String modifiedMessage; + + System.out.println("Server2 gestartet. Warte auf eingehende Requests..."); + + Socket connectionSocket = serverSocket.accept(); + while (true) { + + BufferedReader inFromClient = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream())); + DataOutputStream outToClient = new DataOutputStream(connectionSocket.getOutputStream()); + + // Try/Catch hinzugefügt, nachdem bei Einsatz mit Amazon AWS (Healthcheck des ELB) message null war + try { + message = inFromClient.readLine(); + if (message != null) { + System.out.println("Request von Client2 " + connectionSocket.getInetAddress() + ":" + connectionSocket.getPort() + " empfangen. Erzeuge und sende Antwort..."); + + if (message.equals("exit")) { + break; + } + + modifiedMessage = message.toUpperCase() + '\n'; + outToClient.writeBytes(modifiedMessage); + } + } catch (IOException ioe) { + ioe.printStackTrace(); + } + } + connectionSocket.close(); + serverSocket.close(); + } +}