Een gids voor UDP in Java

1. Overzicht

In dit artikel gaan we de netwerkcommunicatie met Java onderzoeken via het User Datagram Protocol (UDP).

UDP is een communicatieprotocol dat verzendt onafhankelijke pakketten over het netwerk zonder garantie van aankomst en zonder garantie van de volgorde van aflevering.

De meeste communicatie via internet vindt plaats via het Transmission Control Protocol (TCP), maar UDP heeft zijn plaats die we in de volgende sectie zullen onderzoeken.

2. Waarom UDP gebruiken?

UDP verschilt nogal van het meer gebruikelijke TCP. Maar voordat we de nadelen van UDP op oppervlakteniveau overwegen, is het belangrijk om te begrijpen dat het gebrek aan overhead het aanzienlijk sneller kan maken dan TCP.

Afgezien van snelheid, moeten we ook onthouden dat sommige soorten communicatie niet de betrouwbaarheid van TCP vereisen, maar in plaats daarvan lage latentie waarderen. De video is een goed voorbeeld van een applicatie die baat zou kunnen hebben bij gebruik via UDP in plaats van TCP.

3. UDP-applicaties bouwen

Het bouwen van UDP-applicaties lijkt erg op het bouwen van een TCP-systeem; het enige verschil is dat we geen point-to-point-verbinding tot stand brengen tussen een client en een server.

De installatie is ook heel eenvoudig. Java wordt geleverd met ingebouwde netwerkondersteuning voor UDP - dat deel uitmaakt van het java.net pakket. Om netwerkbewerkingen via UDP uit te voeren, hoeven we daarom alleen de klassen uit het java.net pakket: java.net.DatagramSocket en java.net.DatagramPacket.

In de volgende secties zullen we leren hoe u applicaties ontwerpt die communiceren via UDP; we gebruiken het populaire echo-protocol voor deze toepassing.

Eerst zullen we een echoserver bouwen die elk bericht dat ernaar is verzonden terugstuurt, vervolgens een echoclient die zomaar een willekeurig bericht naar de server stuurt, en tot slot zullen we de toepassing testen om er zeker van te zijn dat alles goed werkt.

4. De server

Bij UDP-communicatie is een enkel bericht ingekapseld in een DatagramPacket die wordt verzonden via een DatagramSocket.

Laten we beginnen met het opzetten van een eenvoudige server:

openbare klasse EchoServer breidt Thread {private DatagramSocket socket; privé booleaanse uitvoering; privébyte [] buf = nieuwe byte [256]; openbare EchoServer () {socket = nieuwe DatagramSocket (4445); } public void run () {running = true; while (running) {DatagramPacket packet = new DatagramPacket (buf, buf.length); socket.receive (pakket); InetAddress adres = packet.getAddress (); int port = packet.getPort (); pakket = nieuw DatagramPacket (buf, buf.length, adres, poort); String ontvangen = nieuwe String (packet.getData (), 0, packet.getLength ()); if (ontvangen.equals ("end")) {running = false; doorgaan met; } socket.send (pakket); } socket.close (); }}

We creëren een globaal DatagramSocket die we overal zullen gebruiken om pakketten te verzenden, een byte-array om onze berichten in te pakken en een statusvariabele genaamd rennen.

Voor de eenvoud breidt de server zich uit Draad, zodat we alles binnen het rennen methode.

Binnen rennen, maken we een while-lus die net loopt tot rennen wordt gewijzigd in false door een fout of een beëindigingsbericht van de client.

Bovenaan de lus instantiëren we een DatagramPacket om inkomende berichten te ontvangen.

Vervolgens noemen we de te ontvangen methode op het stopcontact. Deze methode blokkeert totdat er een bericht binnenkomt en slaat het bericht op in de byte-array van de DatagramPacket doorgegeven.

Nadat we het bericht hebben ontvangen, halen we het adres en de poort van de klant op, aangezien we het antwoord gaan verzenden

terug.

Vervolgens maken we een DatagramPacket voor het sturen van een bericht naar de klant. Let op het verschil in handtekening met het ontvangende pakket. Deze vereist ook het adres en de poort van de client waarnaar we het bericht sturen.

5. De klant

Laten we nu een eenvoudige client uitrollen voor deze nieuwe server:

openbare klasse EchoClient {privé DatagramSocket-socket; privé InetAddress-adres; privé-byte [] buf; openbare EchoClient () {socket = nieuwe DatagramSocket (); address = InetAddress.getByName ("localhost"); } openbare String sendEcho (String msg) {buf = msg.getBytes (); DatagramPacket-pakket = nieuw DatagramPacket (buf, buf.length, adres, 4445); socket.send (pakket); pakket = nieuw DatagramPacket (buf, buf.length); socket.receive (pakket); String ontvangen = nieuwe String (packet.getData (), 0, packet.getLength ()); retour ontvangen; } public void close () {socket.close (); }}

De code verschilt niet zo veel van die van de server. We hebben onze globale DatagramSocket en adres van de server. We instantiëren deze binnen de constructor.

We hebben een aparte methode die berichten naar de server stuurt en het antwoord retourneert.

We converteren eerst het stringbericht naar een byte-array en maken vervolgens een DatagramPacket voor het verzenden van berichten.

Vervolgens - we sturen het bericht. We converteren het DatagramPacket in een ontvangende.

Wanneer de echo arriveert, converteren we de bytes naar een string en retourneren we de string.

6. De test

In een klas UDPTest.java, maken we eenvoudig één test om het echo-vermogen van onze twee applicaties te controleren:

openbare klasse UDPTest {EchoClient-client; @Before public void setup () {nieuwe EchoServer (). Start (); client = nieuwe EchoClient (); } @Test openbare leegte whenCanSendAndReceivePacket_thenCorrect () {String echo = client.sendEcho ("hallo server"); assertEquals ("hallo server", echo); echo = client.sendEcho ("server werkt"); assertFalse (echo.equals ("hallo server")); } @After public void tearDown () {client.sendEcho ("end"); client.close (); }}

In opstelling, we starten de server en maken ook de client aan. Terwijl in de scheuren methode, sturen we een beëindigingsbericht naar de server zodat deze kan sluiten en tegelijkertijd sluiten we de client.

7. Conclusie

In dit artikel hebben we geleerd over het User Datagram Protocol en hebben we met succes onze eigen client-servertoepassingen gebouwd die communiceren via UDP.

Om de volledige broncode te krijgen voor de voorbeelden die in dit artikel worden gebruikt, kun je het GitHub-project bekijken.