Vodič za UDP u Javi

1. Pregled

U ovom ćemo članku istraživati ​​mrežnu komunikaciju s Javom putem korisničkog protokola datagrama (UDP).

UDP je komunikacijski protokol koji prenosi neovisne pakete putem mreže bez jamstva dolaska i bez jamstva za redoslijed isporuke.

Većina komunikacije putem Interneta odvija se putem Protokola za kontrolu prijenosa (TCP), međutim, UDP ima svoje mjesto koje ćemo istražiti u sljedećem odjeljku.

2. Zašto koristiti UDP?

UDP se sasvim razlikuje od uobičajenog TCP-a. No, prije razmatranja nedostataka UDP-a na površini, važno je shvatiti da ga nedostatak troškova može učiniti znatno bržim od TCP-a.

Osim brzine, također moramo imati na umu da neke vrste komunikacije ne zahtijevaju pouzdanost TCP-a, već umjesto toga cijene nisku latenciju. Video je dobar primjer aplikacije koja bi mogla imati koristi od rada preko UDP-a umjesto TCP-a.

3. Izrada UDP aplikacija

Izgradnja UDP aplikacija vrlo je slična izgradnji TCP sustava; jedina je razlika što ne uspostavljamo point-to-point vezu između klijenta i poslužitelja.

Postavljanje je također vrlo jednostavno. Java se isporučuje s ugrađenom mrežnom podrškom za UDP - koja je dio java.net paket. Stoga za obavljanje mrežnih operacija putem UDP-a trebamo samo uvesti klase iz java.net paket: java.net.DatagramSocket i java.net.DatagramPacket.

U sljedećim odjeljcima naučit ćemo kako dizajnirati aplikacije koje komuniciraju putem UDP-a; koristit ćemo popularni eho protokol za ovu aplikaciju.

Prvo ćemo izraditi echo poslužitelj koji vraća natrag bilo koju poruku poslanu njemu, zatim echo klijent koji samo pošalje bilo koju proizvoljnu poruku poslužitelju i na kraju ćemo testirati aplikaciju kako bismo osigurali da sve radi u redu.

4. Poslužitelj

U UDP komunikaciji, jedna poruka je enkapsulirana u DatagramPacket koji se šalje putem a DatagramSocket.

Počnimo s postavljanjem jednostavnog poslužitelja:

javna klasa EchoServer proširuje Thread {private DatagramSocket socket; privatno logičko trčanje; privatni bajt [] buf = novi bajt [256]; javni EchoServer () {socket = novi DatagramSocket (4445); } public void run () {running = true; dok je (pokrenut) {DatagramPacket paket = novi DatagramPacket (buf, buf.length); socket.receive (paket); Adresa InetAddress = packet.getAddress (); int port = packet.getPort (); paket = novi DatagramPacket (buf, buf.length, adresa, port); String primljen = novi String (packet.getData (), 0, packet.getLength ()); if (получен.equals ("end")) {trčanje = netačno; nastaviti; } socket.send (paket); } socket.close (); }}

Mi stvaramo globalnu DatagramSocket koje ćemo u cijelosti koristiti za slanje paketa, bajtni niz za umotavanje naših poruka i statusnu varijablu koja se zove trčanje.

Radi jednostavnosti, poslužitelj se proširuje Nit, tako da možemo implementirati sve unutar trčanje metoda.

Iznutra trčanje, kreiramo while petlju koja se samo pokreće do trčanje je promijenjena u false nekom pogreškom ili porukom o prekidu od klijenta.

Na vrhu petlje instanciramo a DatagramPacket za primanje dolaznih poruka.

Dalje, nazivamo primiti metoda na utičnici. Ova metoda blokira sve dok ne stigne poruka i ona spremi poruku unutar bajt polja niza DatagramPacket prešla na njega.

Nakon primanja poruke dohvaćamo adresu i priključak klijenta, jer ćemo poslati odgovor

leđa.

Dalje, kreiramo DatagramPacket za slanje poruke klijentu. Primijetite razliku u potpisu s prijemnim paketom. Ovaj također zahtijeva adresu i port klijenta kojem šaljemo poruku.

5. Klijent

Sada izbacimo jednostavan klijent za ovaj novi poslužitelj:

javna klasa EchoClient {privatna utičnica DatagramSocket; privatna adresa InetAddress; privatni bajt [] buf; javni EchoClient () {socket = novi DatagramSocket (); adresa = InetAddress.getByName ("localhost"); } javni String sendEcho (String msg) {buf = msg.getBytes (); DatagramPacket paket = novi DatagramPacket (buf, buf.length, adresa, 4445); socket.send (paket); paket = novi DatagramPacket (buf, buf.length); socket.receive (paket); String primljen = novi String (packet.getData (), 0, packet.getLength ()); povrat primljen; } javna praznina close () {socket.close (); }}

Kôd se ne razlikuje toliko od poslužiteljskog. Mi imamo svoj globalni DatagramSocket i adresa poslužitelja. Instanciramo ih unutar konstruktora.

Imamo zasebnu metodu koja šalje poruke poslužitelju i vraća odgovor.

Prvo pretvaramo niz poruka u niz bajtova, a zatim kreiramo DatagramPacket za slanje poruka.

Dalje - šaljemo poruku. Odmah pretvaramo DatagramPacket u jedan koji prima.

Kada eho stigne, pretvaramo bajtove u niz i vraćamo niz.

6. Test

U razredu UDPTest.java, mi jednostavno kreiramo jedan test kako bismo provjerili odjek sposobnosti naše dvije aplikacije:

javna klasa UDPTest {klijent EchoClient; @Prije javnog void postavljanja () {novi EchoServer (). Start (); klijent = novi EchoClient (); } @Test public void whenCanSendAndReceivePacket_thenCorrect () {String echo = client.sendEcho ("hello server"); assertEquals ("pozdrav poslužitelju", eho); echo = client.sendEcho ("poslužitelj radi"); assertFalse (echo.equals ("pozdrav poslužitelju")); } @Nakon javne void tearDown () {client.sendEcho ("kraj"); client.close (); }}

U postaviti, pokrećemo poslužitelj i također kreiramo klijenta. Dok je u srušiti metodom, šaljemo poruku prekida poslužitelju kako bi se mogao zatvoriti i istovremeno zatvoriti klijenta.

7. Zaključak

U ovom smo članku saznali više o korisničkom protokolu datagrama i uspješno izgradili vlastite klijent-poslužiteljske aplikacije koje komuniciraju putem UDP-a.

Da biste dobili puni izvorni kod za primjere korištene u ovom članku, možete pogledati projekt GitHub.