Kako stvoriti mrežnu aplikaciju u Javi (sa slikama)

Sadržaj:

Kako stvoriti mrežnu aplikaciju u Javi (sa slikama)
Kako stvoriti mrežnu aplikaciju u Javi (sa slikama)

Video: Kako stvoriti mrežnu aplikaciju u Javi (sa slikama)

Video: Kako stvoriti mrežnu aplikaciju u Javi (sa slikama)
Video: Ako imate iPhone, OVO MORATE ISPROBATI! 2024, April
Anonim

Pisanje koda koji se izvršava na određenom uređaju je vrlo zadovoljavajuće. No, pisanje koda koji se izvršava na nekoliko uređaja koji međusobno komuniciraju jednostavno potvrđuje život. Ovaj članak će vas naučiti kako se povezati i razmjenjivati poruke putem mreže pomoću protokola za kontrolu prijenosa (TCP).

U ovom ćete članku postaviti aplikaciju koja će povezati vaše računalo sa samim sobom i, u biti, izluditi ga - razgovarati sa samim sobom. Naučit ćete i razliku između dva najčešće korištena toka za umrežavanje u Javi i kako oni funkcioniraju.

Tokovi podataka i objekata

Prije ulaska u kôd, potrebno je razlikovati razliku između dva toka koja se koriste u članku.

Prijenosi podataka

Tokovi podataka obrađuju primitivne tipove podataka i nizove. Podaci poslani putem tokova podataka moraju se ručno serijalizirati i deserijalizirati što otežava prijenos složenih podataka. No, tokovi podataka mogu komunicirati sa poslužiteljima i klijentima napisanim na drugim jezicima osim Jave. Sirovi tokovi su slični tokovima podataka u tom aspektu, ali tokovi podataka osiguravaju da su podaci formatirani na način nezavisan od platforme, što je korisno jer će obje strane moći čitati poslane podatke.

Objekt Streams

Tokovi objekata obrađuju primitivne tipove podataka i objekte koje implementiraju

Serializable

interfejs. Podaci poslani preko tokova objekata automatski se serijaliziraju i deserijaliziraju što olakšava prijenos složenih podataka. No, objektni tokovi mogu komunicirati samo sa poslužiteljima i klijentima napisanim na Javi. Takođe,

ObjectOutputStream

nakon inicijalizacije, šalje zaglavlje u

InputStream

druge strane koja nakon inicijalizacije blokira izvršavanje dok se zaglavlje ne primi.

Koraci

Kreirajte mrežnu aplikaciju u Javi Step1
Kreirajte mrežnu aplikaciju u Javi Step1

Korak 1. Kreirajte klasu

Kreirajte klasu i dajte joj ime kako želite. U ovom članku će biti imenovan

NetworkAppExample

javna klasa NetworkAppExample {}

Kreirajte mrežnu aplikaciju u Javi Step2
Kreirajte mrežnu aplikaciju u Javi Step2

Korak 2. Kreirajte glavni metod

Kreirajte glavnu metodu i deklarirajte da bi mogla izazvati izuzetke

Izuzetak

tip i bilo koju njegovu podklasu - svi izuzeci. Ovo se smatra lošom praksom, ali je prihvatljivo za barebone primjere.

javna klasa NetworkAppExample {public static void main (String args) throws Exception {}}

Kreirajte mrežnu aplikaciju u Java Step3
Kreirajte mrežnu aplikaciju u Java Step3

Korak 3. Navedite adresu servera

Ovaj primjer će koristiti lokalnu adresu hosta i proizvoljan broj porta. Broj porta mora biti u rasponu od 0 do 65535 (uključujući). Međutim, brojevi portova koje treba izbjegavati kreću se od 0 do 1023 (uključujući) jer su rezervirani sistemski portovi.

javna klasa NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; int port = 10430; }}

Kreirajte mrežnu aplikaciju u Javi Step4
Kreirajte mrežnu aplikaciju u Javi Step4

Korak 4. Kreirajte server

Poslužitelj je vezan za adresu i port i osluškuje dolazne veze. Na Javi,

ServerSocket

predstavlja krajnju točku na poslužitelju i njena funkcija je prihvaćanje novih veza.

ServerSocket

nema tokove za čitanje i slanje podataka jer ne predstavlja vezu između poslužitelja i klijenta.

import java.net. InetAddress; import java.net. ServerSocket; javna klasa NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; int port = 10430; ServerSocket server = novi ServerSocket (port, 50, InetAddress.getByName (host)); }}

Kreirajte mrežnu aplikaciju u Javi Step5
Kreirajte mrežnu aplikaciju u Javi Step5

Korak 5. Početak poslužitelja dnevnika

Za potrebe evidentiranja, odštampajte na konzoli da je server pokrenut.

import java.net. InetAddress; import java.net. ServerSocket; javna klasa NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; int port = 10430; ServerSocket server = novi ServerSocket (port, 50, InetAddress.getByName (host)); System.out.println ("Server pokrenut."); }}

Kreirajte mrežnu aplikaciju u Javi Step6
Kreirajte mrežnu aplikaciju u Javi Step6

Korak 6. Kreirajte klijenta

Klijent je vezan za adresu i port servera i sluša pakete (poruke) nakon uspostavljanja veze. Na Javi,

Socket

predstavlja ili krajnju točku na strani klijenta povezanu na poslužitelj ili vezu (sa poslužitelja) na klijenta i koristi se za komunikaciju sa stranom na drugom kraju.

