Diskussion Kurzen Text per UDP senden - Codereview

Mat

Aktives Mitglied
Hier wieder der allwöchentliche Gammelcode aus alten (oder auch neuen) Aufgaben und Projekten. Etwas verspätet, weil ich fast nur noch sehr kleine Codeschnipsel oder viel zu große, schwer isolierbare Projekte rumliegen habe.

Dieses Mal was mit Java (kurz und knapp).

Die Aufgabe war, einen Service in einem kleinen Docker-Netzwerk zu entdecken und seine Nachrichten zu verarbeiten. Weil sich das schlecht testen ließ (das Netzwerk fiel auch dauernd aus), haben wir mehrere kleine Hilfsprogramme zum lokalen Simulieren geschrieben.

Eines davon war ein Packet sender für UDP:

Server:
package server;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;

public class Main {
    private static final int PORT = 12_345;

    public static void main(String[] args) {
        final int port;

        switch (args.length) {
            case 0:
                port = PORT;
                break;
            case 1:
                port = Integer.parseInt(args[0]);
                break;
            default:
                System.out.println("Verwendung:\t\tprogramm.jar [PORT]");
                System.out.println("Beispiel:\tprogramm.jar");
                System.out.println("Beispiel:\tprogramm.jar 12345");
                return;
        }

        try (final DatagramSocket socket = new DatagramSocket(); final Scanner scanner = new Scanner(System.in)) {
            System.out.print("Erste Nachricht eingeben (leer lassen zum Abbrechen): ");
            String msg = scanner.nextLine();

            while (!msg.isEmpty()) {
                byte[] buf = msg.getBytes(StandardCharsets.UTF_8);
                DatagramPacket packet = new DatagramPacket(buf, buf.length, InetAddress.getLoopbackAddress(), port);
                socket.send(packet);
                System.out.print("Nachricht eingeben (leer lassen zum Beenden): ");
                msg = scanner.nextLine();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        System.out.println("Programm beendet");
    }
}

So ähnlich könnte ein Listener aussehen (war leichter, einen zu schreiben als den jetzt aus unserem Code zu isolieren ^^):
Java:
package client;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.nio.charset.StandardCharsets;

public class Main {

    public static void main(String[] args) {

        Thread listeningThread = new Thread(() -> {
            try (DatagramSocket socket = new DatagramSocket(12345)) {
                byte[] buf = new byte[512];
                DatagramPacket packet = new DatagramPacket(buf, buf.length);
                while (true) {
                    socket.receive(packet);
                    String msg = new String(packet.getData(), StandardCharsets.UTF_8);
                    System.out.println(msg);
                }

            } catch (IOException e) {
                e.printStackTrace();
            }
        });

        listeningThread.start();
    }

}

Wenn ich den Code so sehe, würde ich das heute wohl einfach mit netcat oder sowas machen (1 Zeile statt 50 Zeilen :oops:). Oder wenn ich mehr Kontrolle bräuchte, dann in einer Sprache, in der man die Pakete selbst zusammenbauen kann (C usw).

Hier mit Netcat:
Bash:
# Empfänger
nc -ulp 12345

# Sender
nc -u localhost 12345

Wenn ich das mit Java machen würde, dann:
  • do-while- statt einer while-Schleife (weniger doppelter Code)
  • Paketgröße beschränken, auch wenn es nur für lokale Tests ist
  • Userinput weglassen und stattdessen Aufrufparameter nehmen für Port und Nachricht (lässt sich besser in ein Skript einbabauen)
Mehr fällt mir nicht auf, aber ich bin auch nicht so der Netzwerk-Spezi
 
Zuletzt bearbeitet:
Oben Unten