En guide til UDP i Java

1. Oversikt

I denne artikkelen vil vi utforske nettverkskommunikasjon med Java via User Datagram Protocol (UDP).

UDP er en kommunikasjonsprotokoll som sender uavhengige pakker over nettverket uten garanti for ankomst og ingen garanti for leveringsbestillingen.

Mest kommunikasjon over internett foregår over Transmission Control Protocol (TCP), men UDP har sin plass som vi skal utforske i neste avsnitt.

2. Hvorfor bruke UDP?

UDP er ganske forskjellig fra den vanligste TCP. Men før du vurderer overflatenivå ulemper med UDP, er det viktig å forstå at mangelen på overhead kan gjøre det betydelig raskere enn TCP.

Bortsett fra hastighet, må vi også huske at noen typer kommunikasjon ikke krever påliteligheten av TCP, men i stedet verdsetter lav latens. Videoen er et godt eksempel på et program som kan ha nytte av å kjøre over UDP i stedet for TCP.

3. Bygg UDP-applikasjoner

Å bygge UDP-applikasjoner ligner veldig på å bygge et TCP-system; den eneste forskjellen er at vi ikke oppretter en punkt-til-punkt-forbindelse mellom en klient og en server.

Oppsettet er veldig greit også. Java leveres med innebygd nettverksstøtte for UDP - som er en del av java.net pakke. Derfor, for å utføre nettverksoperasjoner over UDP, trenger vi bare å importere klassene fra java.net pakke: java.net.DatagramSocket og java.net.DatagramPacket.

I de følgende avsnittene vil vi lære å designe applikasjoner som kommuniserer over UDP; vi bruker den populære ekkoprotokollen for dette programmet.

Først vil vi bygge en ekkoserver som sender tilbake meldinger sendt til den, deretter en ekkoklient som bare sender en vilkårlig melding til serveren, og til slutt vil vi teste applikasjonen for å sikre at alt fungerer bra.

4. Serveren

I UDP-kommunikasjon er en enkelt melding innkapslet i en DatagramPakke som sendes gjennom en DatagramSocket.

La oss starte med å sette opp en enkel server:

offentlig klasse EchoServer utvider tråd {privat DatagramSocket-kontakt; privat boolsk løping; privat byte [] buf = ny byte [256]; offentlig EchoServer () {socket = ny DatagramSocket (4445); } public void run () {running = true; while (running) {DatagramPacket pakke = ny DatagramPacket (buf, buf.length); socket.receive (pakke); InetAddress-adresse = packet.getAddress (); int port = packet.getPort (); pakke = ny DatagramPacket (buf, buf.length, adresse, port); Streng mottatt = ny streng (packet.getData (), 0, packet.getLength ()); if (received.equals ("end")) {running = false; Fortsette; } socket.send (pakke); } socket.close (); }}

Vi skaper et globalt DatagramSocket som vi vil bruke til å sende pakker, en byte-array for å pakke inn meldingene våre, og en statusvariabel kalt løping.

For enkelhets skyld utvides serveren Tråd, slik at vi kan implementere alt i løpe metode.

Innsiden løpe, lager vi en stundsløyfe som bare går til løping blir endret til falsk av en eller annen feil eller en avslutningsmelding fra klienten.

Øverst på løkken instantierer vi a DatagramPakke for å motta innkommende meldinger.

Deretter kaller vi motta metoden på kontakten. Denne metoden blokkeres til en melding kommer, og den lagrer meldingen i byte-arrayet til DatagramPakke overført til den.

Etter å ha mottatt meldingen, henter vi adressen og porten til klienten, siden vi skal sende svaret

tilbake.

Deretter lager vi en DatagramPakke for å sende en melding til klienten. Legg merke til forskjellen i signatur med mottakspakken. Denne krever også adresse og port til klienten vi sender meldingen til.

5. Kunden

La oss nå rulle ut en enkel klient for denne nye serveren:

offentlig klasse EchoClient {privat DatagramSocket-kontakt; privat InetAddress-adresse; privat byte [] buf; offentlig EchoClient () {socket = ny DatagramSocket (); adresse = InetAddress.getByName ("localhost"); } offentlig streng sendEcho (streng msg) {buf = msg.getBytes (); DatagramPacket-pakke = ny DatagramPacket (buf, buf.length, adresse, 4445); socket.send (pakke); pakke = ny DatagramPacket (buf, buf.length); socket.receive (pakke); Streng mottatt = ny streng (packet.getData (), 0, packet.getLength ()); retur mottatt; } public void close () {socket.close (); }}

Koden er ikke så forskjellig fra serverens. Vi har vårt globale DatagramSocket og adresse til serveren. Vi instanserer disse inne i konstruktøren.

Vi har en egen metode som sender meldinger til serveren og returnerer svaret.

Vi konverterer først strengmeldingen til en byte-array, og oppretter deretter en DatagramPakke for sending av meldinger.

Neste - vi sender meldingen. Vi konverterer umiddelbart DatagramPakke inn i en mottakende.

Når ekkoet kommer, konverterer vi byte til en streng og returnerer strengen.

6. Testen

I en klasse UDPTest.java, vi oppretter ganske enkelt en test for å sjekke ekkoevnen til våre to applikasjoner:

offentlig klasse UDPTest {EchoClient-klient; @Før offentlige ugyldig oppsett () {ny EchoServer (). Start (); klient = ny EchoClient (); } @Test offentlig ugyldig nårCanSendAndReceivePacket_thenCorrect () {String echo = client.sendEcho ("hallo server"); assertEquals ("hei server", ekko); echo = client.sendEcho ("serveren fungerer"); assertFalse (echo.equals ("hallo server")); } @Efter offentlig ugyldighet tearDown () {client.sendEcho ("slutt"); client.close (); }}

I oppsettstarter vi serveren og oppretter også klienten. Mens du er i rive ned metode, sender vi en avslutningsmelding til serveren slik at den kan lukkes og samtidig lukker vi klienten.

7. Konklusjon

I denne artikkelen har vi lært om User Datagram Protocol og vellykket bygget våre egne klient-serverapplikasjoner som kommuniserer over UDP.

For å få full kildekode for eksemplene som brukes i denne artikkelen, kan du sjekke ut GitHub-prosjektet.