Cum să creați o aplicație de rețea în Java (cu imagini)

Cuprins:

Cum să creați o aplicație de rețea în Java (cu imagini)
Cum să creați o aplicație de rețea în Java (cu imagini)

Video: Cum să creați o aplicație de rețea în Java (cu imagini)

Video: Cum să creați o aplicație de rețea în Java (cu imagini)
Video: LG Stylo 3: How to Take Screenshot (3 Ways) 2024, Mai
Anonim

Scrierea codului care se execută pe un anumit dispozitiv este foarte satisfăcătoare. Dar, scrierea unui cod care se execută pe mai multe dispozitive care comunică între ele este pur și simplu afirmatoare de viață. Acest articol vă va învăța cum să vă conectați și să schimbați mesaje prin rețea utilizând protocolul de control al transmisiei (TCP).

În acest articol, veți configura o aplicație care vă va conecta computerul la el însuși și, în esență, îl va face nebun - vorbiți cu el însuși. De asemenea, veți afla diferența dintre cele două fluxuri cele mai utilizate pentru rețea în Java și modul în care acestea funcționează.

Fluxuri de date și obiecte

Înainte de a vă scufunda în cod, diferența dintre cele două fluxuri utilizate în articol trebuie să fie distinsă.

Fluxuri de date

Fluxurile de date procesează tipuri și șiruri de date primitive. Datele trimise prin fluxuri de date trebuie să fie serializate manual și deserializate, ceea ce face mai dificilă transferul de date complexe. Dar fluxurile de date pot comunica cu servere și clienți scrise în alte limbi decât Java. Fluxurile brute sunt similare fluxurilor de date în acest aspect, dar fluxurile de date asigură faptul că datele sunt formatate într-un mod independent de platformă, ceea ce este benefic, deoarece ambele părți vor putea citi datele trimise.

Fluxuri de obiecte

Fluxurile de obiecte procesează tipuri de date primitive și obiecte care implementează

Serializabil

interfață. Datele trimise prin fluxuri de obiecte sunt serializate și deserializate automat, ceea ce face mai ușor transferul de date complexe. Dar fluxurile de obiecte pot comunica numai cu servere și clienți scrise în Java. De asemenea,

ObjectOutputStream

la inițializare, trimite un antet la

InputStream

a celeilalte părți care, la inițializare, blochează execuția până la primirea antetului.

Pași

Creați o aplicație de rețea în Java Step1
Creați o aplicație de rețea în Java Step1

Pasul 1. Creați o clasă

Creați o clasă și denumiți-o după cum doriți. În acest articol, va fi numit

NetworkAppExample

clasă publică NetworkAppExample {}

Creați o aplicație de rețea în Java Step2
Creați o aplicație de rețea în Java Step2

Pasul 2. Creați o metodă principală

Creați o metodă principală și declarați că ar putea genera excepții de la

Excepție

tipul și orice subclasă a acestuia - toate excepțiile. Aceasta este considerată o practică proastă, dar este acceptabilă pentru exemplele barebone.

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

Creați o aplicație de rețea în Java Step3
Creați o aplicație de rețea în Java Step3

Pasul 3. Declarați adresa serverului

Acest exemplu va folosi adresa gazdă locală și un număr de port arbitrar. Numărul portului trebuie să fie cuprins între 0 și 65535 (inclusiv). Cu toate acestea, numerele de porturi care trebuie evitate variază de la 0 la 1023 (inclusiv) deoarece sunt porturi de sistem rezervate.

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

Creați o aplicație de rețea în Java Step4
Creați o aplicație de rețea în Java Step4

Pasul 4. Creați un server

Serverul este legat de adresă și port și ascultă conexiunile primite. În Java,

ServerSocket

reprezintă punctul final al serverului și funcția sa este acceptarea de noi conexiuni.

ServerSocket

nu are fluxuri pentru citirea și trimiterea datelor, deoarece nu reprezintă conexiunea dintre un server și un client.

import java.net. InetAddress; import java.net. ServerSocket; public class NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; port int = 10430; ServerSocket server = serverSocket nou (port, 50, InetAddress.getByName (gazdă)); }}

Creați o aplicație de rețea în Java Step5
Creați o aplicație de rețea în Java Step5

Pasul 5. Începutul serverului de jurnal

În scopuri de înregistrare, imprimați pe consolă că serverul a fost pornit.

import java.net. InetAddress; import java.net. ServerSocket; public class NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; port int = 10430; ServerSocket server = serverSocket nou (port, 50, InetAddress.getByName (gazdă)); System.out.println ("Serverul a pornit."); }}

Creați o aplicație de rețea în Java Step6
Creați o aplicație de rețea în Java Step6

Pasul 6. Creați un client

Clientul este legat de adresa și portul unui server și ascultă pachetele (mesajele) după stabilirea conexiunii. În Java,

Priză

reprezintă fie un punct final al clientului conectat la server, fie o conexiune (de la server) la client și este utilizat pentru a comunica cu partea de la celălalt capăt.

import java.net. InetAddress; import java.net. ServerSocket; import java.net. Socket; public class NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; port int = 10430; ServerSocket server = serverSocket nou (port, 50, InetAddress.getByName (gazdă)); System.out.println ("Serverul a pornit."); Socket client = Socket nou (gazdă, port); }}

Creați o aplicație de rețea în Java Step7
Creați o aplicație de rețea în Java Step7

Pasul 7. Încercați conectarea jurnalului

În scopuri de înregistrare, tipăriți pe consolă că s-a încercat conectarea.

import java.net. InetAddress; import java.net. ServerSocket; import java.net. Socket; public class NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; port int = 10430; ServerSocket server = serverSocket nou (port, 50, InetAddress.getByName (gazdă)); System.out.println ("Serverul a pornit."); Socket client = Socket nou (gazdă, port); System.out.println ("Conectarea la server …"); }}

Creați o aplicație de rețea în Java Step8
Creați o aplicație de rețea în Java Step8

Pasul 8. Stabiliți conexiunea

Clienții nu se vor conecta niciodată, cu excepția cazului în care serverul ascultă și acceptă, altfel spus, stabilește conexiuni. În Java, conexiunile sunt stabilite folosind

Accept()

Metodă de

ServerSocket

clasă. Metoda va bloca execuția până când un client se conectează.

import java.net. InetAddress; import java.net. ServerSocket; import java.net. Socket; public class NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; port int = 10430; ServerSocket server = serverSocket nou (port, 50, InetAddress.getByName (gazdă)); System.out.println ("Serverul a pornit."); Socket client = Socket nou (gazdă, port); System.out.println ("Conectarea la server …"); Conexiune socket = server.accept (); }}

Creați o aplicație de rețea în Java Step9
Creați o aplicație de rețea în Java Step9

Pasul 9. Înregistrați conexiunea stabilită

În scopuri de înregistrare, tipăriți pe consolă că conexiunea dintre server și client a fost stabilită.

import java.net. InetAddress; import java.net. ServerSocket; import java.net. Socket; public class NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; port int = 10430; ServerSocket server = serverSocket nou (port, 50, InetAddress.getByName (gazdă)); System.out.println ("Serverul a pornit."); Socket client = Socket nou (gazdă, port); System.out.println ("Conectarea la server …"); Conexiune socket = server.accept (); System.out.println ("Conexiune stabilită."); }}

Creați o aplicație de rețea în Java Step10
Creați o aplicație de rețea în Java Step10

Pasul 10. Pregătiți fluxuri de comunicare

Comunicarea se face prin fluxuri și, în această aplicație, fluxurile brute de (conexiune de la) server (la client) și client trebuie să fie înlănțuite fie cu fluxuri de date, fie cu obiecte. Amintiți-vă, ambele părți trebuie să utilizeze același tip de flux.

  • Fluxuri de date

    import java.io. DataInputStream; import java.io. DataOutputStream; import java.net. InetAddress; import java.net. ServerSocket; import java.net. Socket; public class NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; port int = 10430; ServerSocket server = serverSocket nou (port, 50, InetAddress.getByName (gazdă)); System.out.println ("Serverul a pornit."); Socket client = Socket nou (gazdă, port); System.out.println ("Conectarea la server …"); Conexiune socket = server.accept (); System.out.println ("Conexiune stabilită."); DataOutputStream clientOut = new DataOutputStream (client.getOutputStream ()); DataInputStream clientIn = nou DataInputStream (client.getInputStream ()); DataOutputStream serverOut = new DataOutputStream (connection.getOutputStream ()); DataInputStream serverIn = new DataInputStream (connection.getInputStream ()); }}

  • Fluxuri de obiecte

    Când sunt utilizate mai multe fluxuri de obiecte, fluxurile de intrare trebuie inițializate în aceeași ordine ca fluxurile de ieșire, deoarece

    ObjectOutputStream

    trimite un antet către cealaltă parte și

    ObjectInputStream

    blochează execuția până când citește antetul.

    import java.io. ObjectInputStream; import java.io. ObjectOutputStream; import java.net. InetAddress; import java.net. ServerSocket; import java.net. Socket; public class NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; port int = 10430; ServerSocket server = serverSocket nou (port, 50, InetAddress.getByName (gazdă)); System.out.println ("Serverul a pornit."); Socket client = Socket nou (gazdă, port); System.out.println ("Conectarea la server …"); Conexiune socket = server.accept (); System.out.println ("Conexiune stabilită."); ObjectOutputStream clientOut = new ObjectOutputStream (client.getOutputStream ()); ObjectOutputStream serverOut = nou ObjectOutputStream (connection.getOutputStream ()); ObjectInputStream clientIn = nou ObjectInputStream (client.getInputStream ()); ObjectInputStream serverIn = nou ObjectInputStream (connection.getInputStream ()); }}

    Ordinea specificată în codul de mai sus ar putea fi mai ușor de reținut - inițializați mai întâi fluxurile de ieșire, apoi introduceți fluxurile în aceeași ordine. Cu toate acestea, o altă ordine pentru inițializarea fluxurilor de obiecte este următoarea:

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

Creați o aplicație de rețea în Java Step11
Creați o aplicație de rețea în Java Step11

Pasul 11. Înregistrați-vă că comunicarea este gata

În scopuri de înregistrare, tipăriți pe consolă că comunicarea este gata.

// cod omis import java.net. InetAddress; import java.net. ServerSocket; import java.net. Socket; public class NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; port int = 10430; ServerSocket server = serverSocket nou (port, 50, InetAddress.getByName (gazdă)); System.out.println ("Serverul a pornit."); Socket client = Socket nou (gazdă, port); System.out.println ("Conectarea la server …"); Conexiune socket = server.accept (); System.out.println ("Conexiune stabilită."); // cod omis System.out.println ("Comunicarea este gata."); }}

