Læs en InputStream ved hjælp af Java Server Socket

1. Oversigt

For at sende og modtage data over et netværk bruger vi ofte sockets. Stik er intet andet end en kombination af en IP-adresse og et portnummer, som entydigt kan identificere et program, der kører på en given maskine.

I denne vejledning viser vi, hvordan vi kan læse data, der sendes til os via et stik.

2. Læsning af data fra en stikkontakt

Lad os antage, at vi har en grundlæggende forståelse af socket-programmering.

Nu vil vi grave dybere ned i læsning af data på en port, som vores server lytter til.

For det første er vi nødt til at erklære og initialisere ServerSocket, Socket, og DataInputStream variabler:

ServerSocket server = ny ServerSocket (port); Socket-bøsning = server.accept (); DataInputStream in = ny DataInputStream (ny BufferedInputStream (socket.getInputStream ()));

Bemærk, at vi har valgt at pakke stikkontakterne InputStream i en DataInputStream. Dette giver os mulighed for at læse linjer i en tekst og Java primitive datatyper på en bærbar måde.

Dette er pænt siden nu, hvis vi kender typen af ​​data, vi modtager, vi kan bruge specialiserede metoder som f.eks readChar (), readInt (), readDouble ()og readLine ().

Det kan dog være udfordrende, hvis datatype og længde ikke kendes på forhånd.

I så fald får vi i stedet en strøm af bytes fra stikket ved hjælp af det lavere niveau Læs() fungere. Men der er et lille problem i denne tilgang: Hvordan ved vi længden og typen af ​​data, vi får?

Lad os undersøge dette scenarie i næste afsnit.

3. Læsning af binære data fra en stikkontakt

Når vi læser data i byte, skal vi definere vores egen protokol til kommunikation mellem server og klient. Den enkleste protokol, som vi kan definere, kaldes TLV (Type Length Value). Det betyder, at hver besked, der skrives til stikkontakten, er i form af Type Length Value.

Så vi definerer hver besked, der sendes som:

  • A 1 byte tegn, der repræsenterer datatypen, ligesom s til Snor
  • A 4 byte heltal, der angiver længden på dataene
  • Og så de faktiske data, hvis længde netop var angivet

Når klienten og serveren har oprettet forbindelsen, følger hver besked dette format. Derefter kan vi skrive vores kode for at analysere hver besked og læse n databytes af en bestemt type.

Lad os se, hvordan vi kan implementere dette ved hjælp af et simpelt eksempel med en Snor besked.

For det første skal vi kalde readChar () funktion for at læse datatypen og derefter ringe til readInt () funktion til at læse længden af ​​den:

char dataType = in.readChar (); int længde = in.readInt ();

Derefter skal vi læse de data, vi modtager. Et vigtigt punkt at bemærke her er, at Læs() funktionen muligvis ikke kan læse alle data i et opkald. Så vi er nødt til at ringe til Læs() i et stykke løb:

if (dataType == 's') {byte [] messageByte = ny byte [længde]; boolsk ende = falsk; StringBuilder dataString = ny StringBuilder (længde); int totalBytesRead = 0; while (! end) {int currentBytesRead = in.read (messageByte); totalBytesRead = nuværendeBytesRead + totalBytesRead; hvis (totalBytesRead = længde) {end = sand; }}}

4. Kundekode til at sende data

Og hvad med klientsidekoden? Faktisk er det ret simpelt:

char type = 's'; // s for string String data = "Dette er en streng med længde 29"; byte [] dataInBytes = data.getBytes (StandardCharsets.UTF_8); out.writeChar (type); out.writeInt (dataInBytes.length); out.write (dataInBytes);

Det er alt, hvad vores klient gør!

5. Konklusion

I denne artikel diskuterede vi, hvordan man læser data fra et stik. Vi kiggede på forskellige funktioner, som hjælper os med at læse data af en bestemt type. Vi så også, hvordan man læser binære data.

Den fulde implementering af denne vejledning kan findes på GitHub.