Kaip sukurti tinklo programą „Java“(su paveikslėliais)

Turinys:

Kaip sukurti tinklo programą „Java“(su paveikslėliais)
Kaip sukurti tinklo programą „Java“(su paveikslėliais)

Video: Kaip sukurti tinklo programą „Java“(su paveikslėliais)

Video: Kaip sukurti tinklo programą „Java“(su paveikslėliais)
Video: Sleek Android Design, by Jordan Jozwiak 2024, Gegužė
Anonim

Kodo, kuris vykdomas tam tikrame įrenginyje, rašymas yra labai patenkintas. Tačiau rašyti kodą, kuris vykdomas keliuose tarpusavyje bendraujančiuose įrenginiuose, tiesiog patvirtina gyvybė. Šis straipsnis išmokys jus prisijungti ir keistis pranešimais tinkle naudojant perdavimo valdymo protokolą (TCP).

Šiame straipsnyje jūs sukursite programą, kuri prijungs jūsų kompiuterį prie savęs ir iš esmės padarys jį beprotišką - kalbėkite su savimi. Taip pat sužinosite skirtumą tarp dviejų plačiausiai naudojamų „Java“tinklų kūrimo srautų ir jų veikimo.

Duomenų ir objektų srautai

Prieš pasineriant į kodą, reikia atskirti dviejų straipsnyje naudojamų srautų skirtumą.

Duomenų srautai

Duomenų srautai apdoroja primityvius duomenų tipus ir eilutes. Duomenų srautais siunčiami duomenys turi būti rankiniu būdu sugrupuoti ir deserializuoti, o tai apsunkina sudėtingų duomenų perdavimą. Tačiau duomenų srautai gali bendrauti su serveriais ir klientais, parašytais kitomis kalbomis nei „Java“. Neapdoroti srautai šiuo aspektu yra panašūs į duomenų srautus, tačiau duomenų srautai užtikrina, kad duomenys būtų suformatuoti nepriklausomai nuo platformos, o tai naudinga, nes abi šalys galės skaityti išsiųstus duomenis.

Objektų srautai

Objektų srautai apdoroja primityvius duomenų tipus ir įgyvendinamus objektus

Serijuojama

sąsaja. Duomenys, siunčiami per objektų srautus, automatiškai serijuojami ir deserializuojami, todėl lengviau perkelti sudėtingus duomenis. Tačiau objektų srautai gali bendrauti tik su serveriais ir klientais, parašytais „Java“. Taip pat,

ObjectOutputStream

inicijuojant, siunčia antraštę į

„InputStream“

kitos šalies, kuri inicijuodama blokuoja vykdymą, kol bus gauta antraštė.

Žingsniai

Sukurkite tinklo programą „Java“Step1
Sukurkite tinklo programą „Java“Step1

Žingsnis 1. Sukurkite klasę

Sukurkite klasę ir pavadinkite ją taip, kaip norite. Šiame straipsnyje jis bus pavadintas

„NetworkAppExample“

viešosios klasės „NetworkAppExample“{}

Sukurkite tinklo programą „Java“Step2
Sukurkite tinklo programą „Java“Step2

Žingsnis 2. Sukurkite pagrindinį metodą

Sukurkite pagrindinį metodą ir paskelbkite, kad jis gali sukelti išimčių

Išimtis

tipas ir bet kuris jo poklasis - visos išimtys. Tai laikoma bloga praktika, tačiau yra priimtina pavyzdžiams be kaulo.

viešosios klasės „NetworkAppExample“{public static void main (String args) metimai Išimtis {}}

Sukurkite tinklo programą „Java“Step3
Sukurkite tinklo programą „Java“Step3

Žingsnis 3. Deklaruokite serverio adresą

Šiame pavyzdyje bus naudojamas vietinio kompiuterio adresas ir savavališkas prievado numeris. Prievado numeris turi būti nuo 0 iki 65535 (imtinai). Tačiau vengiamų prievadų numeriai yra nuo 0 iki 1023 (imtinai), nes jie yra rezervuoti sistemos prievadai.

public class NetworkAppExample {public static void main (String args) metimai Išimtis {String host = "localhost"; int prievadas = 10430; }}

Sukurkite tinklo programą „Java“Step4
Sukurkite tinklo programą „Java“Step4

Žingsnis 4. Sukurkite serverį

Serveris yra susietas su adresu ir prievadu ir klauso gaunamų ryšių. „Java“,

ServerSocket

žymi serverio pusės galinį tašką ir jo funkcija yra priimti naujus ryšius.

ServerSocket

neturi srautų duomenims skaityti ir siųsti, nes neatspindi ryšio tarp serverio ir kliento.

importuoti java.net. InetAddress; importuoti java.net. ServerSocket; public class NetworkAppExample {public static void main (String args) metimai Išimtis {String host = "localhost"; int prievadas = 10430; ServerSocket serveris = naujas ServerSocket (prievadas, 50, InetAddress.getByName (priegloba)); }}

Sukurkite tinklo programą „Java“Step5
Sukurkite tinklo programą „Java“Step5

Žingsnis 5. Žurnalo serverio pradžia

Registravimo tikslais spausdinkite į konsolę, kuriame buvo paleistas serveris.

importuoti java.net. InetAddress; importuoti java.net. ServerSocket; public class NetworkAppExample {public static void main (String args) metimai Išimtis {String host = "localhost"; int prievadas = 10430; ServerSocket serveris = naujas ServerSocket (prievadas, 50, InetAddress.getByName (priegloba)); System.out.println („Serveris paleistas“); }}

Sukurkite tinklo programą „Java“Step6
Sukurkite tinklo programą „Java“Step6

Žingsnis 6. Sukurkite klientą

Klientas yra susietas su serverio adresu ir prievadu ir užmezgęs ryšį klausosi paketų (pranešimų). „Java“,

Lizdas

reiškia arba kliento pusės galinį tašką, prijungtą prie serverio, arba ryšį (iš serverio) su klientu ir yra naudojamas bendrauti su kita puse.

importuoti java.net. InetAddress; importuoti java.net. ServerSocket; importuoti java.net. Socket; public class NetworkAppExample {public static void main (String args) metimai Išimtis {String host = "localhost"; int prievadas = 10430; ServerSocket serveris = naujas ServerSocket (prievadas, 50, InetAddress.getByName (priegloba)); System.out.println („Serveris paleistas“); Lizdo klientas = naujas lizdas (priegloba, prievadas); }}

Sukurkite tinklo programą „Java“Step7
Sukurkite tinklo programą „Java“Step7

Žingsnis 7. Prisijungimo bandymas

Registravimo tikslais spausdinkite į konsolę, kad buvo bandoma prisijungti.

importuoti java.net. InetAddress; importuoti java.net. ServerSocket; importuoti java.net. Socket; public class NetworkAppExample {public static void main (String args) metimai Išimtis {String host = "localhost"; int prievadas = 10430; ServerSocket serveris = naujas ServerSocket (prievadas, 50, InetAddress.getByName (priegloba)); System.out.println („Serveris paleistas“); Lizdo klientas = naujas lizdas (priegloba, prievadas); System.out.println („Prisijungimas prie serverio …“); }}

Sukurkite tinklo programą „Java“Step8
Sukurkite tinklo programą „Java“Step8

Žingsnis 8. Užmegzkite ryšį

Klientai niekada neprisijungs, nebent serveris klausys ir nepriims, kitaip tariant, nenustatys ryšių. „Java“ryšiai užmezgami naudojant

priimti()

metodas

ServerSocket

klasė. Metodas blokuoja vykdymą, kol klientas prisijungs.

importuoti java.net. InetAddress; importuoti java.net. ServerSocket; importuoti java.net. Socket; public class NetworkAppExample {public static void main (String args) metimai Išimtis {String host = "localhost"; int prievadas = 10430; ServerSocket serveris = naujas ServerSocket (prievadas, 50, InetAddress.getByName (priegloba)); System.out.println („Serveris paleistas“); Lizdo klientas = naujas lizdas (priegloba, prievadas); System.out.println („Prisijungimas prie serverio …“); Lizdas jungtis = server.accept (); }}

Sukurkite tinklo programą „Java“Step9
Sukurkite tinklo programą „Java“Step9

Žingsnis 9. Prisijunkite prie užmegzto ryšio

Registravimo tikslais į konsolę atspausdinkite, kad užmegztas ryšys tarp serverio ir kliento.

importuoti java.net. InetAddress; importuoti java.net. ServerSocket; importuoti java.net. Socket; public class NetworkAppExample {public static void main (String args) metimai Išimtis {String host = "localhost"; int prievadas = 10430; ServerSocket serveris = naujas ServerSocket (prievadas, 50, InetAddress.getByName (priegloba)); System.out.println („Serveris paleistas“); Lizdo klientas = naujas lizdas (priegloba, prievadas); System.out.println („Prisijungimas prie serverio …“); Lizdas ryšys = server.accept (); System.out.println („Ryšys užmegztas“); }}

Sukurkite tinklo programą „Java“Step10
Sukurkite tinklo programą „Java“Step10

Žingsnis 10. Paruoškite bendravimo srautus

Ryšys vyksta srautais, o šioje programoje neapdoroti (ryšio iš) serverio (su klientu) ir kliento srautai turi būti susieti su duomenų arba objektų srautais. Atminkite, kad abi šalys turi naudoti tą patį srauto tipą.

  • Duomenų srautai

    importuoti java.io. DataInputStream; importuoti java.io. DataOutputStream; importuoti java.net. InetAddress; importuoti java.net. ServerSocket; importuoti java.net. Socket; public class NetworkAppExample {public static void main (String args) metimai Išimtis {String host = "localhost"; int prievadas = 10430; ServerSocket serveris = naujas ServerSocket (prievadas, 50, InetAddress.getByName (priegloba)); System.out.println („Serveris paleistas“); Lizdo klientas = naujas lizdas (priegloba, prievadas); System.out.println („Prisijungimas prie serverio …“); Lizdas ryšys = server.accept (); System.out.println („Ryšys užmegztas“); DataOutputStream clientOut = naujas DataOutputStream (client.getOutputStream ()); DataInputStream clientIn = naujas DataInputStream (client.getInputStream ()); DataOutputStream serverOut = naujas DataOutputStream (connection.getOutputStream ()); DataInputStream serverIn = naujas DataInputStream (connection.getInputStream ()); }}

  • Objektų srautai

    Kai naudojami keli objektų srautai, įvesties srautai turi būti inicijuojami ta pačia tvarka kaip ir išvesties srautai, nes

    ObjectOutputStream

    siunčia antraštę kitai šaliai ir

    ObjectInputStream

    blokuoja vykdymą, kol nuskaito antraštę.

    importuoti java.io. ObjectInputStream; importuoti java.io. ObjectOutputStream; importuoti java.net. InetAddress; importuoti java.net. ServerSocket; importuoti java.net. Socket; public class NetworkAppExample {public static void main (String args) metimai Išimtis {String host = "localhost"; int prievadas = 10430; ServerSocket serveris = naujas ServerSocket (prievadas, 50, InetAddress.getByName (priegloba)); System.out.println („Serveris paleistas“); Lizdo klientas = naujas lizdas (priegloba, prievadas); System.out.println („Prisijungimas prie serverio …“); Lizdas jungtis = server.accept (); System.out.println („Ryšys užmegztas“); ObjectOutputStream clientOut = naujas ObjectOutputStream (client.getOutputStream ()); ObjectOutputStream serverOut = naujas ObjectOutputStream (connection.getOutputStream ()); ObjectInputStream clientIn = naujas ObjectInputStream (client.getInputStream ()); ObjectInputStream serverIn = naujas ObjectInputStream (connection.getInputStream ()); }}

    Užsakymą, kaip nurodyta aukščiau esančiame kode, gali būti lengviau įsiminti - pirmiausia inicijuokite išvesties srautus, tada įveskite srautus ta pačia tvarka. Tačiau kita objektų srautų inicijavimo tvarka yra tokia:

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

Sukurkite tinklo programą „Java“Step11
Sukurkite tinklo programą „Java“Step11

Žingsnis 11. Prisijunkite, kad ryšys paruoštas

Registravimo tikslais spausdinkite į konsolę, kad ryšys paruoštas.

// kodas praleistas importuoti java.net. InetAddress; importuoti java.net. ServerSocket; importuoti java.net. Socket; public class NetworkAppExample {public static void main (String args) metimai Išimtis {String host = "localhost"; int prievadas = 10430; ServerSocket serveris = naujas ServerSocket (prievadas, 50, InetAddress.getByName (priegloba)); System.out.println („Serveris paleistas“); Lizdo klientas = naujas lizdas (priegloba, prievadas); System.out.println („Prisijungimas prie serverio …“); Lizdas ryšys = server.accept (); System.out.println („Ryšys užmegztas“); // kodas praleistas System.out.println ("Ryšys paruoštas."); }}

Sukurkite tinklo programą „Java“Step12
Sukurkite tinklo programą „Java“Step12

Žingsnis 12. Sukurkite pranešimą

Šioje programoje

Labas pasauli

tekstas bus siunčiamas į serverį arba

baitas

arba

Styginė

. Paskelbkite tokio tipo kintamąjį, kuris priklauso nuo naudojamo srauto. Naudoti

baitas

duomenų srautams ir

Styginė

objektų srautams.

  • Duomenų srautai

    Naudojant duomenų srautus, serializacija atliekama konvertuojant objektus į primityvius duomenų tipus arba

    Styginė

    . Tokiu atveju,

    Styginė

    yra konvertuojamas į

    baitas

    vietoj rašymo

    writeBytes ()

    metodas, parodantis, kaip tai būtų daroma su kitais objektais, pvz., vaizdais ar kitais failais.

    importuoti java.io. DataInputStream; importuoti java.io. DataOutputStream; importuoti java.net. InetAddress; importuoti java.net. ServerSocket; importuoti java.net. Socket; public class NetworkAppExample {public static void main (String args) metimai Išimtis {String host = "localhost"; int prievadas = 10430; ServerSocket serveris = naujas ServerSocket (prievadas, 50, InetAddress.getByName (priegloba)); System.out.println („Serveris paleistas“); Lizdo klientas = naujas lizdas (priegloba, prievadas); System.out.println („Prisijungimas prie serverio …“); Lizdas jungtis = server.accept (); System.out.println („Ryšys užmegztas“); DataOutputStream clientOut = naujas DataOutputStream (client.getOutputStream ()); DataInputStream clientIn = naujas DataInputStream (client.getInputStream ()); DataOutputStream serverOut = naujas DataOutputStream (connection.getOutputStream ()); DataInputStream serverIn = naujas DataInputStream (connection.getInputStream ()); System.out.println („Ryšys paruoštas“); baitas messageOut = "Labas pasaulis".getBytes (); }}

  • Objektų srautai

    importuoti java.io. ObjectInputStream; importuoti java.io. ObjectOutputStream; importuoti java.net. InetAddress; importuoti java.net. ServerSocket; importuoti java.net. Socket; public class NetworkAppExample {public static void main (String args) metimai Išimtis {String host = "localhost"; int prievadas = 10430; ServerSocket serveris = naujas ServerSocket (prievadas, 50, InetAddress.getByName (priegloba)); System.out.println („Serveris paleistas“); Lizdo klientas = naujas lizdas (priegloba, prievadas); System.out.println („Prisijungimas prie serverio …“); Lizdas ryšys = server.accept (); System.out.println („Ryšys užmegztas“); ObjectOutputStream clientOut = naujas ObjectOutputStream (client.getOutputStream ()); ObjectOutputStream serverOut = naujas ObjectOutputStream (connection.getOutputStream ()); ObjectInputStream clientIn = naujas ObjectInputStream (client.getInputStream ()); ObjectInputStream serverIn = naujas ObjectInputStream (connection.getInputStream ()); System.out.println („Ryšys paruoštas“); String messageOut = "Labas pasaulis"; }}

Sukurkite tinklo programą „Java“Step13
Sukurkite tinklo programą „Java“Step13

Žingsnis 13. Siųskite pranešimą

Įrašykite duomenis į išvesties srautą ir praplaukite srautą, kad įsitikintumėte, jog duomenys buvo visiškai parašyti.

  • Duomenų srautai

    Pirmiausia reikia išsiųsti pranešimo ilgį, kad kita šalis žinotų, kiek baitų reikia perskaityti. Kai ilgis siunčiamas kaip primityvus sveikasis skaičius, galima siųsti baitus.

    importuoti java.io. DataInputStream; importuoti java.io. DataOutputStream; importuoti java.net. InetAddress; importuoti java.net. ServerSocket; importuoti java.net. Socket; public class NetworkAppExample {public static void main (String args) metimai Išimtis {String host = "localhost"; int prievadas = 10430; ServerSocket serveris = naujas ServerSocket (prievadas, 50, InetAddress.getByName (priegloba)); System.out.println („Serveris paleistas“); Lizdo klientas = naujas lizdas (priegloba, prievadas); System.out.println („Prisijungimas prie serverio …“); Lizdas jungtis = server.accept (); System.out.println („Ryšys užmegztas“); DataOutputStream clientOut = naujas DataOutputStream (client.getOutputStream ()); DataInputStream clientIn = naujas DataInputStream (client.getInputStream ()); DataOutputStream serverOut = naujas DataOutputStream (connection.getOutputStream ()); DataInputStream serverIn = naujas DataInputStream (connection.getInputStream ()); System.out.println („Ryšys paruoštas“); baitas messageOut = "Labas pasaulis".getBytes (); clientOut.writeInt (messageOut.length); clientOut.write (messageOut); clientOut.flush (); }}

  • Objektų srautai

    importuoti java.io. ObjectInputStream; importuoti java.io. ObjectOutputStream; importuoti java.net. InetAddress; importuoti java.net. ServerSocket; importuoti java.net. Socket; public class NetworkAppExample {public static void main (String args) metimai Išimtis {String host = "localhost"; int prievadas = 10430; ServerSocket serveris = naujas ServerSocket (prievadas, 50, InetAddress.getByName (priegloba)); System.out.println („Serveris paleistas“); Lizdo klientas = naujas lizdas (priegloba, prievadas); System.out.println („Prisijungimas prie serverio …“); Lizdas jungtis = server.accept (); System.out.println („Ryšys užmegztas“); ObjectOutputStream clientOut = naujas ObjectOutputStream (client.getOutputStream ()); ObjectOutputStream serverOut = naujas ObjectOutputStream (connection.getOutputStream ()); ObjectInputStream clientIn = naujas ObjectInputStream (client.getInputStream ()); ObjectInputStream serverIn = naujas ObjectInputStream (connection.getInputStream ()); System.out.println („Ryšys paruoštas“); String messageOut = "Labas pasaulis"; clientOut.writeObject (messageOut); clientOut.flush (); }}

Sukurkite tinklo programą „Java“Step14
Sukurkite tinklo programą „Java“Step14

Žingsnis 14. Žurnalas išsiųstas pranešimas

Registravimo tikslais spausdinkite į konsolę, kad pranešimas buvo išsiųstas.

  • Duomenų srautai

    importuoti java.io. DataInputStream; importuoti java.io. DataOutputStream; importuoti java.net. InetAddress; importuoti java.net. ServerSocket; importuoti java.net. Socket; public class NetworkAppExample {public static void main (String args) metimai Išimtis {String host = "localhost"; int prievadas = 10430; ServerSocket serveris = naujas ServerSocket (prievadas, 50, InetAddress.getByName (priegloba)); System.out.println („Serveris paleistas“); Lizdo klientas = naujas lizdas (priegloba, prievadas); System.out.println („Prisijungimas prie serverio …“); Lizdas jungtis = server.accept (); System.out.println („Ryšys užmegztas“); DataOutputStream clientOut = naujas DataOutputStream (client.getOutputStream ()); DataInputStream clientIn = naujas DataInputStream (client.getInputStream ()); DataOutputStream serverOut = naujas DataOutputStream (connection.getOutputStream ()); DataInputStream serverIn = naujas DataInputStream (connection.getInputStream ()); System.out.println („Ryšys paruoštas“); baitas messageOut = "Labas pasaulis".getBytes (); clientOut.writeInt (messageOut.length); clientOut.write (messageOut); clientOut.flush (); System.out.println ("Pranešimas išsiųstas į serverį:" + nauja eilutė (messageOut)); }}

  • Objektų srautai

    importuoti java.io. ObjectInputStream; importuoti java.io. ObjectOutputStream; importuoti java.net. InetAddress; importuoti java.net. ServerSocket; importuoti java.net. Socket; public class NetworkAppExample {public static void main (String args) metimai Išimtis {String host = "localhost"; int prievadas = 10430; ServerSocket serveris = naujas ServerSocket (prievadas, 50, InetAddress.getByName (priegloba)); System.out.println („Serveris paleistas“); Lizdo klientas = naujas lizdas (priegloba, prievadas); System.out.println („Prisijungimas prie serverio …“); Lizdas ryšys = server.accept (); System.out.println („Ryšys užmegztas“); ObjectOutputStream clientOut = naujas ObjectOutputStream (client.getOutputStream ()); ObjectOutputStream serverOut = naujas ObjectOutputStream (connection.getOutputStream ()); ObjectInputStream clientIn = naujas ObjectInputStream (client.getInputStream ()); ObjectInputStream serverIn = naujas ObjectInputStream (connection.getInputStream ()); System.out.println („Ryšys paruoštas“); String messageOut = "Labas pasaulis"; clientOut.writeObject (messageOut); clientOut.flush (); System.out.println ("Pranešimas išsiųstas į serverį:" + messageOut); }}

Sukurkite tinklo programą „Java“Step15
Sukurkite tinklo programą „Java“Step15

Žingsnis 15. Perskaitykite pranešimą

Skaitykite duomenis iš įvesties srauto ir konvertuokite juos. Kadangi tiksliai žinome siunčiamų duomenų tipą, mes arba sukursime

Styginė

nuo

baitas

arba mesti

Objektas

į

Styginė

nepatikrinus, priklausomai nuo naudojamo srauto.

  • Duomenų srautai

    Kadangi ilgis buvo išsiųstas pirmiausia, o vėliau baitai, skaitymas turi būti atliekamas ta pačia tvarka. Jei ilgis lygus nuliui, nėra ko skaityti. Objektas deserializuojamas, kai baitai vėl paverčiami egzemplioriumi, šiuo atveju

    Styginė

    importuoti java.io. DataInputStream; importuoti java.io. DataOutputStream; importuoti java.net. InetAddress; importuoti java.net. ServerSocket; importuoti java.net. Socket; public class NetworkAppExample {public static void main (String args) metimai Išimtis {String host = "localhost"; int prievadas = 10430; ServerSocket serveris = naujas ServerSocket (prievadas, 50, InetAddress.getByName (priegloba)); System.out.println („Serveris paleistas“); Lizdo klientas = naujas lizdas (priegloba, prievadas); System.out.println („Prisijungimas prie serverio …“); Lizdas ryšys = server.accept (); System.out.println („Ryšys užmegztas“); DataOutputStream clientOut = naujas DataOutputStream (client.getOutputStream ()); DataInputStream clientIn = naujas DataInputStream (client.getInputStream ()); DataOutputStream serverOut = naujas DataOutputStream (connection.getOutputStream ()); DataInputStream serverIn = naujas DataInputStream (connection.getInputStream ()); System.out.println („Ryšys paruoštas“); baitas messageOut = "Labas pasaulis".getBytes (); clientOut.writeInt (messageOut.length); clientOut.write (messageOut); clientOut.flush (); System.out.println ("Pranešimas išsiųstas į serverį:" + nauja eilutė (messageOut)); int ilgis = serverIn.readInt (); if (ilgis> 0) {baitas messageIn = naujas baitas [ilgis]; serverIn.readFully (messageIn, 0, messageIn.length); }}}

  • Objektų srautai

    importuoti java.io. ObjectInputStream; importuoti java.io. ObjectOutputStream; importuoti java.net. InetAddress; importuoti java.net. ServerSocket; importuoti java.net. Socket; public class NetworkAppExample {public static void main (String args) metimai Išimtis {String host = "localhost"; int prievadas = 10430; ServerSocket serveris = naujas ServerSocket (prievadas, 50, InetAddress.getByName (priegloba)); System.out.println („Serveris paleistas“); Lizdo klientas = naujas lizdas (priegloba, prievadas); System.out.println („Prisijungimas prie serverio …“); Lizdas ryšys = server.accept (); System.out.println („Ryšys užmegztas“); ObjectOutputStream clientOut = naujas ObjectOutputStream (client.getOutputStream ()); ObjectOutputStream serverOut = naujas ObjectOutputStream (connection.getOutputStream ()); ObjectInputStream clientIn = naujas ObjectInputStream (client.getInputStream ()); ObjectInputStream serverIn = naujas ObjectInputStream (connection.getInputStream ()); System.out.println („Ryšys paruoštas“); String messageOut = "Labas pasaulis"; clientOut.writeObject (messageOut); clientOut.flush (); System.out.println ("Pranešimas išsiųstas į serverį:" + messageOut); String messageIn = (String) serverIn.readObject (); }}

Sukurkite tinklo programą „Java“Step16
Sukurkite tinklo programą „Java“Step16

Žingsnis 16. Prisijunkite prie perskaityto pranešimo

Registravimo tikslais spausdinkite konsolėje tą pranešimą ir gaukite jo turinį.

  • Duomenų srautai

    importuoti java.io. DataInputStream; importuoti java.io. DataOutputStream; importuoti java.net. InetAddress; importuoti java.net. ServerSocket; importuoti java.net. Socket; public class NetworkAppExample {public static void main (String args) metimai Išimtis {String host = "localhost"; int prievadas = 10430; ServerSocket serveris = naujas ServerSocket (prievadas, 50, InetAddress.getByName (priegloba)); System.out.println („Serveris paleistas“); Lizdo klientas = naujas lizdas (priegloba, prievadas); System.out.println („Prisijungimas prie serverio …“); Lizdas ryšys = server.accept (); System.out.println („Ryšys užmegztas“); DataOutputStream clientOut = naujas DataOutputStream (client.getOutputStream ()); DataInputStream clientIn = naujas DataInputStream (client.getInputStream ()); DataOutputStream serverOut = naujas DataOutputStream (connection.getOutputStream ()); DataInputStream serverIn = naujas DataInputStream (connection.getInputStream ()); System.out.println („Ryšys paruoštas“); baitas messageOut = "Labas pasaulis".getBytes (); clientOut.writeInt (messageOut.length); clientOut.write (messageOut); clientOut.flush (); System.out.println ("Pranešimas išsiųstas į serverį:" + nauja eilutė (messageOut)); int ilgis = serverIn.readInt (); if (ilgis> 0) {baitas messageIn = naujas baitas [ilgis]; serverIn.readFully (messageIn, 0, messageIn.length); System.out.println ("Pranešimas gautas iš kliento:" + nauja eilutė (messageIn)); }}}

  • Objektų srautai

    importuoti java.io. ObjectInputStream; importuoti java.io. ObjectOutputStream; importuoti java.net. InetAddress; importuoti java.net. ServerSocket; importuoti java.net. Socket; public class NetworkAppExample {public static void main (String args) metimai Išimtis {String host = "localhost"; int prievadas = 10430; ServerSocket serveris = naujas ServerSocket (prievadas, 50, InetAddress.getByName (priegloba)); System.out.println („Serveris paleistas“); Lizdo klientas = naujas lizdas (priegloba, prievadas); System.out.println („Prisijungimas prie serverio …“); Lizdas ryšys = server.accept (); System.out.println („Ryšys užmegztas“); ObjectOutputStream clientOut = naujas ObjectOutputStream (client.getOutputStream ()); ObjectOutputStream serverOut = naujas ObjectOutputStream (connection.getOutputStream ()); ObjectInputStream clientIn = naujas ObjectInputStream (client.getInputStream ()); ObjectInputStream serverIn = naujas ObjectInputStream (connection.getInputStream ()); System.out.println („Ryšys paruoštas“); String messageOut = "Labas pasaulis"; clientOut.writeObject (messageOut); clientOut.flush (); System.out.println ("Pranešimas išsiųstas į serverį:" + messageOut); String messageIn = (String) serverIn.readObject (); System.out.println ("Pranešimas gautas iš kliento:" + messageIn); }}

Sukurkite tinklo programą „Java“Step17
Sukurkite tinklo programą „Java“Step17

Žingsnis 17. Atjunkite jungtis

Ryšys nutrūksta, kai viena šalis uždaro savo srautus. „Java“, uždarius išvesties srautą, taip pat uždaromi susiję lizdai ir įvesties srautai. Kai kita pusė sužino, kad ryšys nutrūko, ji taip pat turi uždaryti išvesties srautą, kad būtų išvengta atminties nutekėjimo.

// kodas praleistas importuoti java.net. InetAddress; importuoti java.net. ServerSocket; importuoti java.net. Socket; public class NetworkAppExample {public static void main (String args) metimai Išimtis {String host = "localhost"; int prievadas = 10430; ServerSocket serveris = naujas ServerSocket (prievadas, 50, InetAddress.getByName (priegloba)); System.out.println („Serveris paleistas“); Lizdo klientas = naujas lizdas (priegloba, prievadas); System.out.println („Prisijungimas prie serverio …“); Lizdas ryšys = server.accept (); System.out.println („Ryšys užmegztas“); // kodas praleistas System.out.println ("Ryšys paruoštas."); // kodas praleistas clientOut.close (); serverOut.close (); }}

Sukurkite tinklo programą „Java“„Step18 V2“
Sukurkite tinklo programą „Java“„Step18 V2“

Žingsnis 18. Rąstų atjungimas

Registravimo tikslais spausdinimas prie konsolės buvo atjungtas.

// kodas praleistas importuoti java.net. InetAddress; importuoti java.net. ServerSocket; importuoti java.net. Socket; public class NetworkAppExample {public static void main (String args) metimai Išimtis {String host = "localhost"; int prievadas = 10430; ServerSocket serveris = naujas ServerSocket (prievadas, 50, InetAddress.getByName (priegloba)); System.out.println („Serveris paleistas“); Lizdo klientas = naujas lizdas (priegloba, prievadas); System.out.println („Prisijungimas prie serverio …“); Lizdas ryšys = server.accept (); System.out.println („Ryšys užmegztas“); // kodas praleistas System.out.println ("Ryšys paruoštas."); // kodas praleistas clientOut.close (); serverOut.close (); System.out.println („Ryšiai uždaryti“); }}

Sukurkite tinklo programą „Java“Step19
Sukurkite tinklo programą „Java“Step19

Žingsnis 19. Išjunkite serverį

Ryšiai atjungti, bet serveris vis dar veikia. Kaip

ServerSocket

nėra susietas su jokiu srautu, jį reikia aiškiai uždaryti skambinant

Uždaryti()

metodas.

// kodas praleistas importuoti java.net. InetAddress; importuoti java.net. ServerSocket; importuoti java.net. Socket; public class NetworkAppExample {public static void main (String args) metimai Išimtis {String host = "localhost"; int prievadas = 10430; ServerSocket serveris = naujas ServerSocket (prievadas, 50, InetAddress.getByName (priegloba)); System.out.println („Serveris paleistas“); Lizdo klientas = naujas lizdas (priegloba, prievadas); System.out.println („Prisijungimas prie serverio …“); Lizdas ryšys = server.accept (); System.out.println („Ryšys užmegztas“); // kodas praleistas System.out.println ("Ryšys paruoštas."); // kodas praleistas clientOut.close (); serverOut.close (); System.out.println („Ryšiai uždaryti“); server.close (); }}

Sukurkite tinklo programą „Java“Step20
Sukurkite tinklo programą „Java“Step20

Žingsnis 20. Prisijungti prie serverio nutraukimo

Registravimo tikslais spausdinimas į konsolės serverį buvo nutrauktas.

// kodas praleistas importuoti java.net. InetAddress; importuoti java.net. ServerSocket; importuoti java.net. Socket; public class NetworkAppExample {public static void main (String args) metimai Išimtis {String host = "localhost"; int prievadas = 10430; ServerSocket serveris = naujas ServerSocket (prievadas, 50, InetAddress.getByName (priegloba)); System.out.println („Serveris paleistas“); Lizdo klientas = naujas lizdas (priegloba, prievadas); System.out.println („Prisijungimas prie serverio …“); Lizdas ryšys = server.accept (); System.out.println („Ryšys užmegztas“); // kodas praleistas System.out.println ("Ryšys paruoštas."); // kodas praleistas clientOut.close (); serverOut.close (); System.out.println („Ryšiai uždaryti“); server.close (); System.out.println („Serveris nutrauktas“); }}

Sukurkite tinklo programą „Java“Step21
Sukurkite tinklo programą „Java“Step21

21 žingsnis. Sudarykite ir paleiskite

Prisijungimas leido mums sužinoti, ar programa buvo sėkminga, ar ne. Numatoma išvestis:

Serveris paleistas. Prisijungiama prie serverio… Ryšys užmegztas. Bendravimas yra paruoštas. Pranešimas išsiųstas į serverį: „Hello World“Pranešimas gautas iš kliento: „Hello World Connections“uždarytas. Serveris nutrauktas.

Jei jūsų produkcija nėra tokia, kaip nurodyta aukščiau, ir mažai tikėtina, kad tai atsitiks, yra keletas sprendimų:

  • Jei išėjimas sustoja ties linija

    Ryšys užmegztas.

    ir objektų srautai, praplaukite kiekvieną

    ObjectOutputStream

  • iškart po inicijavimo, nes antraštės dėl tam tikrų priežasčių nebuvo išsiųstos.
  • Jei išvestis spausdinama

    java.net. BindException: adresas jau naudojamas

  • pasirinkite kitą prievado numerį, nes nurodytasis jau naudojamas.

Patarimai

  • Prisijungimas prie serverio kitame tinkle atliekamas prisijungus prie išorinio IP adreso įrenginyje, kuriame veikia serveris, turintis persiunčiamą prievadą.
  • Prisijungimas prie serverio tame pačiame tinkle atliekamas prisijungiant prie įrenginio, kuriame veikia serveris, privataus IP adreso arba persiunčiant prievadą ir prisijungiant prie išorinio įrenginio IP adreso.
  • Yra programinės įrangos, pvz., „Hamachi“, kuri leidžia prisijungti prie serverio kitame tinkle nepersiunčiant prievado, tačiau tam reikia įdiegti programinę įrangą abiejuose įrenginiuose.

Pavyzdžiai

Tinklo programoms, kurios naudoja blokuojančią įvestį/išvestį, reikia naudoti gijas. Šie pavyzdžiai rodo minimalistinį serverio ir kliento įgyvendinimą su gijomis. Tinklo kodas iš esmės yra toks pat kaip straipsnyje, išskyrus tai, kad kai kurie fragmentai buvo sinchronizuoti, perkelti į gijas ir tvarkomi išimtys.

Serveris.java

importuoti java.io. IOException; importuoti java.net. InetAddress; importuoti java.net. ServerSocket; importuoti java.net. SocketException; importuoti java.net. UnknownHostException; importuoti java.util. ArrayList; importuoti java.util. Collections; importuoti java.util. List; /*** Klasė {@code Server} yra serverio galinis taškas tinkle. {@code Server}, susietas su tam tikru IP * adresu ir prievadu, užmezga ryšius su klientais ir gali su jais bendrauti arba juos atjungti. *

* Ši klasė yra saugi. * * @version 1.0 * @see Client * @see Connection */ public class Server realizuoja Runnable {private ServerSocket server; privatus sąrašas jungtys; privatus siūlų siūlas; privatus galutinis Objekto ryšiaiLock = naujas objektas (); /** * Sukuria {@code Server}, kuris sąveikauja su klientais pagal nurodytą pagrindinio kompiuterio pavadinimą ir prievadą su nurodytu * prašomu maksimaliu įeinančių klientų eilės ilgiu. * * @param pagrindinio kompiuterio pagrindinio kompiuterio adresas, kurį reikia naudoti. * @param prievadas Naudojamas prievado numeris. * @param atsilikimas Prašoma maksimalaus įeinančių klientų eilės ilgio. * @throws NetworkException Jei paleidžiant serverį įvyksta klaida. */ viešasis serveris (eilutės priegloba, int prievadas, int atsilikimas) meta NetworkException {try {server = new ServerSocket (port, backlog, InetAddress.getByName (host)); } catch (UnknownHostException e) {throws new NetworkException ("Pagrindinio kompiuterio pavadinimo nepavyko išspręsti:" + priegloba, e); } catch (IllegalArgumentException e) {throws new NetworkException ("Prievado numeris turi būti nuo 0 iki 65535 (imtinai):" + prievadas); } catch (IOException e) {throws new NetworkException ("Nepavyko paleisti serverio.", e); } jungtys = Collections.synchronizedList (naujas ArrayList ()); siūlas = naujas Siūlas (šis); thread.start (); } /*** Sukuria {@code Server}, kuris sąveikauja su klientais pagal nurodytą pagrindinio kompiuterio pavadinimą ir prievadą. * * @param pagrindinio kompiuterio prieglobos adresas, kurį reikia susieti. * @param prievadas Prijungti prievado numerį. * @throws NetworkException Jei paleidžiant serverį atsiranda klaidų. */ viešasis serveris (eilutės priegloba, int prievadas) meta „NetworkException“{tai (priegloba, prievadas, 50); } /*** Klausosi, priima ir registruoja gaunamus klientų ryšius. */ @Override public void run () {while (! Server.isClosed ()) {try {connection.add (new Connection (server.accept ()))); } catch (SocketException e) {if (! e.getMessage (). equals ("Socket closed")) {e.printStackTrace (); }} catch (NetworkException | IOException e) {e.printStackTrace (); }}} /*** Siunčia duomenis visiems registruotiems klientams. * * @param data Duomenys, kuriuos reikia siųsti. * @throws IllegalStateException Jei bandoma rašyti duomenis, kai serveris neprisijungęs. * @throws IllegalArgumentException Jei siunčiami duomenys yra niekiniai. */ public void broadcast (Objekto duomenys) {if (server.isClosed ()) {thro new new IllegalStateException ("Duomenys nesiųsti, serveris neprisijungęs."); } if (duomenys == null) {išmesti naują IllegalArgumentException ("null data"); } sinchronizuotas (connectionLock) {for (Ryšio ryšys: ryšiai) {try {connection.send (data); System.out.println („Duomenys sėkmingai išsiųsti klientui“); } sugauti (NetworkException e) {e.printStackTrace (); }}}} /*** Siunčia atsijungimo pranešimą ir atjungia nurodytą klientą. * * @param ryšys Klientas, kurį reikia atjungti. * @throws NetworkException Jei uždarant ryšį įvyksta klaida. */ public void disconnect (Connection connection) meta NetworkException {if (connection.remove (connection)) {connection.close (); }} /*** Siunčia atjungimo pranešimą visiems klientams, atjungia juos ir nutraukia serverį. */ public void close () meta „NetworkException“{synchronized (connectionLock) {for (Ryšio ryšys: ryšiai) {try {connection.close (); } sugauti (NetworkException e) {e.printStackTrace (); }}} jungtys. aiškus (); pabandyk {server.close (); } catch (IOException e) {throws new NetworkException ("Klaida uždarant serverį."); } pagaliau {thread.interrupt (); }} /*** Grąžina, ar serveris yra prisijungęs, ar ne. * * @return Tiesa, jei serveris yra prisijungęs. Klaidinga, kitaip. */ public boolean isOnline () {return! server.isClosed (); } /*** Pateikia registruotų klientų masyvą. */ public Connection getConnections () {synchronized (connectionLock) {return connection.toArray (new Connection [connection.size ()]); }}}

Klientas.java

importuoti java.io. IOException; importuoti java.net. Socket; importuoti java.net. UnknownHostException; /*** Klasė {@code Client} reiškia kliento galutinį tašką tinkle. {@code Client}, prisijungus prie tam tikro * serverio, garantuoja, kad galės bendrauti tik su serveriu. Ar kiti klientai gaus duomenis *, priklauso nuo serverio diegimo. *

* Ši klasė yra saugi. * * @version 1.0 * @see Server * @see Connection */ public class Client {private Connection connection; /*** Sukuria {@code Client}, prijungtą prie serverio nurodytame priegloboje ir prievade. * * @param pagrindinio kompiuterio prieglobos adresas, kurį reikia susieti. * @param prievadas Prijungti prievado numerį. * @throws NetworkException Jei paleidžiant serverį įvyksta klaida. */ public Client (String host, int port) meta NetworkException {try {connection = new Connection (new Socket (host, port)); } catch (UnknownHostException e) {throws new NetworkException ("Pagrindinio kompiuterio pavadinimo nepavyko išspręsti:" + priegloba, e); } catch (IllegalArgumentException e) {throws new NetworkException ("Prievado numeris turi būti nuo 0 iki 65535 (imtinai):" + prievadas); } catch (IOException e) {throws new NetworkException ("Nepavyko paleisti serverio.", e); }} /*** Siunčia duomenis kitai šaliai. * * @param data Duomenys, kuriuos reikia siųsti. * @throws NetworkException Jei nepavyksta rašyti į išvesties srautą. * @throws IllegalStateException Jei bandoma įrašyti duomenis, kai ryšys uždarytas. * @throws IllegalArgumentException Jei siunčiami duomenys yra niekiniai. * @throws UnsupportedOperationException Jei bandoma siųsti nepalaikomą duomenų tipą. */ public void send (Objekto duomenys) meta NetworkException {connection.send (duomenys); } /*** Siunčia atjungimo pranešimą serveriui ir nutraukia ryšį su juo. */ public void close () meta NetworkException {connection.close (); } /*** Grąžina, ar klientas yra prijungtas prie serverio. * * @return Tiesa, jei klientas prijungtas. Klaidinga, kitaip. */ public boolean isOnline () {return connection.isConnected (); } /*** Grąžina kliento {@link Connection} egzempliorių. */ public Connection getConnection () {return connection; }}

Ryšys.java

importuoti java.io. DataInputStream; importuoti java.io. DataOutputStream; importuoti java.io. IOException; importuoti java.net. Socket; importuoti java.net. SocketException; /** * Klasė {@code Connection} reiškia ryšį iš serverio į klientą arba kliento galutinį tašką tinkle * {@code Connection}, prisijungęs, gali keistis duomenimis su kita šalimi ar šalimis, priklausomai nuo serveryje * diegimas. *

* Ši klasė yra saugi. * * @version 1.0 * @see Server * @see Client */ public class Connection implements Runnable {private Socket socket; privati „DataOutputStream“; privatus „DataInputStream“; privatus siūlų siūlas; private final Object writeLock = naujas objektas (); private final Object readLock = naujas objektas (); /*** Sukuria {@code Connection} naudodami nurodyto {@link Socket} srautus. * * @param lizdas, skirtas srautams gauti.*/ viešasis ryšys (lizdo lizdas) meta „NetworkException“{if (socket == null) {metimas naujas „IllegalArgumentException“(„null socket“); } this.socket = lizdas; try {out = new DataOutputStream (socket.getOutputStream ()); } catch (IOException e) {throws new NetworkException ("Nepavyko pasiekti išvesties srauto.", e); } try {in = new DataInputStream (socket.getInputStream ()); } catch (IOException e) {throws new NetworkException ("Nepavyko pasiekti įvesties srauto.", e); } thread = new Thread (tai); thread.start (); } /*** Skaito pranešimus, kol ryšys su kita šalimi gyvas. */ @Override public void run () {while (! Socket.isClosed ()) {try {int identifier; baitų baitų; sinchronizuotas (readLock) {identifikatorius = in.readInt (); int ilgis = in.readInt (); if (ilgis> 0) {baitai = naujas baitas [ilgis]; in.readFully (baitai, 0, baitai.ilgis); } else {tęsti; }} jungiklis (identifikatorius) {case Identifier. INTERNAL: String komanda = new String (baitai); if (command.equals ("atsijungti")) {if (! socket.isClosed ()) {System.out.println ("Gautas atjungimo paketas."); pabandyti {uždaryti (); } pagauti (NetworkException e) {return; } } } pertrauka; atvejo identifikatorius. TEKSTAS: System.out.println ("Pranešimas gautas:" + nauja eilutė (baitai)); pertrauka; numatytasis: System.out.println („Gauti neatpažinti duomenys“); }} catch (SocketException e) {if (! e.getMessage (). equals ("Socket closed")) {e.printStackTrace (); }} laimikis (IOException e) {e.printStackTrace (); }}} /*** Siunčia duomenis kitai šaliai. * * @param data Duomenys, kuriuos reikia siųsti. * @throws NetworkException Jei nepavyksta rašyti į išvesties srautą. * @throws IllegalStateException Jei bandoma įrašyti duomenis, kai ryšys uždarytas. * @throws IllegalArgumentException Jei siunčiami duomenys yra niekiniai. * @throws UnsupportedOperationException Jei bandoma siųsti nepalaikomą duomenų tipą. */ public void send (Objekto duomenys) meta „NetworkException“{if (socket.isClosed ()) {metimas naujas „IllegalStateException“(„Duomenys nesiųsti, ryšys uždarytas“); } if (duomenys == null) {išmesti naują IllegalArgumentException ("null data"); } int identifikatorius; baitų baitų; if (eilutės duomenų egzempliorius) {identifier = Identifier. TEXT; baitai = ((eilutės) duomenys).getBytes (); } else {mesti naują UnsupportedOperationException ("Nepalaikomas duomenų tipas:" + data.getClass ()); } pabandyti {synchronized (writeLock) {out.writeInt (identifikatorius); out.writeInt (baitai.ilgis); out.write (baitai); out.flush (); }} catch (IOException e) {throws new NetworkException ("Duomenų nepavyko išsiųsti.", e); }} /*** Siunčia atsijungimo pranešimą kitai šaliai ir nutraukia ryšį. */ public void close () meta „NetworkException“{if (socket.isClosed ()) {mesti naują „IllegalStateException“(„Ryšys jau uždarytas“); } pabandykite {baitas pranešimas = "atjungti".getBytes (); sinchronizuotas (writeLock) {out.writeInt (Identifier. INTERNAL); out.writeInt (message.length); out.write (žinutė); out.flush (); }} catch (IOException e) {System.out.println ("Nepavyko išsiųsti atsijungimo pranešimo."); } pabandyti {synchronized (writeLock) {out.close (); }} catch (IOException e) {throws new NetworkException ("Klaida uždarant ryšį.", e); } pagaliau {thread.interrupt (); }} /*** Grąžina, ar ryšys su kita šalimi yra gyvas. * * @return Tiesa, jei ryšys gyvas. Klaidinga, kitaip. */ public boolean isConnected () {return! socket.isClosed (); }}

Identifier.java

/** * Klasėje {@code Identifier} yra konstantos, kurias {@link Connection} naudoja tinklu siunčiamų duomenų * serijizavimui ir deserializavimui. * * @version 1.0 * @see Connection * / public final class Identifier { / ** * Vidinių pranešimų identifikatorius. */ public static final int INTERNAL = 1; /*** Tekstinių pranešimų identifikatorius. */ public static final int TEXT = 2; }

NetworkException.java

/*** Klasė {@code NetworkException} nurodo su tinklu susijusią klaidą. * / public class NetworkException pratęsia išimtį { / *** Sukuria {@code NetworkException}, kurio pranešimas yra {@code null}. * / public NetworkException () {} / *** Sukuria {@code NetworkException} su nurodytu pranešimu. * * @param message Pranešimas klaidai apibūdinti. */ public NetworkException (String message) {super (pranešimas); } /*** Sukuria {@code NetworkException} su nurodytu pranešimu ir priežastimi. * * @param message Pranešimas klaidai apibūdinti. * @param priežastis Klaidos priežastis. */ public NetworkException (String message, Throwable reason) {super (pranešimas, priežastis); } /*** Sukuria {@code NetworkException} dėl nurodytos priežasties. * * @param priežastis Klaidos priežastis. */ public NetworkException (Throwable cause) {super (priežastis); }}

NaudojimasPavyzdys.java

/*** Klasėje {@code UsageExample} rodomas {@link Server} ir {@link Client} naudojimas. Šiame pavyzdyje naudojamas * {@link Thread#sleep (ilgas)}, siekiant užtikrinti, kad kiekvienas segmentas būtų įvykdytas, nes dėl greito paleidimo ir uždarymo kai kurie * segmentai nevykdomi. * * @version 1.0 * @see Server * @see Client */ public class UsageExample {public static void main (String args) metimai Išimtis {String host = "localhost"; int prievadas = 10430; Serverio serveris = naujas serveris (priegloba, prievadas); Kliento klientas = naujas klientas (priegloba, prievadas); Siūlai.miegoti (100L); client.send („Labas“); server.broadcast ("Ei, vaikeli!"); Siūlai.miegoti (100L); server.disconnect (server.getConnections () [0]); // arba client.close () atsijungti nuo kliento pusės server.close (); }}

Rekomenduojamas: