Eine Anleitung zu UDP in Java

1. Übersicht

In diesem Artikel untersuchen wir die Netzwerkkommunikation mit Java über das User Datagram Protocol (UDP).

UDP ist ein Kommunikationsprotokoll, das unabhängige Pakete ohne Garantie für die Ankunft und ohne Garantie für die Reihenfolge der Zustellung über das Netzwerk überträgt .

Die meiste Kommunikation über das Internet findet über das Transmission Control Protocol (TCP) statt. UDP hat jedoch seinen Platz, den wir im nächsten Abschnitt untersuchen werden.

2. Warum UDP verwenden?

UDP unterscheidet sich stark von dem allgemeineren TCP. Bevor jedoch die Nachteile von UDP auf Oberflächenebene betrachtet werden, ist es wichtig zu verstehen, dass das Fehlen von Overhead es erheblich schneller als TCP machen kann.

Abgesehen von der Geschwindigkeit müssen wir uns auch daran erinnern, dass einige Arten der Kommunikation nicht die Zuverlässigkeit von TCP erfordern, sondern stattdessen eine niedrige Latenz schätzen. Das Video ist ein gutes Beispiel für eine Anwendung, die möglicherweise von der Ausführung über UDP anstelle von TCP profitiert.

3. Erstellen von UDP-Anwendungen

Das Erstellen von UDP-Anwendungen ist dem Erstellen eines TCP-Systems sehr ähnlich. Der einzige Unterschied besteht darin, dass wir keine Punkt-zu-Punkt-Verbindung zwischen einem Client und einem Server herstellen.

Das Setup ist auch sehr einfach. Java wird mit integrierter Netzwerkunterstützung für UDP ausgeliefert, das Teil des Pakets java.net ist . Daher Netzwerkoperationen über UDP zu erfüllen, brauchen wir nur die Klassen aus dem importieren java.net Paket: java.net.DatagramSocket und java.net.DatagramPacket .

In den folgenden Abschnitten erfahren Sie, wie Sie Anwendungen entwerfen, die über UDP kommunizieren. Wir werden das beliebte Echo-Protokoll für diese Anwendung verwenden.

Zuerst erstellen wir einen Echoserver, der alle an ihn gesendeten Nachrichten zurücksendet, dann einen Echoclient, der nur beliebige Nachrichten an den Server sendet, und schließlich testen wir die Anwendung, um sicherzustellen, dass alles einwandfrei funktioniert.

4. Der Server

Bei der UDP-Kommunikation wird eine einzelne Nachricht in ein DatagramPacket gekapselt, das über ein DatagramSocket gesendet wird .

Beginnen wir mit der Einrichtung eines einfachen Servers:

public class EchoServer extends Thread { private DatagramSocket socket; private boolean running; private byte[] buf = new byte[256]; public EchoServer() { socket = new DatagramSocket(4445); } public void run() { running = true; while (running) { DatagramPacket packet = new DatagramPacket(buf, buf.length); socket.receive(packet); InetAddress address = packet.getAddress(); int port = packet.getPort(); packet = new DatagramPacket(buf, buf.length, address, port); String received = new String(packet.getData(), 0, packet.getLength()); if (received.equals("end")) { running = false; continue; } socket.send(packet); } socket.close(); } }

Wir erstellen ein globales DatagramSocket, das wir durchgehend zum Senden von Paketen verwenden, ein Byte-Array zum Umschließen unserer Nachrichten und eine Statusvariable namens running .

Der Einfachheit halber erweitert der Server Thread , sodass wir alles innerhalb der Ausführungsmethode implementieren können .

Innerhalb von run erstellen wir eine while-Schleife, die nur ausgeführt wird, bis die Ausführung durch einen Fehler oder eine Beendigungsnachricht vom Client in false geändert wird.

Am Anfang der Schleife instanziieren wir ein DatagramPacket , um eingehende Nachrichten zu empfangen.

Als nächstes rufen wir die Empfangsmethode für den Socket auf. Diese Methode blockiert, bis eine Nachricht eintrifft, und speichert die Nachricht im Byte-Array des an sie übergebenen DatagramPacket .

Nach dem Empfang der Nachricht rufen wir die Adresse und den Port des Clients ab, da wir die Antwort senden werden

zurück.

Als Nächstes erstellen wir ein DatagramPacket zum Senden einer Nachricht an den Client. Beachten Sie den Unterschied in der Signatur mit dem empfangenden Paket. Dieser erfordert auch die Adresse und den Port des Clients, an den wir die Nachricht senden.

5. Der Kunde

Lassen Sie uns nun einen einfachen Client für diesen neuen Server bereitstellen:

public class EchoClient { private DatagramSocket socket; private InetAddress address; private byte[] buf; public EchoClient() { socket = new DatagramSocket(); address = InetAddress.getByName("localhost"); } public String sendEcho(String msg) { buf = msg.getBytes(); DatagramPacket packet = new DatagramPacket(buf, buf.length, address, 4445); socket.send(packet); packet = new DatagramPacket(buf, buf.length); socket.receive(packet); String received = new String( packet.getData(), 0, packet.getLength()); return received; } public void close() { socket.close(); } }

Der Code unterscheidet sich nicht wesentlich vom des Servers. Wir haben unser globales DatagramSocket und die Adresse des Servers. Wir instanziieren diese im Konstruktor.

Wir haben eine separate Methode, die Nachrichten an den Server sendet und die Antwort zurückgibt.

Wir konvertieren zuerst die String-Nachricht in ein Byte-Array und erstellen dann ein DatagramPacket zum Senden von Nachrichten.

Als nächstes senden wir die Nachricht. Wir konvertieren das DatagramPacket sofort in ein empfangendes.

Wenn das Echo eintrifft, konvertieren wir die Bytes in eine Zeichenfolge und geben die Zeichenfolge zurück.

6. Der Test

In einer Klasse UDPTest.java erstellen wir einfach einen Test, um die Echofähigkeit unserer beiden Anwendungen zu überprüfen:

public class UDPTest { EchoClient client; @Before public void setup(){ new EchoServer().start(); client = new EchoClient(); } @Test public void whenCanSendAndReceivePacket_thenCorrect() { String echo = client.sendEcho("hello server"); assertEquals("hello server", echo); echo = client.sendEcho("server is working"); assertFalse(echo.equals("hello server")); } @After public void tearDown() { client.sendEcho("end"); client.close(); } }

Im Setup starten wir den Server und erstellen auch den Client. Während der TearDown- Methode senden wir eine Beendigungsnachricht an den Server, damit dieser geschlossen werden kann, und gleichzeitig schließen wir den Client.

7. Fazit

In diesem Artikel haben wir das User Datagram Protocol kennengelernt und erfolgreich eigene Client-Server-Anwendungen erstellt, die über UDP kommunizieren.

Um den vollständigen Quellcode für die in diesem Artikel verwendeten Beispiele zu erhalten, können Sie das GitHub-Projekt überprüfen.