import java.net. InetAddress; import java.net. ServerSocket; import java.net. Socket; javna klasa NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; int port = 10430; ServerSocket server = novi ServerSocket (port, 50, InetAddress.getByName (host)); System.out.println ("Server pokrenut."); Socket client = novi Socket (host, port); }}

Kreirajte mrežnu aplikaciju u Javi Step7
Kreirajte mrežnu aplikaciju u Javi Step7

Korak 7. Zabilježite pokušaj povezivanja

Za potrebe evidentiranja, ispišite na konzoli pokušaj povezivanja.

import java.net. InetAddress; import java.net. ServerSocket; import java.net. Socket; javna klasa NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; int port = 10430; ServerSocket server = novi ServerSocket (port, 50, InetAddress.getByName (host)); System.out.println ("Server pokrenut."); Socket client = novi Socket (host, port); System.out.println ("Povezivanje sa serverom …"); }}

Kreirajte mrežnu aplikaciju u Javi Step8
Kreirajte mrežnu aplikaciju u Javi Step8

Korak 8. Uspostavite vezu

Klijenti se nikada neće povezati ako server ne posluša i ne prihvati, drugim riječima, uspostavi veze. U Javi se veze uspostavljaju pomoću

prihvatiti ()

metoda

ServerSocket

razred. Metoda će blokirati izvršavanje sve dok se klijent ne poveže.

import java.net. InetAddress; import java.net. ServerSocket; import java.net. Socket; javna klasa NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; int port = 10430; ServerSocket server = novi ServerSocket (port, 50, InetAddress.getByName (host)); System.out.println ("Server pokrenut."); Socket client = novi Socket (host, port); System.out.println ("Povezivanje sa serverom …"); Socket connection = server.accept (); }}

Kreirajte mrežnu aplikaciju u Javi Step9
Kreirajte mrežnu aplikaciju u Javi Step9

Korak 9. Zabilježite uspostavljenu vezu

Za potrebe evidentiranja, ispišite na konzoli da je uspostavljena veza između poslužitelja i klijenta.

import java.net. InetAddress; import java.net. ServerSocket; import java.net. Socket; javna klasa NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; int port = 10430; ServerSocket server = novi ServerSocket (port, 50, InetAddress.getByName (host)); System.out.println ("Server pokrenut."); Socket client = novi Socket (host, port); System.out.println ("Povezivanje sa serverom …"); Socket connection = server.accept (); System.out.println ("Veza uspostavljena."); }}

Kreirajte mrežnu aplikaciju u Javi Step10
Kreirajte mrežnu aplikaciju u Javi Step10

Korak 10. Pripremite komunikacijske tokove

Komunikacija se vrši putem tokova i, u ovoj aplikaciji, sirovi tokovi (povezivanje sa) servera (sa klijentom) i klijenta moraju biti povezani lancima na tokove podataka ili objekata. Upamtite, obje strane moraju koristiti istu vrstu prijenosa.

  • Tokovi podataka

    import java.io. DataInputStream; import java.io. DataOutputStream; import java.net. InetAddress; import java.net. ServerSocket; import java.net. Socket; javna klasa NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; int port = 10430; ServerSocket server = novi ServerSocket (port, 50, InetAddress.getByName (host)); System.out.println ("Server pokrenut."); Socket client = novi Socket (host, port); System.out.println ("Povezivanje sa serverom …"); Socket connection = server.accept (); System.out.println ("Veza uspostavljena."); DataOutputStream clientOut = novi DataOutputStream (client.getOutputStream ()); DataInputStream clientIn = novi DataInputStream (client.getInputStream ()); DataOutputStream serverOut = novi DataOutputStream (connection.getOutputStream ()); DataInputStream serverIn = novi DataInputStream (connection.getInputStream ()); }}

  • Objektni tokovi

    Kada se koristi više tokova objekata, ulazni tokovi moraju se inicijalizirati istim redoslijedom kao izlazni tokovi jer

    ObjectOutputStream

    šalje zaglavlje drugoj strani i

    ObjectInputStream

    blokira izvršavanje dok ne pročita zaglavlje.

    import java.io. ObjectInputStream; import java.io. ObjectOutputStream; import java.net. InetAddress; import java.net. ServerSocket; import java.net. Socket; javna klasa NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; int port = 10430; ServerSocket server = novi ServerSocket (port, 50, InetAddress.getByName (host)); System.out.println ("Server pokrenut."); Socket client = novi Socket (host, port); System.out.println ("Povezivanje sa serverom …"); Socket connection = server.accept (); System.out.println ("Veza uspostavljena."); ObjectOutputStream clientOut = novi ObjectOutputStream (client.getOutputStream ()); ObjectOutputStream serverOut = novi ObjectOutputStream (connection.getOutputStream ()); ObjectInputStream clientIn = novi ObjectInputStream (client.getInputStream ()); ObjectInputStream serverIn = novi ObjectInputStream (connection.getInputStream ()); }}

    Redoslijed naveden u gore navedenom kodu mogao bi biti lakše zapamtiti - prvo inicijalizirajte izlazne tokove, a zatim ulazne tokove istim redoslijedom. Međutim, drugi redoslijed za inicijalizaciju tokova objekata je sljedeći:

    ObjectOutputStream clientOut = novi ObjectOutputStream (client.getOutputStream ()); ObjectInputStream serverIn = novi ObjectInputStream (connection.getInputStream ()); ObjectOutputStream serverOut = novi ObjectOutputStream (connection.getOutputStream ()); ObjectInputStream clientIn = novi ObjectInputStream (client.getInputStream ());

Kreirajte mrežnu aplikaciju u Javi Step11
Kreirajte mrežnu aplikaciju u Javi Step11

Korak 11. Zapišite da je komunikacija spremna

Za potrebe evidentiranja, odštampajte na konzoli da je komunikacija spremna.

// kod izostavljen import java.net. InetAddress; import java.net. ServerSocket; import java.net. Socket; javna klasa NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; int port = 10430; ServerSocket server = novi ServerSocket (port, 50, InetAddress.getByName (host)); System.out.println ("Server pokrenut."); Socket client = novi Socket (host, port); System.out.println ("Povezivanje sa serverom …"); Socket connection = server.accept (); System.out.println ("Veza uspostavljena."); // kôd izostavljen System.out.println ("Komunikacija je spremna."); }}

Kreirajte mrežnu aplikaciju u Javi Step12
Kreirajte mrežnu aplikaciju u Javi Step12

Korak 12. Kreirajte poruku

U ovoj aplikaciji,

Zdravo svijete

tekst će biti poslan na server bilo kao

bajt

ili

String

. Deklarirajte varijablu tipa koja ovisi o korištenom toku. Upotreba

bajt

za tokove podataka i

String

za strujanje objekata.

  • Tokovi podataka

    Koristeći tokove podataka, serijalizacija se vrši pretvaranjem objekata u primitivne tipove podataka ili

    String

    . U ovom slučaju,

    String

    pretvara se u

    bajt

    umesto pisanim korišćenjem

    writeBytes ()

    metoda koja pokazuje kako bi to bilo učinjeno s drugim objektima, poput slika ili drugih datoteka.

    import java.io. DataInputStream; import java.io. DataOutputStream; import java.net. InetAddress; import java.net. ServerSocket; import java.net. Socket; javna klasa NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; int port = 10430; ServerSocket server = novi ServerSocket (port, 50, InetAddress.getByName (host)); System.out.println ("Server pokrenut."); Socket client = novi Socket (host, port); System.out.println ("Povezivanje sa serverom …"); Socket connection = server.accept (); System.out.println ("Veza uspostavljena."); DataOutputStream clientOut = novi DataOutputStream (client.getOutputStream ()); DataInputStream clientIn = novi DataInputStream (client.getInputStream ()); DataOutputStream serverOut = novi DataOutputStream (connection.getOutputStream ()); DataInputStream serverIn = novi DataInputStream (connection.getInputStream ()); System.out.println ("Komunikacija je spremna."); byte messageOut = "Zdravo Svijete".getBytes (); }}

  • Objektni tokovi

    import java.io. ObjectInputStream; import java.io. ObjectOutputStream; import java.net. InetAddress; import java.net. ServerSocket; import java.net. Socket; javna klasa NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; int port = 10430; ServerSocket server = novi ServerSocket (port, 50, InetAddress.getByName (host)); System.out.println ("Server pokrenut."); Socket client = novi Socket (host, port); System.out.println ("Povezivanje sa serverom …"); Socket connection = server.accept (); System.out.println ("Veza uspostavljena."); ObjectOutputStream clientOut = novi ObjectOutputStream (client.getOutputStream ()); ObjectOutputStream serverOut = novi ObjectOutputStream (connection.getOutputStream ()); ObjectInputStream clientIn = novi ObjectInputStream (client.getInputStream ()); ObjectInputStream serverIn = novi ObjectInputStream (connection.getInputStream ()); System.out.println ("Komunikacija je spremna."); String messageOut = "Zdravo svete"; }}

Kreirajte mrežnu aplikaciju u Javi Step13
Kreirajte mrežnu aplikaciju u Javi Step13

Korak 13. Pošaljite poruku

Upišite podatke u izlazni tok i isperite tok kako biste bili sigurni da su podaci u potpunosti zapisani.

  • Tokovi podataka

    Prvo je potrebno poslati dužinu poruke kako bi druga strana znala koliko bajtova treba pročitati. Nakon što se dužina pošalje kao primitivni cijeli broj, mogu se poslati bajtovi.

    import java.io. DataInputStream; import java.io. DataOutputStream; import java.net. InetAddress; import java.net. ServerSocket; import java.net. Socket; javna klasa NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; int port = 10430; ServerSocket server = novi ServerSocket (port, 50, InetAddress.getByName (host)); System.out.println ("Server pokrenut."); Socket client = novi Socket (host, port); System.out.println ("Povezivanje sa serverom …"); Socket connection = server.accept (); System.out.println ("Veza uspostavljena."); DataOutputStream clientOut = novi DataOutputStream (client.getOutputStream ()); DataInputStream clientIn = novi DataInputStream (client.getInputStream ()); DataOutputStream serverOut = novi DataOutputStream (connection.getOutputStream ()); DataInputStream serverIn = novi DataInputStream (connection.getInputStream ()); System.out.println ("Komunikacija je spremna."); byte messageOut = "Zdravo Svijete".getBytes (); clientOut.writeInt (messageOut.length); clientOut.write (messageOut); clientOut.flush (); }}

  • Objektni tokovi

    import java.io. ObjectInputStream; import java.io. ObjectOutputStream; import java.net. InetAddress; import java.net. ServerSocket; import java.net. Socket; javna klasa NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; int port = 10430; ServerSocket server = novi ServerSocket (port, 50, InetAddress.getByName (host)); System.out.println ("Server pokrenut."); Socket client = novi Socket (host, port); System.out.println ("Povezivanje sa serverom …"); Socket connection = server.accept (); System.out.println ("Veza uspostavljena."); ObjectOutputStream clientOut = novi ObjectOutputStream (client.getOutputStream ()); ObjectOutputStream serverOut = novi ObjectOutputStream (connection.getOutputStream ()); ObjectInputStream clientIn = novi ObjectInputStream (client.getInputStream ()); ObjectInputStream serverIn = novi ObjectInputStream (connection.getInputStream ()); System.out.println ("Komunikacija je spremna."); String messageOut = "Hello World"; clientOut.writeObject (messageOut); clientOut.flush (); }}

Kreirajte mrežnu aplikaciju u Javi Step14
Kreirajte mrežnu aplikaciju u Javi Step14

Korak 14. Zabilježite poslanu poruku

Za potrebe evidentiranja, odštampajte na konzoli poruku koja je poslata.

  • Tokovi podataka

    import java.io. DataInputStream; import java.io. DataOutputStream; import java.net. InetAddress; import java.net. ServerSocket; import java.net. Socket; javna klasa NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; int port = 10430; ServerSocket server = novi ServerSocket (port, 50, InetAddress.getByName (host)); System.out.println ("Server pokrenut."); Socket client = novi Socket (host, port); System.out.println ("Povezivanje sa serverom …"); Socket connection = server.accept (); System.out.println ("Veza uspostavljena."); DataOutputStream clientOut = novi DataOutputStream (client.getOutputStream ()); DataInputStream clientIn = novi DataInputStream (client.getInputStream ()); DataOutputStream serverOut = novi DataOutputStream (connection.getOutputStream ()); DataInputStream serverIn = novi DataInputStream (connection.getInputStream ()); System.out.println ("Komunikacija je spremna."); byte messageOut = "Zdravo Svijete".getBytes (); clientOut.writeInt (messageOut.length); clientOut.write (messageOut); clientOut.flush (); System.out.println ("Poruka poslana serveru:" + novi niz (messageOut)); }}

  • Objektni tokovi

    import java.io. ObjectInputStream; import java.io. ObjectOutputStream; import java.net. InetAddress; import java.net. ServerSocket; import java.net. Socket; javna klasa NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; int port = 10430; ServerSocket server = novi ServerSocket (port, 50, InetAddress.getByName (host)); System.out.println ("Server pokrenut."); Socket client = novi Socket (host, port); System.out.println ("Povezivanje sa serverom …"); Socket connection = server.accept (); System.out.println ("Veza uspostavljena."); ObjectOutputStream clientOut = novi ObjectOutputStream (client.getOutputStream ()); ObjectOutputStream serverOut = novi ObjectOutputStream (connection.getOutputStream ()); ObjectInputStream clientIn = novi ObjectInputStream (client.getInputStream ()); ObjectInputStream serverIn = novi ObjectInputStream (connection.getInputStream ()); System.out.println ("Komunikacija je spremna."); String messageOut = "Hello World"; clientOut.writeObject (messageOut); clientOut.flush (); System.out.println ("Poruka poslana serveru:" + messageOut); }}

Kreirajte mrežnu aplikaciju u Javi Step15
Kreirajte mrežnu aplikaciju u Javi Step15

Korak 15. Pročitajte poruku

Očitajte podatke iz ulaznog toka i pretvorite ih. Budući da znamo točno vrstu poslanih podataka, ili ćemo stvoriti

String

from

bajt

ili glumci

Object

to

String

bez provjere, ovisno o korištenom toku.

  • Tokovi podataka

    Kako je prvo poslana dužina, a kasnije bajtovi, čitanje se mora obaviti istim redoslijedom. U slučaju da je dužina nula, nema se što čitati. Objekt se deserijalizira kada se bajtovi pretvore nazad u instancu, u ovom slučaju, datoteke

    String

    import java.io. DataInputStream; import java.io. DataOutputStream; import java.net. InetAddress; import java.net. ServerSocket; import java.net. Socket; javna klasa NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; int port = 10430; ServerSocket server = novi ServerSocket (port, 50, InetAddress.getByName (host)); System.out.println ("Server pokrenut."); Socket client = novi Socket (host, port); System.out.println ("Povezivanje sa serverom …"); Socket connection = server.accept (); System.out.println ("Veza uspostavljena."); DataOutputStream clientOut = novi DataOutputStream (client.getOutputStream ()); DataInputStream clientIn = novi DataInputStream (client.getInputStream ()); DataOutputStream serverOut = novi DataOutputStream (connection.getOutputStream ()); DataInputStream serverIn = novi DataInputStream (connection.getInputStream ()); System.out.println ("Komunikacija je spremna."); byte messageOut = "Zdravo Svijete".getBytes (); clientOut.writeInt (messageOut.length); clientOut.write (messageOut); clientOut.flush (); System.out.println ("Poruka poslana serveru:" + novi niz (messageOut)); int length = serverIn.readInt (); if (dužina> 0) {byte messageIn = novi bajt [dužina]; serverIn.readFully (messageIn, 0, messageIn.length); }}}

  • Objektni tokovi

    import java.io. ObjectInputStream; import java.io. ObjectOutputStream; import java.net. InetAddress; import java.net. ServerSocket; import java.net. Socket; javna klasa NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; int port = 10430; ServerSocket server = novi ServerSocket (port, 50, InetAddress.getByName (host)); System.out.println ("Server pokrenut."); Socket client = novi Socket (host, port); System.out.println ("Povezivanje sa serverom …"); Socket connection = server.accept (); System.out.println ("Veza uspostavljena."); ObjectOutputStream clientOut = novi ObjectOutputStream (client.getOutputStream ()); ObjectOutputStream serverOut = novi ObjectOutputStream (connection.getOutputStream ()); ObjectInputStream clientIn = novi ObjectInputStream (client.getInputStream ()); ObjectInputStream serverIn = novi ObjectInputStream (connection.getInputStream ()); System.out.println ("Komunikacija je spremna."); String messageOut = "Hello World"; clientOut.writeObject (messageOut); clientOut.flush (); System.out.println ("Poruka poslana serveru:" + messageOut); String messageIn = (String) serverIn.readObject (); }}

Kreirajte mrežnu aplikaciju u Javi Step16
Kreirajte mrežnu aplikaciju u Javi Step16

Korak 16. Zapišite pročitanu poruku

Za potrebe evidentiranja, odštampajte na konzoli primljenu poruku i odštampajte njen sadržaj.

  • Tokovi podataka

    import java.io. DataInputStream; import java.io. DataOutputStream; import java.net. InetAddress; import java.net. ServerSocket; import java.net. Socket; javna klasa NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; int port = 10430; ServerSocket server = novi ServerSocket (port, 50, InetAddress.getByName (host)); System.out.println ("Server pokrenut."); Socket client = novi Socket (host, port); System.out.println ("Povezivanje sa serverom …"); Socket connection = server.accept (); System.out.println ("Veza uspostavljena."); DataOutputStream clientOut = novi DataOutputStream (client.getOutputStream ()); DataInputStream clientIn = novi DataInputStream (client.getInputStream ()); DataOutputStream serverOut = novi DataOutputStream (connection.getOutputStream ()); DataInputStream serverIn = novi DataInputStream (connection.getInputStream ()); System.out.println ("Komunikacija je spremna."); byte messageOut = "Zdravo Svijete".getBytes (); clientOut.writeInt (messageOut.length); clientOut.write (messageOut); clientOut.flush (); System.out.println ("Poruka poslana serveru:" + novi niz (messageOut)); int length = serverIn.readInt (); if (dužina> 0) {byte messageIn = novi bajt [dužina]; serverIn.readFully (messageIn, 0, messageIn.length); System.out.println ("Poruka primljena od klijenta:" + novi niz (messageIn)); }}}

  • Objektni tokovi

    import java.io. ObjectInputStream; import java.io. ObjectOutputStream; import java.net. InetAddress; import java.net. ServerSocket; import java.net. Socket; javna klasa NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; int port = 10430; ServerSocket server = novi ServerSocket (port, 50, InetAddress.getByName (host)); System.out.println ("Server pokrenut."); Socket client = novi Socket (host, port); System.out.println ("Povezivanje sa serverom …"); Socket connection = server.accept (); System.out.println ("Veza uspostavljena."); ObjectOutputStream clientOut = novi ObjectOutputStream (client.getOutputStream ()); ObjectOutputStream serverOut = novi ObjectOutputStream (connection.getOutputStream ()); ObjectInputStream clientIn = novi ObjectInputStream (client.getInputStream ()); ObjectInputStream serverIn = novi ObjectInputStream (connection.getInputStream ()); System.out.println ("Komunikacija je spremna."); String messageOut = "Hello World"; clientOut.writeObject (messageOut); clientOut.flush (); System.out.println ("Poruka poslana serveru:" + messageOut); String messageIn = (String) serverIn.readObject (); System.out.println ("Poruka primljena od klijenta:" + messageIn); }}

Kreirajte mrežnu aplikaciju u Javi Step17
Kreirajte mrežnu aplikaciju u Javi Step17

Korak 17. Prekinite veze

Veza se prekida kada jedna strana zatvori svoje tokove. U Javi, zatvaranjem izlaznog toka, zatvaraju se i povezani priključak i ulazni tok. Jednom kada strana na drugom kraju sazna da je veza prekinuta, mora zatvoriti i svoj izlazni tok kako bi spriječila curenje memorije.

// kod izostavljen import java.net. InetAddress; import java.net. ServerSocket; import java.net. Socket; javna klasa NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; int port = 10430; ServerSocket server = novi ServerSocket (port, 50, InetAddress.getByName (host)); System.out.println ("Server pokrenut."); Socket client = novi Socket (host, port); System.out.println ("Povezivanje sa serverom …"); Socket connection = server.accept (); System.out.println ("Veza uspostavljena."); // kôd izostavljen System.out.println ("Komunikacija je spremna."); // kôd izostavljen clientOut.close (); serverOut.close (); }}

Kreirajte mrežnu aplikaciju u Javi Step18 V2
Kreirajte mrežnu aplikaciju u Javi Step18 V2

Korak 18. Isključivanje dnevnika

Radi evidentiranja, veze za ispis na konzolu su prekinute.

// kod izostavljen import java.net. InetAddress; import java.net. ServerSocket; import java.net. Socket; javna klasa NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; int port = 10430; ServerSocket server = novi ServerSocket (port, 50, InetAddress.getByName (host)); System.out.println ("Server pokrenut."); Socket client = novi Socket (host, port); System.out.println ("Povezivanje sa serverom …"); Socket connection = server.accept (); System.out.println ("Veza uspostavljena."); // kôd izostavljen System.out.println ("Komunikacija je spremna."); // kôd izostavljen clientOut.close (); serverOut.close (); System.out.println ("Veze zatvorene."); }}

Kreirajte mrežnu aplikaciju u Javi Step19
Kreirajte mrežnu aplikaciju u Javi Step19

Korak 19. Zatvorite poslužitelj

Veze su prekinute, ali server je i dalje pokrenut. As

ServerSocket

nije povezan s bilo kojim tokom, potrebno ga je izričito zatvoriti pozivom

zatvori ()

metoda.

// kod izostavljen import java.net. InetAddress; import java.net. ServerSocket; import java.net. Socket; javna klasa NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; int port = 10430; ServerSocket server = novi ServerSocket (port, 50, InetAddress.getByName (host)); System.out.println ("Server pokrenut."); Socket client = novi Socket (host, port); System.out.println ("Povezivanje sa serverom …"); Socket connection = server.accept (); System.out.println ("Veza uspostavljena."); // kôd izostavljen System.out.println ("Komunikacija je spremna."); // kôd izostavljen clientOut.close (); serverOut.close (); System.out.println ("Veze zatvorene."); server.close (); }}

Kreirajte mrežnu aplikaciju u Javi Step20
Kreirajte mrežnu aplikaciju u Javi Step20

Korak 20. Zaustavljanje poslužitelja dnevnika

Za potrebe evidentiranja, štampanje na poslužitelju konzole je prekinuto.

// kod izostavljen import java.net. InetAddress; import java.net. ServerSocket; import java.net. Socket; javna klasa NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; int port = 10430; ServerSocket server = novi ServerSocket (port, 50, InetAddress.getByName (host)); System.out.println ("Server pokrenut."); Socket client = novi Socket (host, port); System.out.println ("Povezivanje sa serverom …"); Socket connection = server.accept (); System.out.println ("Veza uspostavljena."); // kôd izostavljen System.out.println ("Komunikacija je spremna."); // kôd izostavljen clientOut.close (); serverOut.close (); System.out.println ("Veze zatvorene."); server.close (); System.out.println ("Server je zatvoren."); }}

Kreirajte mrežnu aplikaciju u Javi Step21
Kreirajte mrežnu aplikaciju u Javi Step21

Korak 21. Prevedite i pokrenite

Evidentiranje nam je omogućilo da znamo je li aplikacija uspješna ili ne. Očekivani učinak:

Server pokrenut. Povezivanje sa serverom … Veza uspostavljena. Komunikacija je spremna. Poruka poslana na server: Hello World Poruka primljena od klijenta: Hello World Connections closed. Server je ukinut.

U slučaju da vaš ispis nije poput gore navedenog, što se vjerojatno neće dogoditi, postoji nekoliko rješenja:

  • Ako izlaz stane na liniju

    Veza uspostavljena.

    i koriste se tokovi objekata, isperite svaki

    ObjectOutputStream

  • odmah nakon inicijalizacije jer zaglavlja iz nekog razloga nisu poslana.
  • Ako se ispisuje

    java.net. BindException: Adresa koja se već koristi

  • odaberite drugi broj porta jer se već koristi.

Savjeti

  • Povezivanje sa serverom na drugoj mreži vrši se povezivanjem na spoljnu IP adresu uređaja koji radi na serveru koji ima prosleđeni port.
  • Povezivanje sa serverom na istoj mreži vrši se ili povezivanjem na privatnu IP adresu uređaja koji radi na serveru ili prosljeđivanjem porta i povezivanjem na vanjsku IP adresu uređaja.
  • Postoje programi, poput Hamachija, koji omogućuju povezivanje sa serverom na drugoj mreži bez prosljeđivanja porta, ali zahtijevaju instalaciju softvera na oba uređaja.

Primjeri

Mrežne aplikacije koje koriste blokiranje ulaza/izlaza moraju koristiti niti. Sljedeći primjeri prikazuju minimalističku implementaciju poslužitelja i klijenta s nitima. Kôd za umrežavanje u osnovi je isti kao u članku, osim što su neki isječci sinhronizirani, premješteni u niti i obrađeni izuzeci.

Server.java

import java.io. IOException; import java.net. InetAddress; import java.net. ServerSocket; import java.net. SocketException; import java.net. UnknownHostException; import java.util. ArrayList; import java.util. Collections; import java.util. List; /*** Klasa {@code Server} predstavlja krajnju tačku servera u mreži. {@code Server} jednom vezan za određenu IP * adresu i port, uspostavlja veze s klijentima i može komunicirati s njima ili ih prekinuti. *

* Ova klasa nije sigurna. * * @version 1.0 * @see Client * @see Connection */ javna klasa Server implementira Runnable {private ServerSocket server; privatna lista veze; privatna nit; private final Object connectionsLock = new Object (); /** * Konstruiše {@code Server} koji komunicira sa klijentima na navedenom imenu hosta i portu sa navedenom * traženom maksimalnom dužinom reda dolaznih klijenata. * * @param host Adresa hosta za upotrebu. * @param port Broj porta za upotrebu. * @param backlog Tražena maksimalna dužina reda dolaznih klijenata. * @throws NetworkException Ako dođe do greške pri pokretanju servera. */ javni poslužitelj (Niz host, int port, int zaostatak) baca NetworkException {try {server = new ServerSocket (port, backlog, InetAddress.getByName (host)); } catch (UnknownHostException e) {throw new NetworkException ("Ime hosta nije moguće rešiti:" + host, e); } catch (IllegalArgumentException e) {throw new NetworkException ("Broj porta mora biti između 0 i 65535 (uključujući))" + port); } catch (IOException e) {throw new NetworkException ("Server nije moguće pokrenuti.", e); } veze = Collections.synchronizedList (novi ArrayList ()); nit = nova nit (ovo); thread.start (); } /*** Konstruira {@code Server} koji komunicira s klijentima na navedenom imenu hosta i portu. * * @param host Adresa hosta za vezivanje. * @param port Broj porta za vezivanje. * @throws NetworkException Ako dođe do grešaka prilikom pokretanja poslužitelja. */ javni server (String host, int port) baca NetworkException {this (host, port, 50); } /*** Sluša, prihvaća i registrira dolazne veze od klijenata. */ @Override public void run () {while (! Server.isClosed ()) {try {connections.add (nova veza (server.accept ())); } catch (SocketException e) {if (! e.getMessage (). equals ("Socket closed")) {e.printStackTrace (); }} catch (NetworkException | IOException e) {e.printStackTrace (); }}} /*** Šalje podatke svim registriranim klijentima. * * @param podaci Podaci za slanje. * @throws IllegalStateException Ako se pokuša upisivanje podataka kada je server van mreže. * @throws IllegalArgumentException Ako su podaci za slanje nuli. */ javno void emitovanje (Podaci objekta) {if (server.isClosed ()) {baci novu IllegalStateException ("Podaci nisu poslati, server je van mreže."); } if (data == null) {throw new IllegalArgumentException ("null data"); } sinhronizovano (connectionsLock) {za (Veza veze: veze) {probajte {connection.send (data); System.out.println ("Podaci su uspješno poslani klijentu."); } catch (NetworkException e) {e.printStackTrace (); }}}} /*** Šalje poruku o prekidu veze i prekida vezu s navedenim klijentom. * * @param veza Klijent za prekid veze. * @throw NetworkException Ako dođe do greške pri prekidu veze. */ public void disconnect (Connection connection) baca NetworkException {if (connections.remove (connection)) {connection.close (); }} /*** Šalje poruku o prekidu veze svim klijentima, prekida ih i prekida server. */ public void close () baca NetworkException {synchronized (connectionsLock) {for (Connection connection: connections) {try {connection.close (); } catch (NetworkException e) {e.printStackTrace (); }}} links.clear (); probajte {server.close (); } catch (IOException e) {throw new NetworkException ("Greška pri zatvaranju servera."); } konačno {thread.interrupt (); }} /*** Vraća da li je server na mreži. * * @return Tačno ako je server na mreži. Netačno, inače. */ public boolean isOnline () {return! server.isClosed (); } /*** Vraća niz registriranih klijenata. */ public Connection getConnections () {synchronized (connectionsLock) {return connections.toArray (new Connection [connections.size ()]); }}}

Client.java

import java.io. IOException; import java.net. Socket; import java.net. UnknownHostException; /*** Klasa {@code Client} predstavlja krajnju tačku klijenta u mreži. {@code Client}, kada se jednom poveže na određeni * server, garantuje se da će moći komunicirati samo sa serverom. Hoće li drugi klijenti primiti podatke * ovisi o implementaciji poslužitelja. *

* Ova klasa nije sigurna. * * @verzija 1.0 * @see Server * @see Connection */ javna klasa Client {private Connection connection; /*** Konstruira {@code Client} povezan sa serverom na navedenom hostu i portu. * * @param host Adresa hosta za vezivanje. * @param port Broj porta za vezivanje. * @throws NetworkException Ako dođe do greške pri pokretanju servera. */ javni klijent (string niz, int port) baca NetworkException {try {connection = new Connection (new Socket (host, port)); } catch (UnknownHostException e) {throw new NetworkException ("Ime hosta nije moguće rešiti:" + host, e); } catch (IllegalArgumentException e) {throw new NetworkException ("Broj porta mora biti između 0 i 65535 (uključujući))" + port); } catch (IOException e) {throw new NetworkException ("Server nije moguće pokrenuti.", e); }} /*** Šalje podatke drugoj strani. * * @param podaci Podaci za slanje. * @throws NetworkException Ako pisanje na izlazni tok ne uspije. * @throws IllegalStateException Ako se pokuša upisati podatak kada je veza zatvorena. * @throws IllegalArgumentException Ako su podaci za slanje nuli. * @throws UnsupportedOperationException Ako se pokuša poslati nepodržani tip podataka. */ public void send (Podaci objekta) baca NetworkException {connection.send (data); } /*** Šalje poruku o prekidu veze s serverom i prekida vezu s njim. */ public void close () baca NetworkException {connection.close (); } /*** Vraća da li je klijent povezan sa serverom. * * @return Tačno ako je klijent povezan. Netačno, inače. */ public boolean isOnline () {return connection.isConnected (); } /*** Vraća {@link Connection} instancu klijenta. */ javna veza getConnection () {povratna veza; }}

Connection.java

import java.io. DataInputStream; import java.io. DataOutputStream; import java.io. IOException; import java.net. Socket; import java.net. SocketException; /** * Klasa {@code Connection} predstavlja ili vezu između servera i klijenta ili krajnju tačku klijenta u mreži * {@code Connection}, nakon što se poveže, može razmjenjivati podatke s drugom stranom ili stranama, ovisno o tome na implementaciji servera *. *

* Ova klasa nije sigurna. * * @version 1.0 * @see Server * @see Client */ javna klasa Veza implementira Runnable {private Socket socket; privatni DataOutputStream out; privatni DataInputStream u; privatna nit; private final Object writeLock = new Object (); private final Object readLock = new Object (); /*** Konstruira {@code Connection} koristeći tokove navedene {@link utičnice}. * * @param utičnica Utičnica za dohvaćanje tokova.*/ javna veza (utičnica utičnice) baca NetworkException {if (socket == null) {baca novu IllegalArgumentException ("null utičnica"); } this.socket = utičnica; isprobajte {out = new DataOutputStream (socket.getOutputStream ()); } catch (IOException e) {throw new NetworkException ("Nije moguće pristupiti izlaznom toku.", e); } probati {in = new DataInputStream (socket.getInputStream ()); } catch (IOException e) {throw new NetworkException ("Nije moguće pristupiti ulaznom toku.", e); } nit = nova nit (ovo); thread.start (); } /*** Čita poruke dok je veza s drugom stranom živa. */ @Override void run () {while (! Socket.isClosed ()) {try {int identifier; byte bajtova; sinhronizovano (readLock) {identifikator = in.readInt (); int length = in.readInt (); if (dužina> 0) {bajtova = novi bajt [dužina]; in.readFully (bajti, 0, bajtovi.dužina); } else {nastavi; }} prekidač (identifikator) {identifikator slučaja. INTERNAL: Naredba niza = novi niz (bajtovi); if (command.equals ("prekini vezu")) {if (! socket.isClosed ()) {System.out.println ("Prekinut paket primljen."); probajte {close (); } catch (NetworkException e) {return; }}} break; case Identifier. TEXT: System.out.println ("Poruka primljena:" + novi niz (bajtovi)); break; default: System.out.println ("Neprepoznati podaci primljeni."); }} catch (SocketException e) {if (! e.getMessage (). equals ("Socket closed")) {e.printStackTrace (); }} catch (IOException e) {e.printStackTrace (); }}} /*** Šalje podatke drugoj strani. * * @param podaci Podaci za slanje. * @throws NetworkException Ako pisanje na izlazni tok ne uspije. * @throws IllegalStateException Ako se pokuša upisati podatak kada je veza zatvorena. * @throws IllegalArgumentException Ako su podaci za slanje nuli. * @throws UnsupportedOperationException Ako se pokuša poslati nepodržani tip podataka. */ public void send (Object data) baca NetworkException {if (socket.isClosed ()) {throw new IllegalStateException ("Podaci nisu poslati, veza je zatvorena."); } if (data == null) {throw new IllegalArgumentException ("null data"); } int identifikator; byte bajtova; if (data instanceof String) {identifier = Identifier. TEXT; bajtovi = ((String) podaci).getBytes (); } else {throw new UnsupportedOperationException ("Nepodržani tip podataka:" + data.getClass ()); } probajte {synchronized (writeLock) {out.writeInt (identifikator); out.writeInt (bytes.length); out.write (bajtovi); out.flush (); }} catch (IOException e) {throw new NetworkException ("Podaci se ne mogu poslati.", e); }} /*** Šalje poruku o prekidu veze sa drugom stranom i prekida vezu. */ public void close () baca NetworkException {if (socket.isClosed ()) {baca novu IllegalStateException ("Veza je već zatvorena."); } probati {byte message = "prekinuti vezu".getBytes (); sinhronizovano (writeLock) {out.writeInt (Identifier. INTERNAL); out.writeInt (message.length); out.write (poruka); out.flush (); }} catch (IOException e) {System.out.println ("Poruka o prekidu veze nije mogla biti poslana."); } probajte {synchronized (writeLock) {out.close (); }} catch (IOException e) {throw new NetworkException ("Greška pri zatvaranju veze.", e); } konačno {thread.interrupt (); }} /*** Vraća da li je veza sa drugom stranom živa ili ne. * * @return Tačno ako je veza živa. Netačno, inače. */ public boolean isConnected () {return! socket.isClosed (); }}

Identifier.java

/** * Klasa {@code Identifier} sadrži konstante koje koristi {@link Connection} za serijalizaciju i deserijalizaciju podataka * poslanih preko mreže. * * @verzija 1.0 * @vidi vezu * / javni završni identifikator klase { / ** * Identifikator za interne poruke. */ javni statički završni int INTERNAL = 1; /*** Identifikator tekstualnih poruka. */ javni statički završni int TEXT = 2; }

NetworkException.java

/*** Klasa {@code NetworkException} označava grešku vezanu za mrežu. * / javna klasa NetworkException proširuje Exception { / *** Konstruira {@code NetworkException} sa {@code null} kao porukom. * / public NetworkException () {} / *** Konstruira {@code NetworkException} sa navedenom porukom. * * @param poruka Poruka za opis greške. */ public NetworkException (String poruka) {super (poruka); } /*** Konstruira {@code NetworkException} sa navedenom porukom i uzrokom. * * @param poruka Poruka za opis greške. * @param uzrok Uzrok greške. */ public NetworkException (string poruka, Throwable uzrok) {super (poruka, uzrok); } /*** Konstruira {@code NetworkException} s navedenim uzrokom. * * @param uzrok Uzrok greške. */ public NetworkException (Bacivi uzrok) {super (uzrok); }}

UsageExample.java

/*** Klasa {@code UsageExample} prikazuje upotrebu {@link Server} i {@link Client}. U ovim primjerima se koristi * {@link Thread#sleep (long)} kako bi se osiguralo izvršavanje svakog segmenta jer brzo pokretanje i zatvaranje dovodi do toga da se neki * segmenti ne izvršavaju. * * @version 1.0 * @see Server * @see Client */ javna klasa UsageExample {public static void main (String args) throws Exception {String host = "localhost"; int port = 10430; Server server = novi server (host, port); Klijent klijent = novi klijent (host, port); Thread.sleep (100L); client.send ("Zdravo."); server.broadcast ("Hej, momče!"); Thread.sleep (100L); server.disconnect (server.getConnections () [0]); // ili client.close () za prekid veze sa serverom na strani klijenta.close (); }}

Preporučuje se: