Ako vytvoriť sieťovú aplikáciu v Jave (s obrázkami)

Obsah:

Ako vytvoriť sieťovú aplikáciu v Jave (s obrázkami)
Ako vytvoriť sieťovú aplikáciu v Jave (s obrázkami)

Video: Ako vytvoriť sieťovú aplikáciu v Jave (s obrázkami)

Video: Ako vytvoriť sieťovú aplikáciu v Jave (s obrázkami)
Video: 🟡 POCO X5 PRO - САМЫЙ ДЕТАЛЬНЫЙ ОБЗОР и ТЕСТЫ 2024, Smieť
Anonim

Písanie kódu, ktorý sa vykonáva na určitom zariadení, je veľmi uspokojujúce. Napísanie kódu, ktorý sa spustí na niekoľkých zariadeniach, ktoré navzájom komunikujú, však jednoducho potvrdzuje život. Tento článok vás naučí, ako sa pripojiť a vymieňať si správy prostredníctvom siete pomocou protokolu TCP (Transmission Control Protocol).

V tomto článku nastavíte aplikáciu, ktorá k vám pripojí počítač a v podstate ho zblázni - hovorte so sebou. Dozviete sa tiež rozdiel medzi dvoma najpoužívanejšími streammi na vytváranie sietí v Jave a ich fungovaním.

Dátové a objektové toky

Pred ponorením sa do kódu je potrebné rozlíšiť rozdiel medzi dvoma prúdmi použitými v článku.

Dátové toky

Dátové toky spracovávajú primitívne dátové typy a reťazce. Údaje odosielané cez dátové toky je potrebné ručne serializovať a deserializovať, čo sťažuje prenos komplexných údajov. Dátové toky však môžu komunikovať so servermi a klientmi napísanými v iných jazykoch ako Java. Surové toky sú v tomto aspekte podobné dátovým tokom, ale dátové toky zaisťujú, že údaje sú formátované spôsobom nezávislým na platforme, čo je výhodné, pretože obe strany budú schopné čítať odoslané údaje.

Objektové toky

Objektové toky spracovávajú primitívne dátové typy a objekty, ktoré implementujú

Serializovateľné

rozhranie. Údaje odosielané cez prúdy objektov sa automaticky serializujú a deserializujú, čo uľahčuje prenos komplexných údajov. Objektové toky však môžu komunikovať iba so servermi a klientmi napísanými v jazyku Java. Tiež,

ObjectOutputStream

pri inicializácii odošle hlavičku do súboru

InputStream

druhej strany, ktorá pri inicializácii blokuje vykonanie, kým nie je prijatá hlavička.

Kroky

Vytvorte sieťovú aplikáciu v jazyku Java Step1
Vytvorte sieťovú aplikáciu v jazyku Java Step1

Krok 1. Vytvorte triedu

Vytvorte triedu a pomenujte ju, ako chcete. V tomto článku bude pomenovaný

NetworkAppExample

verejná trieda NetworkAppExample {}

Vytvorte sieťovú aplikáciu v jazyku Java Step2
Vytvorte sieťovú aplikáciu v jazyku Java Step2

Krok 2. Vytvorte hlavnú metódu

Vytvorte hlavnú metódu a deklarujte, že môže vyvolávať výnimky z

Výnimka

typu a akejkoľvek jeho podtriedy - všetky výnimky. Toto je považované za zlú prax, ale je prijateľné pre barebone príklady.

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

Vytvorte sieťovú aplikáciu v jazyku Java Step3
Vytvorte sieťovú aplikáciu v jazyku Java Step3

Krok 3. Deklarujte adresu servera

V tomto prípade sa použije adresa lokálneho hostiteľa a ľubovoľné číslo portu. Číslo portu musí byť v rozsahu od 0 do 65535 (vrátane). Čísla portov, ktorým sa treba vyhnúť, sa však pohybujú od 0 do 1023 (vrátane), pretože ide o vyhradené systémové porty.

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

Vytvorte sieťovú aplikáciu v jazyku Java Step4
Vytvorte sieťovú aplikáciu v jazyku Java Step4

Krok 4. Vytvorte server

Server je viazaný na adresu a port a počúva prichádzajúce pripojenia. V Jave,

ServerSocket

predstavuje koncový bod na strane servera a jeho funkciou je prijímanie nových pripojení.

ServerSocket

nemá toky na čítanie a odosielanie údajov, pretože nereprezentuje spojenie medzi serverom a klientom.

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

Vytvorte sieťovú aplikáciu v jazyku Java Step5
Vytvorte sieťovú aplikáciu v jazyku Java Step5

Krok 5. Začiatok servera denníka

Na účely protokolovania vytlačte na konzolu, že server bol spustený.

import java.net. InetAddress; import java.net. ServerSocket; public class NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; int port = 10430; ServerSocket server = nový ServerSocket (port, 50, InetAddress.getByName (hostiteľ)); System.out.println ("Server spustený."); }}

Vytvorte sieťovú aplikáciu v jazyku Java Step6
Vytvorte sieťovú aplikáciu v jazyku Java Step6

Krok 6. Vytvorte klienta

Klient je viazaný na adresu a port servera a po nadviazaní spojenia počúva pakety (správy). V Jave,

Zásuvka

predstavuje buď koncový bod na strane klienta pripojený k serveru, alebo pripojenie (zo servera) ku klientovi, a slúži na komunikáciu so stranou na druhom konci.

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"; int port = 10430; ServerSocket server = nový ServerSocket (port, 50, InetAddress.getByName (hostiteľ)); System.out.println ("Server spustený."); Socket client = nový Socket (hostiteľ, port); }}

Vytvorte sieťovú aplikáciu v jazyku Java Step7
Vytvorte sieťovú aplikáciu v jazyku Java Step7

Krok 7. Pokus o pripojenie

Na účely protokolovania vytlačte na konzolu, že sa pokúsilo o pripojenie.

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"; int port = 10430; ServerSocket server = nový ServerSocket (port, 50, InetAddress.getByName (hostiteľ)); System.out.println ("Server spustený."); Socket client = nový Socket (hostiteľ, port); System.out.println ("Pripojenie k serveru …"); }}

Vytvorte sieťovú aplikáciu v jazyku Java Step8
Vytvorte sieťovú aplikáciu v jazyku Java Step8

Krok 8. Vytvorte pripojenie

Klienti sa nikdy nepripoja, pokiaľ server nepočúva a neprijíma, inými slovami, nadväzuje pripojenia. V Jave sa spojenia nadväzujú pomocou

súhlasiť()

metóda

ServerSocket

trieda. Metóda zablokuje spustenie, kým sa klient nepripojí.

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"; int port = 10430; ServerSocket server = nový ServerSocket (port, 50, InetAddress.getByName (hostiteľ)); System.out.println ("Server spustený."); Socket client = nový Socket (hostiteľ, port); System.out.println ("Pripojenie k serveru …"); Soketové pripojenie = server.accept (); }}

Vytvorte sieťovú aplikáciu v jazyku Java Step9
Vytvorte sieťovú aplikáciu v jazyku Java Step9

Krok 9. Zaznamenať nadviazané pripojenie

Na účely protokolovania vytlačte na konzolu, že bolo nadviazané spojenie medzi serverom a klientom.

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"; int port = 10430; ServerSocket server = nový ServerSocket (port, 50, InetAddress.getByName (hostiteľ)); System.out.println ("Server spustený."); Socket client = nový Socket (hostiteľ, port); System.out.println ("Pripojenie k serveru …"); Soketové pripojenie = server.accept (); System.out.println ("Pripojenie nadviazané."); }}

Vytvorte sieťovú aplikáciu v jazyku Java Step10
Vytvorte sieťovú aplikáciu v jazyku Java Step10

Krok 10. Pripravte komunikačné toky

Komunikácia prebieha cez toky a v tejto aplikácii musia byť surové toky (pripojenie z) servera (ku klientovi) a klientovi reťazené buď do dátových alebo objektových tokov. Nezabudnite, že obe strany musia používať rovnaký typ streamu.

  • Dátové toky

    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"; int port = 10430; ServerSocket server = nový ServerSocket (port, 50, InetAddress.getByName (hostiteľ)); System.out.println ("Server spustený."); Socket client = nový Socket (hostiteľ, port); System.out.println ("Pripojenie k serveru …"); Soketové pripojenie = server.accept (); System.out.println ("Pripojenie nadviazané."); DataOutputStream clientOut = nový DataOutputStream (client.getOutputStream ()); DataInputStream clientIn = nový DataInputStream (client.getInputStream ()); DataOutputStream serverOut = nový DataOutputStream (connection.getOutputStream ()); DataInputStream serverIn = nový DataInputStream (connection.getInputStream ()); }}

  • Objektové toky

    Keď sa používa viac objektových prúdov, vstupné toky sa musia inicializovať v rovnakom poradí ako výstupné toky, pretože

    ObjectOutputStream

    pošle hlavičku druhej strane a

    ObjectInputStream

    blokuje spustenie, kým neprečíta hlavičku.

    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"; int port = 10430; ServerSocket server = nový ServerSocket (port, 50, InetAddress.getByName (hostiteľ)); System.out.println ("Server spustený."); Socket client = nový Socket (hostiteľ, port); System.out.println ("Pripojenie k serveru …"); Soketové pripojenie = server.accept (); System.out.println ("Pripojenie nadviazané."); ObjectOutputStream clientOut = nový ObjectOutputStream (client.getOutputStream ()); ObjectOutputStream serverOut = nový ObjectOutputStream (connection.getOutputStream ()); ObjectInputStream clientIn = nový ObjectInputStream (client.getInputStream ()); ObjectInputStream serverIn = nový ObjectInputStream (connection.getInputStream ()); }}

    Poradie podľa vyššie uvedeného kódu môže byť jednoduchšie na zapamätanie - najskôr inicializujte výstupné toky a potom vstupné toky v rovnakom poradí. Ďalší príkaz na inicializáciu prúdov objektov je však nasledujúci:

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

Vytvorte sieťovú aplikáciu v jazyku Java Step11
Vytvorte sieťovú aplikáciu v jazyku Java Step11

Krok 11. Zaznamenajte, že komunikácia je pripravená

Na účely protokolovania vytlačte na konzolu, že komunikácia je pripravená.