Creați o aplicație de rețea în Java Step12
Creați o aplicație de rețea în Java Step12

Pasul 12. Creați un mesaj

În această aplicație,

Salut Lume

textul va fi trimis la server fie ca

octet

sau

Şir

. Declarați o variabilă de tipul care depinde de fluxul utilizat. Utilizare

octet

pentru fluxurile de date și

Şir

pentru fluxurile de obiecte.

  • Fluxuri de date

    Folosind fluxuri de date, serializarea se face prin conversia obiectelor în tipuri de date primitive sau a

    Şir

    . În acest caz,

    Şir

    este convertit în

    octet

    în loc de scris folosind

    writeBytes ()

    metodă pentru a arăta cum s-ar face cu alte obiecte, cum ar fi imagini sau alte fișiere.

    import java.io. DataInputStream; import java.io. DataOutputStream; import java.net. InetAddress; import java.net. ServerSocket; import java.net. Socket; public class NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; port int = 10430; ServerSocket server = serverSocket nou (port, 50, InetAddress.getByName (gazdă)); System.out.println ("Serverul a pornit."); Socket client = Socket nou (gazdă, port); System.out.println ("Conectarea la server …"); Conexiune socket = server.accept (); System.out.println ("Conexiune stabilită."); DataOutputStream clientOut = new DataOutputStream (client.getOutputStream ()); DataInputStream clientIn = nou DataInputStream (client.getInputStream ()); DataOutputStream serverOut = new DataOutputStream (connection.getOutputStream ()); DataInputStream serverIn = new DataInputStream (connection.getInputStream ()); System.out.println ("Comunicarea este gata."); octet messageOut = "Hello World".getBytes (); }}

  • Fluxuri de obiecte

    import java.io. ObjectInputStream; import java.io. ObjectOutputStream; import java.net. InetAddress; import java.net. ServerSocket; import java.net. Socket; public class NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; port int = 10430; ServerSocket server = serverSocket nou (port, 50, InetAddress.getByName (gazdă)); System.out.println ("Serverul a pornit."); Socket client = Socket nou (gazdă, port); System.out.println ("Conectarea la server …"); Conexiune socket = server.accept (); System.out.println ("Conexiune stabilită."); ObjectOutputStream clientOut = new ObjectOutputStream (client.getOutputStream ()); ObjectOutputStream serverOut = nou ObjectOutputStream (connection.getOutputStream ()); ObjectInputStream clientIn = nou ObjectInputStream (client.getInputStream ()); ObjectInputStream serverIn = nou ObjectInputStream (connection.getInputStream ()); System.out.println ("Comunicarea este gata."); String messageOut = "Hello World"; }}

Creați o aplicație de rețea în Java Step13
Creați o aplicație de rețea în Java Step13

Pasul 13. Trimiteți mesajul

Scrieți datele în fluxul de ieșire și spălați fluxul pentru a vă asigura că datele au fost scrise în întregime.

  • Fluxuri de date

    Lungimea unui mesaj trebuie trimisă mai întâi, astfel încât cealaltă parte să știe câte octeți trebuie să citească. După ce lungimea este trimisă ca tip întreg primitiv, pot fi trimiși octeți.

    import java.io. DataInputStream; import java.io. DataOutputStream; import java.net. InetAddress; import java.net. ServerSocket; import java.net. Socket; public class NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; port int = 10430; ServerSocket server = serverSocket nou (port, 50, InetAddress.getByName (gazdă)); System.out.println ("Serverul a pornit."); Socket client = Socket nou (gazdă, port); System.out.println ("Conectarea la server …"); Conexiune socket = server.accept (); System.out.println ("Conexiune stabilită."); DataOutputStream clientOut = new DataOutputStream (client.getOutputStream ()); DataInputStream clientIn = nou DataInputStream (client.getInputStream ()); DataOutputStream serverOut = new DataOutputStream (connection.getOutputStream ()); DataInputStream serverIn = new DataInputStream (connection.getInputStream ()); System.out.println ("Comunicarea este gata."); octet messageOut = "Hello World".getBytes (); clientOut.writeInt (messageOut.length); clientOut.write (mesajOut); clientOut.flush (); }}

  • Fluxuri de obiecte

    import java.io. ObjectInputStream; import java.io. ObjectOutputStream; import java.net. InetAddress; import java.net. ServerSocket; import java.net. Socket; public class NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; port int = 10430; ServerSocket server = serverSocket nou (port, 50, InetAddress.getByName (gazdă)); System.out.println ("Serverul a pornit."); Socket client = Socket nou (gazdă, port); System.out.println ("Conectarea la server …"); Conexiune socket = server.accept (); System.out.println ("Conexiune stabilită."); ObjectOutputStream clientOut = new ObjectOutputStream (client.getOutputStream ()); ObjectOutputStream serverOut = nou ObjectOutputStream (connection.getOutputStream ()); ObjectInputStream clientIn = nou ObjectInputStream (client.getInputStream ()); ObjectInputStream serverIn = nou ObjectInputStream (connection.getInputStream ()); System.out.println ("Comunicarea este gata."); String messageOut = "Hello World"; clientOut.writeObject (mesajOut); clientOut.flush (); }}

Creați o aplicație de rețea în Java Step14
Creați o aplicație de rețea în Java Step14

Pasul 14. Înregistrați mesajul trimis

În scopuri de înregistrare, imprimați pe consolă că mesajul a fost trimis.

  • Fluxuri de date

    import java.io. DataInputStream; import java.io. DataOutputStream; import java.net. InetAddress; import java.net. ServerSocket; import java.net. Socket; public class NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; port int = 10430; ServerSocket server = serverSocket nou (port, 50, InetAddress.getByName (gazdă)); System.out.println ("Serverul a pornit."); Socket client = Socket nou (gazdă, port); System.out.println ("Conectarea la server …"); Conexiune socket = server.accept (); System.out.println ("Conexiune stabilită."); DataOutputStream clientOut = new DataOutputStream (client.getOutputStream ()); DataInputStream clientIn = nou DataInputStream (client.getInputStream ()); DataOutputStream serverOut = new DataOutputStream (connection.getOutputStream ()); DataInputStream serverIn = new DataInputStream (connection.getInputStream ()); System.out.println ("Comunicarea este gata."); octet messageOut = "Hello World".getBytes (); clientOut.writeInt (messageOut.length); clientOut.write (mesajOut); clientOut.flush (); System.out.println ("Mesaj trimis la server:" + șir nou (mesajOut)); }}

  • Fluxuri de obiecte

    import java.io. ObjectInputStream; import java.io. ObjectOutputStream; import java.net. InetAddress; import java.net. ServerSocket; import java.net. Socket; public class NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; port int = 10430; ServerSocket server = serverSocket nou (port, 50, InetAddress.getByName (gazdă)); System.out.println ("Serverul a pornit."); Socket client = Socket nou (gazdă, port); System.out.println ("Conectarea la server …"); Conexiune socket = server.accept (); System.out.println ("Conexiune stabilită."); ObjectOutputStream clientOut = new ObjectOutputStream (client.getOutputStream ()); ObjectOutputStream serverOut = nou ObjectOutputStream (connection.getOutputStream ()); ObjectInputStream clientIn = nou ObjectInputStream (client.getInputStream ()); ObjectInputStream serverIn = nou ObjectInputStream (connection.getInputStream ()); System.out.println ("Comunicarea este gata."); String messageOut = "Hello World"; clientOut.writeObject (mesajOut); clientOut.flush (); System.out.println ("Mesaj trimis la server:" + mesajOut); }}

Creați o aplicație de rețea în Java Step15
Creați o aplicație de rețea în Java Step15

Pasul 15. Citiți mesajul

Citiți datele din fluxul de intrare și convertiți-le. Deoarece știm exact tipul de date trimise, fie vom crea un

Şir

din

octet

sau turnat

Obiect

la

Şir

fără verificare, în funcție de fluxul utilizat.

  • Fluxuri de date

    Deoarece lungimea a fost trimisă mai întâi și octeții după aceea, citirea trebuie făcută în aceeași ordine. În cazul în care lungimea este zero, nu este nimic de citit. Obiectul este deserializat atunci când octeții sunt convertiți înapoi într-o instanță, în acest caz, a

    Şir

    import java.io. DataInputStream; import java.io. DataOutputStream; import java.net. InetAddress; import java.net. ServerSocket; import java.net. Socket; public class NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; port int = 10430; ServerSocket server = serverSocket nou (port, 50, InetAddress.getByName (gazdă)); System.out.println ("Serverul a pornit."); Socket client = Socket nou (gazdă, port); System.out.println ("Conectarea la server …"); Conexiune socket = server.accept (); System.out.println ("Conexiune stabilită."); DataOutputStream clientOut = new DataOutputStream (client.getOutputStream ()); DataInputStream clientIn = nou DataInputStream (client.getInputStream ()); DataOutputStream serverOut = new DataOutputStream (connection.getOutputStream ()); DataInputStream serverIn = new DataInputStream (connection.getInputStream ()); System.out.println ("Comunicarea este gata."); octet messageOut = "Hello World".getBytes (); clientOut.writeInt (messageOut.length); clientOut.write (mesajOut); clientOut.flush (); System.out.println ("Mesaj trimis la server:" + șir nou (mesajOut)); lungime int = serverIn.readInt (); if (lungime> 0) {octet messageIn = octet nou [lungime]; serverIn.readFully (messageIn, 0, messageIn.length); }}}

  • Fluxuri de obiecte

    import java.io. ObjectInputStream; import java.io. ObjectOutputStream; import java.net. InetAddress; import java.net. ServerSocket; import java.net. Socket; public class NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; port int = 10430; ServerSocket server = serverSocket nou (port, 50, InetAddress.getByName (gazdă)); System.out.println ("Serverul a pornit."); Socket client = Socket nou (gazdă, port); System.out.println ("Conectarea la server …"); Conexiune socket = server.accept (); System.out.println ("Conexiune stabilită."); ObjectOutputStream clientOut = new ObjectOutputStream (client.getOutputStream ()); ObjectOutputStream serverOut = nou ObjectOutputStream (connection.getOutputStream ()); ObjectInputStream clientIn = nou ObjectInputStream (client.getInputStream ()); ObjectInputStream serverIn = nou ObjectInputStream (connection.getInputStream ()); System.out.println ("Comunicarea este gata."); String messageOut = "Hello World"; clientOut.writeObject (mesajOut); clientOut.flush (); System.out.println ("Mesaj trimis la server:" + mesajOut); String messageIn = (String) serverIn.readObject (); }}

Creați o aplicație de rețea în Java Step16
Creați o aplicație de rețea în Java Step16

Pasul 16. Jurnal mesaj citit

În scopuri de înregistrare, tipăriți pe consolă mesajul care a fost primit și imprimați conținutul acestuia.

  • Fluxuri de date

    import java.io. DataInputStream; import java.io. DataOutputStream; import java.net. InetAddress; import java.net. ServerSocket; import java.net. Socket; public class NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; port int = 10430; ServerSocket server = serverSocket nou (port, 50, InetAddress.getByName (gazdă)); System.out.println ("Serverul a pornit."); Socket client = Socket nou (gazdă, port); System.out.println ("Conectarea la server …"); Conexiune socket = server.accept (); System.out.println ("Conexiune stabilită."); DataOutputStream clientOut = new DataOutputStream (client.getOutputStream ()); DataInputStream clientIn = nou DataInputStream (client.getInputStream ()); DataOutputStream serverOut = new DataOutputStream (connection.getOutputStream ()); DataInputStream serverIn = new DataInputStream (connection.getInputStream ()); System.out.println ("Comunicarea este gata."); octet messageOut = "Hello World".getBytes (); clientOut.writeInt (messageOut.length); clientOut.write (mesajOut); clientOut.flush (); System.out.println ("Mesaj trimis la server:" + șir nou (mesajOut)); lungime int = serverIn.readInt (); if (lungime> 0) {octet messageIn = octet nou [lungime]; serverIn.readFully (messageIn, 0, messageIn.length); System.out.println ("Mesaj primit de la client:" + șir nou (messageIn)); }}}

  • Fluxuri de obiecte

    import java.io. ObjectInputStream; import java.io. ObjectOutputStream; import java.net. InetAddress; import java.net. ServerSocket; import java.net. Socket; public class NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; port int = 10430; ServerSocket server = serverSocket nou (port, 50, InetAddress.getByName (gazdă)); System.out.println ("Serverul a pornit."); Socket client = Socket nou (gazdă, port); System.out.println ("Conectarea la server …"); Conexiune socket = server.accept (); System.out.println ("Conexiune stabilită."); ObjectOutputStream clientOut = new ObjectOutputStream (client.getOutputStream ()); ObjectOutputStream serverOut = nou ObjectOutputStream (connection.getOutputStream ()); ObjectInputStream clientIn = nou ObjectInputStream (client.getInputStream ()); ObjectInputStream serverIn = nou ObjectInputStream (connection.getInputStream ()); System.out.println ("Comunicarea este gata."); String messageOut = "Hello World"; clientOut.writeObject (mesajOut); clientOut.flush (); System.out.println ("Mesaj trimis la server:" + mesajOut); String messageIn = (String) serverIn.readObject (); System.out.println ("Mesaj primit de la client:" + messageIn); }}

Creați o aplicație de rețea în Java Step17
Creați o aplicație de rețea în Java Step17

Pasul 17. Deconectați conexiunile

Conexiunea este deconectată atunci când o parte își închide fluxurile. În Java, prin închiderea fluxului de ieșire, socketul și fluxul de intrare sunt închise, de asemenea. Odată ce o parte din celălalt capăt află că conexiunea este moartă, trebuie să-și închidă fluxul de ieșire, de asemenea, pentru a preveni scurgerile de memorie.

// cod omis import java.net. InetAddress; import java.net. ServerSocket; import java.net. Socket; public class NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; port int = 10430; ServerSocket server = serverSocket nou (port, 50, InetAddress.getByName (gazdă)); System.out.println ("Serverul a pornit."); Socket client = Socket nou (gazdă, port); System.out.println ("Conectarea la server …"); Conexiune socket = server.accept (); System.out.println ("Conexiune stabilită."); // cod omis System.out.println ("Comunicarea este gata."); // cod omis clientOut.close (); serverOut.close (); }}

Creați o aplicație de rețea în Java Step18 V2
Creați o aplicație de rețea în Java Step18 V2

Pasul 18. Deconectarea jurnalului

În scopuri de înregistrare, tipărirea la conexiunea consolă a fost deconectată.

// cod omis import java.net. InetAddress; import java.net. ServerSocket; import java.net. Socket; public class NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; port int = 10430; ServerSocket server = serverSocket nou (port, 50, InetAddress.getByName (gazdă)); System.out.println ("Serverul a pornit."); Socket client = Socket nou (gazdă, port); System.out.println ("Conectarea la server …"); Conexiune socket = server.accept (); System.out.println ("Conexiune stabilită."); // cod omis System.out.println ("Comunicarea este gata."); // cod omis clientOut.close (); serverOut.close (); System.out.println ("Conexiuni închise."); }}

Creați o aplicație de rețea în Java Step19
Creați o aplicație de rețea în Java Step19

Pasul 19. Terminați serverul

Conexiunile sunt deconectate, dar serverul este în continuare funcțional. La fel de

ServerSocket

nu este asociat cu niciun flux, trebuie închis în mod explicit prin apelare

închide()

metodă.

// cod omis import java.net. InetAddress; import java.net. ServerSocket; import java.net. Socket; public class NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; port int = 10430; ServerSocket server = serverSocket nou (port, 50, InetAddress.getByName (gazdă)); System.out.println ("Serverul a pornit."); Socket client = Socket nou (gazdă, port); System.out.println ("Conectarea la server …"); Conexiune socket = server.accept (); System.out.println ("Conexiune stabilită."); // cod omis System.out.println ("Comunicarea este gata."); // cod omis clientOut.close (); serverOut.close (); System.out.println ("Conexiuni închise."); server.close (); }}

Creați o aplicație de rețea în Java Step20
Creați o aplicație de rețea în Java Step20

Pasul 20. Terminare server server

În scopuri de înregistrare, imprimarea pe serverul consolă a fost terminată.

// cod omis import java.net. InetAddress; import java.net. ServerSocket; import java.net. Socket; public class NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; port int = 10430; ServerSocket server = serverSocket nou (port, 50, InetAddress.getByName (gazdă)); System.out.println ("Serverul a pornit."); Socket client = Socket nou (gazdă, port); System.out.println ("Conectarea la server …"); Conexiune socket = server.accept (); System.out.println ("Conexiune stabilită."); // cod omis System.out.println ("Comunicarea este gata."); // cod omis clientOut.close (); serverOut.close (); System.out.println ("Conexiuni închise."); server.close (); System.out.println ("Server terminat."); }}

Creați o aplicație de rețea în Java Step21
Creați o aplicație de rețea în Java Step21

Pasul 21. Compilați și rulați

Logarea ne-a permis să știm dacă aplicația a avut succes sau nu. Ieșire preconizată:

Serverul a început. Conectarea la server … Conexiunea stabilită. Comunicarea este gata. Mesaj trimis la server: Hello World Mesaj primit de la client: Hello World Conexiuni închise. Server terminat.

În cazul în care rezultatul dvs. nu este ca cel de mai sus, ceea ce este puțin probabil să se întâmple, există câteva soluții:

  • Dacă ieșirea se oprește la linie

    Conexiune stabilita.

    și fluxurile de obiecte sunt utilizate, spălați fiecare

    ObjectOutputStream

  • imediat după inițializare deoarece anteturile, dintr-un anumit motiv, nu au fost trimise.
  • Dacă ieșirea se imprimă

    java.net. BindException: Adresa deja utilizată

  • alegeți un număr de port diferit, deoarece cel specificat este deja utilizat.

sfaturi

  • Conectarea la un server dintr-o altă rețea se face prin conectarea la adresa IP externă a unui dispozitiv care rulează serverul care are un port redirecționat.
  • Conectarea la un server din aceeași rețea se face fie prin conectarea la adresa IP privată a unui dispozitiv care rulează serverul, fie prin redirecționarea unui port și conectarea la adresa IP externă a dispozitivului.
  • Există programe software, cum ar fi Hamachi, care permit conectarea la server pe o altă rețea fără redirecționarea unui port, dar necesită instalarea software-ului pe ambele dispozitive.

Exemple

Aplicațiile de rețea care utilizează blocarea de intrare / ieșire trebuie să utilizeze fire. Următoarele exemple arată o implementare minimalistă de server și client cu fire. Codul de rețea este în esență același cu cel din articol, cu excepția faptului că unele fragmente au fost sincronizate, mutate în fire și excepțiile sunt tratate.

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; / ** * Clasa {@code Server} reprezintă un punct final al serverului într-o rețea. {@code Server} odată legat de o anumită adresă IP * și port, stabilește conexiuni cu clienții și este capabil să comunice cu aceștia sau să le deconecteze. *

* Această clasă este threadsafe. * * @version 1.0 * @see Client * @see Connection * / public class Server implements Runnable {private ServerSocket server; Listă privată conexiuni; fir Thread privat; private final Object connectionsLock = new Object (); / ** * Construiește un {@code Server} care interacționează cu clienții pe numele de gazdă și portul specificat cu lungimea maximă solicitată * specificată pentru o coadă de clienți primiți. * * @param Adresa gazdei de utilizat. * @param port Număr de port de utilizat. * @param backlog A solicitat lungimea maximă a cozii clienților de intrare. * @throws NetworkException Dacă apare o eroare la pornirea unui server. * / Server public (String host, int port, int backlog) aruncă NetworkException {try {server = new ServerSocket (port, backlog, InetAddress.getByName (host)); } catch (UnknownHostException e) {throw new NetworkException ("Numele gazdei nu a putut fi rezolvat:" + gazda, e); } catch (IllegalArgumentException e) {throw new NetworkException ("Numărul portului trebuie să fie între 0 și 65535 (inclusiv):" + port); } catch (IOException e) {throw new NetworkException ("Serverul nu a putut fi pornit.", e); } conexiuni = Collections.synchronizedList (new ArrayList ()); fir = fir nou (acesta); thread.start (); } / ** * Construiește un {@code Server} care interacționează cu clienții pe numele gazdă și portul specificat. * * @param Adresa gazdei de legat. * @param port Număr de port de legat. * @throws NetworkException Dacă apar erori la pornirea unui server. * / Server public (String host, int port) aruncă NetworkException {aceasta (gazdă, port, 50); } / ** * Ascultă, acceptă și înregistrează conexiunile primite de la clienți. * / @Override public void run () {while (! Server.isClosed ()) {try {connections.add (new Connection (server.accept ())); } catch (SocketException e) {if (! e.getMessage (). egal cu ("Socket închis")) {e.printStackTrace (); }} catch (NetworkException | IOException e) {e.printStackTrace (); }}} / ** * Trimite date tuturor clienților înregistrați. * * @param date Date de trimis. * @throws IllegalStateException Dacă se încearcă scrierea datelor când serverul este offline. * @throws IllegalArgumentException Dacă datele de trimis sunt nule. * / difuzare publică nulă (date obiect) {if (server.isClosed ()) {aruncă o nouă IllegalStateException („Datele nu au fost trimise, serverul este offline.”); } if (data == null) {aruncă o nouă excepție IllegalArgumentException („date nule”); } sincronizat (conexiuniLock) {pentru (Conexiune conexiune: conexiuni) {încercați {connection.send (date); System.out.println ("Datele trimise clientului cu succes."); } catch (NetworkException e) {e.printStackTrace (); }}}} / ** * Trimite un mesaj de deconectare și deconectează clientul specificat. * * @param connection Client de deconectat. * @throws NetworkException Dacă apare o eroare la închiderea conexiunii. * / public void disconnect (conexiune conexiune) lansează NetworkException {if (connections.remove (connection)) {connection.close (); }} / ** * Trimite un mesaj de deconectare tuturor clienților, îi deconectează și termină serverul. * / public void close () aruncă NetworkException {synchronized (connectionsLock) {for (Conexiune conexiune: conexiuni) {try {connection.close (); } catch (NetworkException e) {e.printStackTrace (); }}} connections.clear (); încercați {server.close (); } catch (IOException e) {throw new NetworkException ("Eroare la închiderea serverului."); } în cele din urmă {thread.interrupt (); }} / ** * Returnează dacă serverul este sau nu online. * * @return True dacă serverul este online. Fals, altfel. * / public boolean isOnline () {return! server.isClosed (); } / ** * Returnează o serie de clienți înregistrați. * / 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; / ** * Clasa {@code Client} reprezintă un punct final al clientului într-o rețea. {@code Client}, odată conectat la un anumit server *, este garantat că va putea comunica numai cu serverul. Dacă alți clienți primesc sau nu datele * depinde de implementarea serverului. *

* Această clasă este threadsafe. * * @version 1.0 * @see Server * @see Connection * / public class Client {private Connection connection; / ** * Construiește un {@code Client} conectat la server pe gazda și portul specificat. * * @param Adresa gazdei de legat. * @param port Număr de port de legat. * @throws NetworkException Dacă apare o eroare la pornirea unui server. * / public Client (String host, int port) aruncă NetworkException {try {connection = new Connection (new Socket (host, port)); } catch (UnknownHostException e) {throw new NetworkException ("Numele gazdei nu a putut fi rezolvat:" + gazda, e); } catch (IllegalArgumentException e) {throw new NetworkException ("Numărul portului trebuie să fie între 0 și 65535 (inclusiv):" + port); } catch (IOException e) {throw new NetworkException ("Serverul nu a putut fi pornit.", e); }} / ** * Trimite date celeilalte părți. * * @param date Date de trimis. * @throws NetworkException Dacă scrierea în fluxul de ieșire eșuează. * @throws IllegalStateException Dacă se încearcă scrierea datelor când conexiunea este închisă. * @throws IllegalArgumentException Dacă datele de trimis sunt nule. * @throws UnsupportedOperationException Dacă se încearcă trimiterea unui tip de date neacceptat. * / public nul de trimitere (date obiect) aruncă NetworkException {connection.send (date); } / ** * Trimite un mesaj de deconectare la server și închide conexiunea cu acesta. * / public void close () aruncă NetworkException {connection.close (); } / ** * Returnează dacă clientul este sau nu conectat la server. * * @return True dacă clientul este conectat. Fals, altfel. * / public boolean isOnline () {return connection.isConnected (); } / ** * Returnează instanța {@link Connection} a clientului. * / public Connection getConnection () {returnare conexiune; }}

Conexiune.java

import java.io. DataInputStream; import java.io. DataOutputStream; import java.io. IOException; import java.net. Socket; import java.net. SocketException; / ** * Clasa {@code Connection} reprezintă fie o conexiune de la server la client, fie un punct final al clientului într-o rețea * {@code Connection}, odată conectat, poate schimba date cu alte părți sau părți, în funcție de pe un server * implementare. *

* Această clasă este threadsafe. * * @version 1.0 * @see Server * @see Client * / public class Connection implements Runnable {private Socket socket; private DataOutputStream out; private DataInputStream în; fir Thread privat; private final Object writeLock = new Object (); private final Object readLock = new Object (); / ** * Construiește {@code Connection} folosind fluxurile unui {@link Socket} specificat. * * @param socket Socket pentru a prelua fluxurile.* / Conexiune publică (socket socket) aruncă NetworkException {if (socket == null) {aruncă o nouă IllegalArgumentException ("socket null"); } this.socket = socket; încercați {out = new DataOutputStream (socket.getOutputStream ()); } catch (IOException e) {throw new NetworkException („Nu s-a putut accesa fluxul de ieșire.”, e); } încercați {in = new DataInputStream (socket.getInputStream ()); } catch (IOException e) {throw new NetworkException („Nu s-a putut accesa fluxul de intrare.”, e); } fir = fir nou (acesta); thread.start (); } / ** * Citește mesajele în timp ce conexiunea cu cealaltă parte este activă. * / @Override public void run () {while (! Socket.isClosed ()) {try {int identificator; byte bytes; sincronizat (readLock) {identificator = in.readInt (); lungime int = in.readInt (); if (lungime> 0) {octeți = octet nou [lungime]; in.readFully (octeți, 0, octeți lungime); } else {continue; }} switch (identificator) {case Identifier. INTERNAL: String command = new String (bytes); if (command.equals ("deconectați")) {if (! socket.isClosed ()) {System.out.println ("Pachetul de deconectare primit."); încercați {close (); } catch (NetworkException e) {return; } } } pauză; identificator de caz. TEXT: System.out.println ("Mesaj primit:" + șir nou (octeți)); pauză; implicit: System.out.println ("Date nerecunoscute primite."); }} catch (SocketException e) {if (! e.getMessage (). equals ("Socket închis")) {e.printStackTrace (); }} catch (IOException e) {e.printStackTrace (); }}} / ** * Trimite date către cealaltă parte. * * @param date Date de trimis. * @throws NetworkException Dacă scrierea în fluxul de ieșire eșuează. * @throws IllegalStateException Dacă se încearcă scrierea datelor când conexiunea este închisă. * @throws IllegalArgumentException Dacă datele de trimis sunt nule. * @throws UnsupportedOperationException Dacă se încearcă trimiterea unui tip de date neacceptat. * / public void send (Object data) lansează NetworkException {if (socket.isClosed ()) {throw new IllegalStateException ("Datele nu au fost trimise, conexiunea este închisă."); } if (data == null) {aruncă o nouă excepție IllegalArgumentException („date nule”); } identificator int; byte bytes; if (instance instanceof String) {identificator = Identificator. TEXT; octeți = ((Șir) date).getBytes (); } else {throw new UnsupportedOperationException ("Tip de date neacceptat:" + data.getClass ()); } încercați {synchronized (writeLock) {out.writeInt (identificator); out.writeInt (bytes.length); out.write (octeți); out.flush (); }} catch (IOException e) {throw new NetworkException ("Datele nu au putut fi trimise.", e); }} / ** * Trimite un mesaj de deconectare către și oprește conexiunea cu cealaltă parte. * / public void close () aruncă NetworkException {if (socket.isClosed ()) {aruncă o nouă IllegalStateException ("Conexiunea este deja închisă."); } try {byte message = "disconnect".getBytes (); sincronizat (writeLock) {out.writeInt (Identifier. INTERNAL); out.writeInt (message.length); out.write (mesaj); out.flush (); }} catch (IOException e) {System.out.println ("Mesajul de deconectare nu a putut fi trimis."); } încercați {synchronized (writeLock) {out.close (); }} catch (IOException e) {throw new NetworkException ("Eroare la închiderea conexiunii.", e); } în cele din urmă {thread.interrupt (); }} / ** * Returnează dacă conexiunea cu cealaltă parte este sau nu activă. * * @return Adevărat dacă conexiunea este vie. Fals, altfel. * / public boolean isConnected () {return! socket.isClosed (); }}

Identificator.java

/ ** * Clasa {@code Identifier} conține constante utilizate de {@link Connection} pentru serializarea și deserializarea datelor * trimise prin rețea. * * @version 1.0 * @vege Connection * / public final class Identifier {/ ** * Identifier pentru mesaje interne. * / public static final int INTERN = 1; / ** * Identificator pentru mesaje text. * / public static final int TEXT = 2; }

NetworkException.java

/ ** * Clasa {@code NetworkException} indică o eroare legată de rețea. * / public class NetworkException extends Exception {/ ** * Construiește un {@code NetworkException} cu {@code null} ca mesaj. * / public NetworkException () {} / ** * Construiește un {@code NetworkException} cu mesajul specificat. * * @param message Un mesaj pentru a descrie eroarea. * / public NetworkException (String message) {super (mesaj); } / ** * Construiește o {@code NetworkException} cu mesajul și cauza specificate. * * @param message Un mesaj pentru a descrie eroarea. * @param cauza O cauză de eroare. * / public NetworkException (String message, Throwable cause) {super (mesaj, cauză); } / ** * Construiește o {@code NetworkException} cu cauza specificată. * * @param cauza O cauză de eroare. * / public NetworkException (cauza aruncabilă) {super (cauza); }}

UsageExample.java

/ ** * Clasa {@code UsageExample} arată utilizarea {@link Server} și {@link Client}. Acest exemplu folosește * {@link Thread # sleep (long)} pentru a vă asigura că fiecare segment este executat, deoarece pornirea și închiderea rapidă fac ca unele * segmente să nu se execute. * * @version 1.0 * @see Server * @see Client * / public class UsageExample {public static void main (String args) throws Exception {String host = "localhost"; port int = 10430; Server server = server nou (gazdă, port); Client client = client nou (gazdă, port); Thread.sleep (100L); client.send ("Bună ziua"); server.broadcast ("Hei, fella!"); Thread.sleep (100L); server.disconnect (server.getConnections () [0]); // sau client.close () pentru a vă deconecta de la server.close () partea clientului; }}

Recomandat: