Lees een InputStream met behulp van de Java Server Socket

1. Overzicht

Om gegevens over een netwerk te verzenden en te ontvangen, gebruiken we vaak stopcontacten. Sockets zijn niets anders dan een combinatie van een IP-adres en een poortnummer, die op unieke wijze een programma kunnen identificeren dat op een bepaalde machine wordt uitgevoerd.

In deze tutorial laten we zien hoe we gegevens kunnen lezen die via een stopcontact naar ons worden gestuurd.

2. Gegevens uit een stopcontact lezen

Laten we aannemen dat we een basiskennis hebben van socketprogrammering.

Nu gaan we dieper in op het lezen van gegevens op een poort waarop onze server luistert.

Ten eerste moeten we declareren en initialiseren ServerSocket, Socket, en DataInputStream variabelen:

ServerSocket server = nieuwe ServerSocket (poort); Socket socket = server.accept (); DataInputStream in = nieuwe DataInputStream (nieuwe BufferedInputStream (socket.getInputStream ()));

Merk op dat we ervoor hebben gekozen om de socket's in te pakken InputStream in een DataInputStream. Dit stelt ons in staat om tekstregels en primitieve Java-gegevenstypen op een draagbare manier te lezen.

Dit is prettig aangezien we nu weten welk type gegevens we zullen ontvangen, we kunnen gespecialiseerde methoden gebruiken zoals readChar (), readInt (), readDouble (), en Lees regel().

Het kan echter een uitdaging zijn als het type en de lengte van de gegevens niet van tevoren bekend zijn.

In dat geval halen we in plaats daarvan een stroom bytes uit de socket, met behulp van het lagere niveau lezen() functie. Maar er is een klein probleem bij deze benadering: hoe weten we de lengte en het type gegevens dat we zullen krijgen?

Laten we dit scenario in de volgende sectie onderzoeken.

3. Binaire gegevens uit een socket lezen

Bij het lezen van gegevens in bytes moeten we ons eigen protocol definiëren voor communicatie tussen server en client. Het eenvoudigste protocol dat we kunnen definiëren, wordt TLV (Type Length Value) genoemd. Het betekent dat elk bericht dat naar de socket wordt geschreven, de vorm heeft van de Type Length Value.

Daarom definiëren we elk verzonden bericht als:

  • A 1 byte teken dat het gegevenstype vertegenwoordigt, zoals s voor Draad
  • A 4 byte geheel getal dat de lengte van de gegevens aangeeft
  • En dan de feitelijke gegevens, waarvan de lengte zojuist werd aangegeven

Zodra de client en de server de verbinding tot stand hebben gebracht, volgt elk bericht dit formaat. Vervolgens kunnen we onze code schrijven om elk bericht te ontleden en te lezen n bytes aan gegevens van een specifiek type.

Laten we eens kijken hoe we dit kunnen implementeren aan de hand van een eenvoudig voorbeeld met een Draad bericht.

Ten eerste moeten we de readChar () functie, om het type gegevens te lezen en vervolgens de readInt () functie om de lengte ervan te lezen:

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

Daarna moeten we de gegevens lezen die we ontvangen. Een belangrijk punt om op te merken is dat de lezen() functie kan mogelijk niet alle gegevens in één oproep lezen. Dus we moeten de lezen() in een while-lus:

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

4. Klantcode om gegevens te verzenden

En hoe zit het met de client-side code? Eigenlijk is het vrij simpel:

char type = 's'; // s for string String data = "Dit is een string met een lengte van 29"; byte [] dataInBytes = data.getBytes (StandardCharsets.UTF_8); out.writeChar (type); out.writeInt (dataInBytes.length); out.write (dataInBytes);

Dat is alles wat onze klant doet!

5. Conclusie

In dit artikel hebben we besproken hoe je gegevens uit een socket kunt lezen. We hebben verschillende functies bekeken die ons helpen om gegevens van een bepaald type te lezen. We hebben ook gezien hoe binaire gegevens moeten worden gelezen.

De volledige implementatie van deze tutorial is te vinden op GitHub.


$config[zx-auto] not found$config[zx-overlay] not found