Lesen Sie einen InputStream mit dem Java Server Socket

1. Übersicht

Zum Senden und Empfangen von Daten über ein Netzwerk verwenden wir häufig Sockets. Sockets sind nichts anderes als eine Kombination aus einer IP-Adresse und einer Portnummer, mit der ein Programm, das auf einem bestimmten Computer ausgeführt wird, eindeutig identifiziert werden kann.

In diesem Tutorial zeigen wir, wie wir Daten lesen können, die über einen Socket an uns gesendet werden.

2. Lesen von Daten aus einer Steckdose

Nehmen wir an, wir haben ein grundlegendes Verständnis der Socket-Programmierung.

Jetzt werden wir uns eingehender mit dem Lesen von Daten an einem Port befassen, den unser Server abhört.

Zunächst müssen wir die Variablen ServerSocket, Socket und DataInputStream deklarieren und initialisieren :

ServerSocket server = new ServerSocket(port); Socket socket = server.accept(); DataInputStream in = new DataInputStream(new BufferedInputStream(socket.getInputStream()));

Beachten Sie, dass wir uns entschieden haben, den InputStream des Sockets in einen DataInputStream zu verpacken. Auf diese Weise können wir Zeilen eines Textes und primitive Java-Datentypen auf tragbare Weise lesen.

Das ist schön, denn wenn wir jetzt wissen, welche Art von Daten wir erhalten, können wir spezielle Methoden wie readChar (), readInt (), readDouble () und readLine () verwenden.

Es kann jedoch schwierig sein, wenn Art und Länge der Daten nicht im Voraus bekannt sind.

In diesem Fall erhalten wir stattdessen einen Bytestrom vom Socket, indem wir die Funktion read () der unteren Ebene verwenden. Bei diesem Ansatz gibt es jedoch ein kleines Problem: Woher wissen wir, wie lange und welche Art von Daten wir erhalten?

Lassen Sie uns dieses Szenario im nächsten Abschnitt untersuchen.

3. Lesen von Binärdaten aus einem Socket

Beim Lesen von Daten in Bytes müssen wir unser eigenes Protokoll für die Kommunikation zwischen Server und Client definieren. Das einfachste Protokoll, das wir definieren können, heißt TLV (Type Length Value). Dies bedeutet, dass jede in den Socket geschriebene Nachricht die Form des Typs Längenwert hat.

Daher definieren wir jede gesendete Nachricht wie folgt:

  • Ein 1- Byte- Zeichen, das den Datentyp darstellt, z. B. s für String
  • Eine 4- Byte- Ganzzahl, die die Länge der Daten angibt
  • Und dann die tatsächlichen Daten, deren Länge gerade angegeben wurde

Sobald der Client und der Server die Verbindung hergestellt haben, folgt jede Nachricht diesem Format. Dann können wir unseren Code schreiben, um jede Nachricht zu analysieren und n Datenbytes eines bestimmten Typs zu lesen .

Lassen Sie uns anhand eines einfachen Beispiels mit einer String- Nachricht sehen, wie wir dies implementieren können .

Zuerst müssen wir die Funktion readChar () aufrufen, um den Datentyp zu lesen, und dann die Funktion readInt () aufrufen , um die Länge zu lesen:

char dataType = in.readChar(); int length = in.readInt();

Danach müssen wir die Daten lesen, die wir erhalten. Ein wichtiger Punkt hierbei ist, dass die Funktion read () möglicherweise nicht alle Daten in einem Aufruf lesen kann. Also müssen wir read () in einer while-Schleife aufrufen :

if(dataType == 's') { byte[] messageByte = new byte[length]; boolean end = false; StringBuilder dataString = new StringBuilder(length); int totalBytesRead = 0; while(!end) { int currentBytesRead = in.read(messageByte); totalBytesRead = currentBytesRead + totalBytesRead; if(totalBytesRead =length) { end = true; } } }

4. Client-Code zum Senden von Daten

Und was ist mit dem clientseitigen Code? Eigentlich ist es ganz einfach:

char type = 's'; // s for string String data = "This is a string of length 29"; byte[] dataInBytes = data.getBytes(StandardCharsets.UTF_8); out.writeChar(type); out.writeInt(dataInBytes.length); out.write(dataInBytes);

Das ist alles was unser Kunde tut!

5. Schlussfolgerung

In diesem Artikel haben wir das Lesen von Daten aus einem Socket erläutert. Wir haben uns verschiedene Funktionen angesehen, mit denen wir Daten eines bestimmten Typs lesen können. Wir haben auch gesehen, wie man Binärdaten liest.

Die vollständige Implementierung dieses Tutorials finden Sie auf GitHub.