// vynechaný kód 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"; int port = 10430; ServerSocket server = nový ServerSocket (port, 50, InetAddress.getByName (hostiteľ)); System.out.println ("Server spustený."); Socket client = nový Socket (hostiteľ, port); System.out.println ("Pripojenie k serveru …"); Soketové pripojenie = server.accept (); System.out.println ("Pripojenie nadviazané."); // vynechaný kód System.out.println ("Komunikácia je pripravená."); }}

Vytvorte sieťovú aplikáciu v jazyku Java Step12
Vytvorte sieťovú aplikáciu v jazyku Java Step12

Krok 12. Vytvorte správu

V tejto aplikácii,

Ahoj Svet

text bude odoslaný na server buď ako

bajt

alebo

Reťazec

. Deklarujte premennú typu, ktorý závisí od použitého streamu. Použite

bajt

pre dátové toky a

Reťazec

pre toky objektov.

  • Dátové toky

    Serializácia sa pomocou dátových tokov vykonáva prevodom objektov na primitívne dátové typy alebo

    Reťazec

    . V tomto prípade,

    Reťazec

    sa prevádza na

    bajt

    namiesto písomného použitia

    writeBytes ()

    metóda, ktorá ukazuje, ako by sa to robilo s inými objektmi, ako sú obrázky alebo iné súbory.

    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"; int port = 10430; ServerSocket server = nový ServerSocket (port, 50, InetAddress.getByName (hostiteľ)); System.out.println ("Server spustený."); Socket client = nový Socket (hostiteľ, port); System.out.println ("Pripojenie k serveru …"); Soketové pripojenie = server.accept (); System.out.println ("Pripojenie nadviazané."); DataOutputStream clientOut = nový DataOutputStream (client.getOutputStream ()); DataInputStream clientIn = nový DataInputStream (client.getInputStream ()); DataOutputStream serverOut = nový DataOutputStream (connection.getOutputStream ()); DataInputStream serverIn = nový DataInputStream (connection.getInputStream ()); System.out.println („Komunikácia je pripravená.“); byte messageOut = "Hello World".getBytes (); }}

  • Objektové toky

    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"; int port = 10430; ServerSocket server = nový ServerSocket (port, 50, InetAddress.getByName (hostiteľ)); System.out.println ("Server spustený."); Socket client = nový Socket (hostiteľ, port); System.out.println ("Pripojenie k serveru …"); Soketové pripojenie = server.accept (); System.out.println ("Pripojenie nadviazané."); ObjectOutputStream clientOut = nový ObjectOutputStream (client.getOutputStream ()); ObjectOutputStream serverOut = nový ObjectOutputStream (connection.getOutputStream ()); ObjectInputStream clientIn = nový ObjectInputStream (client.getInputStream ()); ObjectInputStream serverIn = nový ObjectInputStream (connection.getInputStream ()); System.out.println („Komunikácia je pripravená.“); String messageOut = "Hello World"; }}

Vytvorte sieťovú aplikáciu v jazyku Java Step13
Vytvorte sieťovú aplikáciu v jazyku Java Step13

Krok 13. Odošlite správu

Zapisujte údaje do výstupného toku a vypláchnite tok, aby ste sa presvedčili, že údaje boli úplne zapísané.

  • Dátové toky

    Najprv je potrebné odoslať dĺžku správy, aby druhá strana vedela, koľko bajtov potrebuje na prečítanie. Potom, čo je dĺžka odoslaná ako primitívny celočíselný typ, je možné odoslať bajty.

    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"; int port = 10430; ServerSocket server = nový ServerSocket (port, 50, InetAddress.getByName (hostiteľ)); System.out.println ("Server spustený."); Socket client = nový Socket (hostiteľ, port); System.out.println ("Pripojenie k serveru …"); Soketové pripojenie = server.accept (); System.out.println ("Pripojenie nadviazané."); DataOutputStream clientOut = nový DataOutputStream (client.getOutputStream ()); DataInputStream clientIn = nový DataInputStream (client.getInputStream ()); DataOutputStream serverOut = nový DataOutputStream (connection.getOutputStream ()); DataInputStream serverIn = nový DataInputStream (connection.getInputStream ()); System.out.println („Komunikácia je pripravená.“); byte messageOut = "Hello World".getBytes (); clientOut.writeInt (messageOut.length); clientOut.write (messageOut); clientOut.flush (); }}

  • Objektové toky

    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"; int port = 10430; ServerSocket server = nový ServerSocket (port, 50, InetAddress.getByName (hostiteľ)); System.out.println ("Server spustený."); Socket client = nový Socket (hostiteľ, port); System.out.println ("Pripojenie k serveru …"); Soketové pripojenie = server.accept (); System.out.println ("Pripojenie nadviazané."); ObjectOutputStream clientOut = nový ObjectOutputStream (client.getOutputStream ()); ObjectOutputStream serverOut = nový ObjectOutputStream (connection.getOutputStream ()); ObjectInputStream clientIn = nový ObjectInputStream (client.getInputStream ()); ObjectInputStream serverIn = nový ObjectInputStream (connection.getInputStream ()); System.out.println („Komunikácia je pripravená.“); String messageOut = "Hello World"; clientOut.writeObject (messageOut); clientOut.flush (); }}

Vytvorte sieťovú aplikáciu v jazyku Java Step14
Vytvorte sieťovú aplikáciu v jazyku Java Step14

Krok 14. Protokol odoslanej správy

Na účely protokolovania vytlačte správu, ktorá bola odoslaná, do konzoly.

  • Dátové toky

    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"; int port = 10430; ServerSocket server = nový ServerSocket (port, 50, InetAddress.getByName (hostiteľ)); System.out.println ("Server spustený."); Socket client = nový Socket (hostiteľ, port); System.out.println ("Pripojenie k serveru …"); Soketové pripojenie = server.accept (); System.out.println ("Pripojenie nadviazané."); DataOutputStream clientOut = nový DataOutputStream (client.getOutputStream ()); DataInputStream clientIn = nový DataInputStream (client.getInputStream ()); DataOutputStream serverOut = nový DataOutputStream (connection.getOutputStream ()); DataInputStream serverIn = nový DataInputStream (connection.getInputStream ()); System.out.println („Komunikácia je pripravená.“); byte messageOut = "Hello World".getBytes (); clientOut.writeInt (messageOut.length); clientOut.write (messageOut); clientOut.flush (); System.out.println ("Správa odoslaná na server:" + nový reťazec (messageOut)); }}

  • Objektové toky

    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"; int port = 10430; ServerSocket server = nový ServerSocket (port, 50, InetAddress.getByName (hostiteľ)); System.out.println ("Server spustený."); Socket client = nový Socket (hostiteľ, port); System.out.println ("Pripojenie k serveru …"); Soketové pripojenie = server.accept (); System.out.println ("Pripojenie nadviazané."); ObjectOutputStream clientOut = nový ObjectOutputStream (client.getOutputStream ()); ObjectOutputStream serverOut = nový ObjectOutputStream (connection.getOutputStream ()); ObjectInputStream clientIn = nový ObjectInputStream (client.getInputStream ()); ObjectInputStream serverIn = nový ObjectInputStream (connection.getInputStream ()); System.out.println („Komunikácia je pripravená.“); String messageOut = "Hello World"; clientOut.writeObject (messageOut); clientOut.flush (); System.out.println ("Správa odoslaná na server:" + messageOut); }}

Vytvorte sieťovú aplikáciu v jazyku Java Step15
Vytvorte sieťovú aplikáciu v jazyku Java Step15

Krok 15. Prečítajte si správu

Čítajte údaje zo vstupného toku a prevádzajte ich. Keďže presne poznáme typ odosielaných údajov, vytvoríme buď a

Reťazec

od

bajt

alebo obsadenie

Objekt

do

Reťazec

bez kontroly, v závislosti od použitého streamu.

  • Dátové toky

    Keďže bola najskôr odoslaná dĺžka a potom bajty, čítanie sa musí vykonať v rovnakom poradí. V prípade, že je dĺžka nulová, nie je čo čítať. Objekt sa deserializuje, keď sa bajty prevedú späť na inštanciu, v tomto prípade z

    Reťazec

    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"; int port = 10430; ServerSocket server = nový ServerSocket (port, 50, InetAddress.getByName (hostiteľ)); System.out.println ("Server spustený."); Socket client = nový Socket (hostiteľ, port); System.out.println ("Pripojenie k serveru …"); Soketové pripojenie = server.accept (); System.out.println ("Pripojenie nadviazané."); DataOutputStream clientOut = nový DataOutputStream (client.getOutputStream ()); DataInputStream clientIn = nový DataInputStream (client.getInputStream ()); DataOutputStream serverOut = nový DataOutputStream (connection.getOutputStream ()); DataInputStream serverIn = nový DataInputStream (connection.getInputStream ()); System.out.println („Komunikácia je pripravená.“); byte messageOut = "Hello World".getBytes (); clientOut.writeInt (messageOut.length); clientOut.write (messageOut); clientOut.flush (); System.out.println ("Správa odoslaná na server:" + nový reťazec (messageOut)); int dĺžka = serverIn.readInt (); if (dĺžka> 0) {byte messageIn = nový bajt [dĺžka]; serverIn.readFully (messageIn, 0, messageIn.length); }}}

  • Objektové toky

    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"; int port = 10430; ServerSocket server = nový ServerSocket (port, 50, InetAddress.getByName (hostiteľ)); System.out.println ("Server spustený."); Socket client = nový Socket (hostiteľ, port); System.out.println ("Pripojenie k serveru …"); Soketové pripojenie = server.accept (); System.out.println ("Pripojenie nadviazané."); ObjectOutputStream clientOut = nový ObjectOutputStream (client.getOutputStream ()); ObjectOutputStream serverOut = nový ObjectOutputStream (connection.getOutputStream ()); ObjectInputStream clientIn = nový ObjectInputStream (client.getInputStream ()); ObjectInputStream serverIn = nový ObjectInputStream (connection.getInputStream ()); System.out.println („Komunikácia je pripravená.“); String messageOut = "Hello World"; clientOut.writeObject (messageOut); clientOut.flush (); System.out.println ("Správa odoslaná na server:" + messageOut); Reťazec messageIn = (Reťazec) serverIn.readObject (); }}

Vytvorte sieťovú aplikáciu v jazyku Java Step16
Vytvorte sieťovú aplikáciu v jazyku Java Step16

Krok 16. Protokol o prečítaní správy

Na účely protokolovania vytlačte na konzolu prijatú správu a vytlačte jej obsah.

  • Dátové toky

    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"; int port = 10430; ServerSocket server = nový ServerSocket (port, 50, InetAddress.getByName (hostiteľ)); System.out.println ("Server spustený."); Socket client = nový Socket (hostiteľ, port); System.out.println ("Pripojenie k serveru …"); Soketové pripojenie = server.accept (); System.out.println ("Pripojenie nadviazané."); DataOutputStream clientOut = nový DataOutputStream (client.getOutputStream ()); DataInputStream clientIn = nový DataInputStream (client.getInputStream ()); DataOutputStream serverOut = nový DataOutputStream (connection.getOutputStream ()); DataInputStream serverIn = nový DataInputStream (connection.getInputStream ()); System.out.println („Komunikácia je pripravená.“); byte messageOut = "Hello World".getBytes (); clientOut.writeInt (messageOut.length); clientOut.write (messageOut); clientOut.flush (); System.out.println ("Správa odoslaná na server:" + nový reťazec (messageOut)); int dĺžka = serverIn.readInt (); if (dĺžka> 0) {byte messageIn = nový bajt [dĺžka]; serverIn.readFully (messageIn, 0, messageIn.length); System.out.println ("Správa prijatá od klienta:" + nový reťazec (messageIn)); }}}

  • Objektové toky

    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"; int port = 10430; ServerSocket server = nový ServerSocket (port, 50, InetAddress.getByName (hostiteľ)); System.out.println ("Server spustený."); Socket client = nový Socket (hostiteľ, port); System.out.println ("Pripojenie k serveru …"); Soketové pripojenie = server.accept (); System.out.println ("Pripojenie nadviazané."); ObjectOutputStream clientOut = nový ObjectOutputStream (client.getOutputStream ()); ObjectOutputStream serverOut = nový ObjectOutputStream (connection.getOutputStream ()); ObjectInputStream clientIn = nový ObjectInputStream (client.getInputStream ()); ObjectInputStream serverIn = nový ObjectInputStream (connection.getInputStream ()); System.out.println („Komunikácia je pripravená.“); String messageOut = "Hello World"; clientOut.writeObject (messageOut); clientOut.flush (); System.out.println ("Správa odoslaná na server:" + messageOut); Reťazec messageIn = (Reťazec) serverIn.readObject (); System.out.println ("Správa prijatá od klienta:" + messageIn); }}

Vytvorte sieťovú aplikáciu v jazyku Java Step17
Vytvorte sieťovú aplikáciu v jazyku Java Step17

Krok 17. Odpojte pripojenia

Pripojenie sa preruší, keď jedna strana zavrie svoje streamy. V Jave sa zatvorením výstupného toku zatvorí aj príslušný soket a vstupný tok. Akonáhle strana na druhom konci zistí, že pripojenie je mŕtve, musí tiež zavrieť svoj výstupný tok, aby sa zabránilo úniku pamäte.

// vynechaný kód 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"; int port = 10430; ServerSocket server = nový ServerSocket (port, 50, InetAddress.getByName (hostiteľ)); System.out.println ("Server spustený."); Socket client = nový Socket (hostiteľ, port); System.out.println ("Pripojenie k serveru …"); Soketové pripojenie = server.accept (); System.out.println ("Pripojenie nadviazané."); // vynechaný kód System.out.println ("Komunikácia je pripravená."); // kód vynechaný clientOut.close (); serverOut.close (); }}

Vytvorte sieťovú aplikáciu v jazyku Java Step18 V2
Vytvorte sieťovú aplikáciu v jazyku Java Step18 V2

Krok 18. Odpojenie denníka

Na účely protokolovania boli odpojené pripojenia k tlači na konzole.

// vynechaný kód 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"; int port = 10430; ServerSocket server = nový ServerSocket (port, 50, InetAddress.getByName (hostiteľ)); System.out.println ("Server spustený."); Socket client = nový Socket (hostiteľ, port); System.out.println ("Pripojenie k serveru …"); Soketové pripojenie = server.accept (); System.out.println ("Pripojenie nadviazané."); // vynechaný kód System.out.println ("Komunikácia je pripravená."); // kód vynechaný clientOut.close (); serverOut.close (); System.out.println („Pripojenia uzavreté.“); }}

Vytvorte sieťovú aplikáciu v jazyku Java Step19
Vytvorte sieťovú aplikáciu v jazyku Java Step19

Krok 19. Ukončite server

Pripojenia sú odpojené, ale server je stále v prevádzke. Ako

ServerSocket

nie je spojený so žiadnym streamom, treba ho výslovne zavrieť volaním

Zavrieť()

metóda.

// vynechaný kód 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"; int port = 10430; ServerSocket server = nový ServerSocket (port, 50, InetAddress.getByName (hostiteľ)); System.out.println ("Server spustený."); Socket client = nový Socket (hostiteľ, port); System.out.println ("Pripojenie k serveru …"); Soketové pripojenie = server.accept (); System.out.println ("Pripojenie nadviazané."); // vynechaný kód System.out.println ("Komunikácia je pripravená."); // kód vynechaný clientOut.close (); serverOut.close (); System.out.println („Pripojenia uzavreté.“); server.close (); }}

Vytvorte sieťovú aplikáciu v jazyku Java Step20
Vytvorte sieťovú aplikáciu v jazyku Java Step20

Krok 20. Protokol servera denníka

Na účely protokolovania bola tlač na server konzoly ukončená.

// vynechaný kód 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"; int port = 10430; ServerSocket server = nový ServerSocket (port, 50, InetAddress.getByName (hostiteľ)); System.out.println ("Server spustený."); Socket client = nový Socket (hostiteľ, port); System.out.println ("Pripojenie k serveru …"); Soketové pripojenie = server.accept (); System.out.println ("Pripojenie nadviazané."); // vynechaný kód System.out.println ("Komunikácia je pripravená."); // kód vynechaný clientOut.close (); serverOut.close (); System.out.println („Pripojenia uzavreté.“); server.close (); System.out.println („Server ukončený.“); }}

Vytvorte sieťovú aplikáciu v jazyku Java Step21
Vytvorte sieťovú aplikáciu v jazyku Java Step21

Krok 21. Zostavte a spustite

Protokolovanie nám umožnilo zistiť, či bola aplikácia úspešná alebo nie. Očakávaný výkon:

Server spustený. Pripája sa k serveru … Pripojenie bolo nadviazané. Komunikácia je pripravená. Správa odoslaná na server: Hello World Správa prijatá od klienta: Hello World Connections zatvorené. Server ukončený.

V prípade, že váš výstup nie je taký, ako je uvedený vyššie, čo je nepravdepodobné, existuje niekoľko riešení:

  • Ak sa výstup zastaví na linke

    Pripojenie nadviazané.

    a používajú sa toky objektov, prepláchnite každý

    ObjectOutputStream

  • bezprostredne po inicializácii, pretože hlavičky z nejakého dôvodu neboli odoslané.
  • Ak sa výstup vytlačí

    java.net. BindException: Adresa sa už používa

  • zvoľte iné číslo portu, pretože zadané je už použité.

Tipy

  • Pripojenie k serveru v inej sieti sa vykonáva pripojením k externej adrese IP zariadenia, na ktorom je spustený server s presmerovaným portom.
  • Pripojenie k serveru v rovnakej sieti sa vykonáva buď pripojením k súkromnej adrese IP zariadenia, na ktorom je server spustený, alebo presmerovaním portu a pripojením k externej adrese IP zariadenia.
  • Existuje softvér, napríklad Hamachi, ktorý umožňuje pripojenie k serveru v inej sieti bez presmerovania portu, ale vyžaduje inštaláciu softvéru na obe zariadenia.

Príklady

Sieťové aplikácie, ktoré používajú blokovanie vstupu/výstupu, musia používať vlákna. Nasledujúce príklady ukazujú minimalistickú implementáciu servera a klienta pomocou vlákien. Sieťový kód je v zásade rovnaký ako v článku, ibaže niektoré úryvky boli synchronizované, presunuté do vlákien a riešené výnimky.

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; /*** Trieda {@code Server} predstavuje koncový bod servera v sieti. {@code Server}, keď je viazaný na určitú adresu IP * a port, nadviaže spojenie s klientmi a je schopný s nimi komunikovať alebo ich odpojiť. *

* Táto trieda je bezpečná pre vlákna. * * @version 1.0 * @see Client * @see Connection */ public class Server implementuje spustiteľný {private ServerSocket server; súkromný zoznam spojenia; vlákno súkromného vlákna; private final Object connectionsLock = nový Object (); /** * Vytvorí {@code Server}, ktorý interaguje s klientmi na zadanom názve hostiteľa a porte so zadanou * požadovanou maximálnou dĺžkou frontu prichádzajúcich klientov. * * @param hostiteľ Adresa hostiteľa, ktorú chcete použiť. * @param port Číslo portu, ktorý sa má použiť. * @param backlog Požadovaná maximálna dĺžka frontu prichádzajúcich klientov. * @throws NetworkException Ak sa pri spustení servera vyskytne chyba. */ public Server (String host, int port, int backlog) hodí NetworkException {try {server = new ServerSocket (port, backlog, InetAddress.getByName (host)); } catch (UnknownHostException e) {throw new NetworkException ("Názov hostiteľa sa nepodarilo vyriešiť:" + host, e); } catch (IllegalArgumentException e) {throw new NetworkException ("Číslo portu musí byť medzi 0 a 65535 (vrátane):" + port); } catch (IOException e) {throw new NetworkException („Server nebolo možné spustiť.“, e); } connections = Collections.synchronizedList (new ArrayList ()); vlákno = nové vlákno (toto); thread.start (); } /*** Vytvorí {@code server}, ktorý interaguje s klientmi na zadanom názve hostiteľa a porte. * * @param hostiteľ Adresa hostiteľa na väzbu. * @param port Číslo portu na viazanie. * @throws NetworkException Ak sa pri spustení servera vyskytnú chyby. */ public Server (String host, int port) hodí NetworkException {this (host, port, 50); } /*** Počúva, prijíma a registruje prichádzajúce pripojenia od klientov. */ @Override public void run () {while (! Server.isClosed ()) {try {connections.add (new Connection (server.accept ())); } catch (SocketException e) {if (! e.getMessage (). equals ("Socket closed")) {e.printStackTrace (); }} catch (NetworkException | IOException e) {e.printStackTrace (); }}} /*** Odosiela údaje všetkým registrovaným klientom. * * @param údaje Údaje na odoslanie. * @throws IllegalStateException Ak sa pokúsite o zápis údajov, keď je server offline. * @throws IllegalArgumentException Ak sú údaje na odoslanie nulové. */ public void broadcast (Object data) {if (server.isClosed ()) {throw new IllegalStateException ("Data not sent, server is offline."); } if (data == null) {throw new IllegalArgumentException ("null data"); } synchronizované (connectionsLock) {pre (Connection connection: connections) {try {connection.send (data); System.out.println ("Údaje boli úspešne odoslané klientovi."); } catch (NetworkException e) {e.printStackTrace (); }}}} /*** Pošle správu o odpojení a odpojí zadaného klienta. * * @param pripojenie Klient sa odpojí. * @throws NetworkException Ak sa pri zatváraní pripojenia vyskytne chyba. */ public void disconnect (Connection connection) hodí NetworkException {if (connections.remove (connection)) {connection.close (); }} /*** Odošle všetkým klientom správu o odpojení, odpojí ich a ukončí server. */ public void close () hodí NetworkException {synchronized (connectionsLock) {for (Connection connection: connections) {try {connection.close (); } catch (NetworkException e) {e.printStackTrace (); }}} connections.clear (); skúste {server.close (); } catch (IOException e) {throw new NetworkException ("Chyba pri zatváraní servera."); } konečne {vlákno.interrupt (); }} /*** Vráti, či je server online. * * @return Pravda, ak je server online. Falošné, inak. */ public boolean isOnline () {return! server.isClosed (); } /*** Vráti množstvo registrovaných klientov. */ 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; /*** Trieda {@code Client} predstavuje koncový bod klienta v sieti. {@code Client}, keď je pripojený k určitému * serveru, bude zaručene schopný komunikovať iba so serverom. To, či údaje dostanú iní klienti *, závisí od implementácie servera. *

* Táto trieda je bezpečná pre vlákna. * * @version 1.0 * @viz Server * @viz Pripojenie */ klient verejnej triedy {pripojenie súkromného pripojenia; /*** Vytvorí {@code Client} pripojeného k serveru na zadanom hostiteľovi a porte. * * @param hostiteľ Adresa hostiteľa na väzbu. * @param port Číslo portu na viazanie. * @throws NetworkException Ak sa pri spustení servera vyskytne chyba. */ public Client (String host, int port) hodí NetworkException {try {connection = new Connection (new Socket (host, port)); } catch (UnknownHostException e) {throw new NetworkException ("Názov hostiteľa sa nepodarilo vyriešiť:" + host, e); } catch (IllegalArgumentException e) {throw new NetworkException ("Číslo portu musí byť medzi 0 a 65535 (vrátane):" + port); } catch (IOException e) {throw new NetworkException („Server nebolo možné spustiť.“, e); }} /*** Odošle údaje druhej strane. * * @param údaje Údaje na odoslanie. * @throws NetworkException Ak zápis do výstupného toku zlyhá. * @throws IllegalStateException Ak sa pokúsite o zápis údajov, keď je pripojenie uzavreté. * @throws IllegalArgumentException Ak sú údaje na odoslanie nulové. * @throws UnsupportedOperationException Ak sa pokúšate odoslať nepodporovaný typ údajov. */ public void send (údaje o objektoch) vyvolá NetworkException {connection.send (data); } /*** Odošle správu o odpojení na server a ukončí spojenie so serverom. */ public void close () hodí NetworkException {connection.close (); } /*** Vráti, či je klient pripojený k serveru alebo nie. * * @return True, ak je klient pripojený. Falošné, inak. */ public boolean isOnline () {return connection.isConnected (); } /*** Vráti inštanciu klienta {@link Connection}. */ public Connection getConnection () {spätné pripojenie; }}

Connection.java

import java.io. DataInputStream; import java.io. DataOutputStream; import java.io. IOException; import java.net. Socket; import java.net. SocketException; /** * Trieda {@code Connection} predstavuje buď pripojenie servera ku klientovi, alebo koncový bod klienta v sieti * {@code Connection} po pripojení si dokáže vymieňať údaje s inou stranou alebo stranami v závislosti od na implementácii servera *. *

* Táto trieda je bezpečná pre vlákna. * * @version 1.0 * @see Server * @see Client */ public class Pripojenie implementuje Spustiteľné {private Socket socket; súkromný DataOutputStream von; súkromný DataInputStream v; vlákno súkromného vlákna; private final Object writeLock = nový Object (); private final Objekt readLock = nový Object (); /*** Vytvára {@code Connection} pomocou streamov určeného {@link Socket}. * * @param socket Zásuvka na načítanie streamov z.*/ public Connection (Socket socket) hodí NetworkException {if (socket == null) {throw new IllegalArgumentException ("null socket"); } this.socket = socket; try {out = new DataOutputStream (socket.getOutputStream ()); } catch (IOException e) {throw new NetworkException ("Could not access output stream.", e); } try {in = new DataInputStream (socket.getInputStream ()); } catch (IOException e) {throw new NetworkException ("Could not access input stream.", e); } vlákno = nové vlákno (toto); thread.start (); } /*** Číta správy, keď je spojenie s druhou stranou živé. */ @Override public void run () {while (! Socket.isClosed ()) {try {int identifier; byte bajtov; synchronizované (readLock) {identifier = in.readInt (); int dĺžka = in.readInt (); if (dĺžka> 0) {bajtov = nový bajt [dĺžka]; in.readFully (bajty, 0, bajty.dĺžka); } else {pokračovať; }} switch (identifier) {case Identifier. INTERNAL: String command = new String (bytes); if (command.equals ("disconnect")) {if (! socket.isClosed ()) {System.out.println ("Disconnection packet prijat."); skus {zavri (); } catch (NetworkException e) {return; } } } prestávka; case Identifier. TEXT: System.out.println ("Prijatá správa:" + nový reťazec (bajty)); prestávka; predvolené: System.out.println ("Prijaté boli nerozpoznané údaje."); }} catch (SocketException e) {if (! e.getMessage (). equals ("Socket closed")) {e.printStackTrace (); }} catch (IOException e) {e.printStackTrace (); }}} /*** Odošle údaje druhej strane. * * @param údaje Údaje na odoslanie. * @throws NetworkException Ak zápis do výstupného toku zlyhá. * @throws IllegalStateException Ak sa pokúsite o zápis údajov, keď je pripojenie uzavreté. * @throws IllegalArgumentException Ak sú údaje na odoslanie nulové. * @throws UnsupportedOperationException Ak sa pokúšate odoslať nepodporovaný typ údajov. */ public void send (Údaje o objektoch) vyvolá NetworkException {if (socket.isClosed ()) {throw new IllegalStateException („Údaje neboli odoslané, pripojenie je uzavreté.“); } if (data == null) {throw new IllegalArgumentException ("null data"); } identifikátor int; byte bajtov; if (dátová inštancia reťazca) {identifier = Identifier. TEXT; bajty = ((Reťazec) údaje).getBytes (); } else {throw new UnsupportedOperationException ("Unsupported data type:" + data.getClass ()); } skúste {synchronizované (writeLock) {out.writeInt (identifikátor); out.writeInt (bajty.dĺžka); out.write (bajty); out.flush (); }} catch (IOException e) {throw new NetworkException ("Data could not be sent.", e); }} /*** Odošle druhej strane správu o odpojení a uzavrie s ňou spojenie. */ public void close () hodí NetworkException {if (socket.isClosed ()) {throw new IllegalStateException ("Pripojenie je už uzavreté."); } skúste {byte message = "odpojiť".getBytes (); synchronizované (writeLock) {out.writeInt (Identifier. INTERNAL); out.writeInt (message.length); out.write (správa); out.flush (); }} catch (IOException e) {System.out.println ("Správu o odpojení nebolo možné odoslať."); } skúste {synchronizované (writeLock) {out.close (); }} catch (IOException e) {throw new NetworkException („Chyba pri zatváraní pripojenia.“, e); } konečne {vlákno.interrupt (); }} /*** Vráti, či je alebo nie je nadviazané spojenie s druhou stranou. * * @return Pravda, ak je pripojenie živé. Falošné, inak. */ public boolean isConnected () {return! socket.isClosed (); }}

Identifier.java

/** * Trieda {@code Identifier} obsahuje konštanty, ktoré používa {@link Connection} na serializáciu a deserializáciu údajov * odoslaných cez sieť. * * @version 1.0 * @viz Pripojenie * / verejný identifikátor konečnej triedy { / ** * Identifikátor pre interné správy. */ public static final int INTERNAL = 1; /*** Identifikátor pre textové správy. */ public static final int TEXT = 2; }

NetworkException.java

/*** Trieda {@code NetworkException} označuje chybu súvisiacu so sieťou. * / public class NetworkException extends Exception { / *** Constructs a {@code NetworkException} with {@code null} as its message. * / public NetworkException () {} / *** Vytvorí {@code NetworkException} so zadanou správou. * * @param správa Správa popisujúca chybu. */ public NetworkException (String message) {super (message); } /*** Vytvorí {@code NetworkException} so zadanou správou a príčinou. * * @param správa Správa popisujúca chybu. * @param príčina Príčina chyby. */ public NetworkException (reťazcová správa, vyvolávacia príčina) {super (správa, príčina); } /*** Vytvorí {@code NetworkException} so zadanou príčinou. * * @param príčina Príčina chyby. */ public NetworkException (vyvolávacia príčina) {super (príčina); }}

UsageExample.java

/*** Trieda {@code UsageExample} ukazuje použitie {@link Server} a {@link Client}. Tento príklad používa * {@link Thread#sleep (long)} na zaistenie vykonania každého segmentu, pretože rýchle spustenie a zatvorenie spôsobuje, že niektoré * segmenty sa nespúšťajú. * * @version 1.0 * @viz Server * @viz Klient */ verejná trieda UsageExample {public static void main (String args) throws Exception {String host = "localhost"; int port = 10430; Server server = nový server (hostiteľ, port); Klient klienta = nový klient (hostiteľ, port); Thread.sleep (100L); client.send („Dobrý deň.“); server.broadcast („Hej, chlapče!“); Thread.sleep (100L); server.disconnect (server.getConnections () [0]); // alebo client.close () na odpojenie od server-server-server.close (); }}

Odporúča: