Hoe om 'n netwerktoepassing in Java te skep (met foto's)

INHOUDSOPGAWE:

Hoe om 'n netwerktoepassing in Java te skep (met foto's)
Hoe om 'n netwerktoepassing in Java te skep (met foto's)

Video: Hoe om 'n netwerktoepassing in Java te skep (met foto's)

Video: Hoe om 'n netwerktoepassing in Java te skep (met foto's)
Video: How to Fix a Samsung Washer 4E or 4C Code - Fixing a Washer That Won't Fill with Water 2024, April
Anonim

Die skryf van kode wat op 'n sekere toestel uitgevoer word, is baie bevredigend. Maar om kode te skryf wat uitgevoer word op verskeie toestelle wat met mekaar kommunikeer, is bloot lewensbevestigend. Hierdie artikel sal u leer hoe u boodskappe via die netwerk met behulp van transmissiebeheerprotokol (TCP) kan verbind en uitruil.

In hierdie artikel stel u 'n toepassing op wat u rekenaar met homself verbind en dit in wese mal maak - praat met homself. U leer ook die verskil tussen die twee strome wat die meeste gebruik word vir netwerk in Java en hoe dit funksioneer.

Data- en voorwerpstrome

Voordat u in die kode duik, moet die verskil tussen die twee strome wat in die artikel gebruik word, onderskei word.

Datastrome

Datastrome verwerk primitiewe datatipes en snare. Data wat oor datastrome gestuur word, moet handmatig ingevoer en gedeserialiseer word, wat dit moeiliker maak om komplekse data oor te dra. Datastrome kan egter kommunikeer met bedieners en kliënte wat in ander tale as Java geskryf is. Rou strome is soortgelyk aan datastrome in daardie aspek, maar datastrome verseker dat die data op 'n platformonafhanklike manier geformateer word, wat voordelig is omdat beide partye gestuurde data kan lees.

Voorwerpstrome

Voorwerpstrome verwerk primitiewe datatipes en voorwerpe wat implementeer

Serialiseerbaar

koppelvlak. Data wat oor voorwerpstrome gestuur word, word outomaties in reeks en gedeserialiseer, wat dit makliker maak om komplekse data oor te dra. Objekstrome kan egter slegs kommunikeer met bedieners en kliënte wat in Java geskryf is. Ook,

ObjectOutputStream

stuur na inisialisering 'n kop na die

InputStream

van die ander party, wat by inisialisering die uitvoering blokkeer totdat die opskrif ontvang is.

Stappe

Skep 'n netwerktoepassing in Java Step1
Skep 'n netwerktoepassing in Java Step1

Stap 1. Skep 'n klas

Skep 'n klas en noem dit soos u wil. In hierdie artikel word dit genoem

NetwerkAppVoorbeeld

openbare klas NetworkAppExample {}

Skep 'n netwerktoepassing in Java Step2
Skep 'n netwerktoepassing in Java Step2

Stap 2. Skep 'n hoofmetode

Skep 'n hoofmetode en verklaar dat dit uitsonderings kan veroorsaak

Uitsondering

tipe en enige subklas daarvan - alle uitsonderings. Dit word as 'n slegte praktyk beskou, maar is aanvaarbaar vir voorbeelde van kaalbeen.

openbare klas NetworkAppExample {public static void main (String args) gooi uitsondering {}}

Skep 'n netwerktoepassing in Java Step3
Skep 'n netwerktoepassing in Java Step3

Stap 3. Verklaar bediener adres

Hierdie voorbeeld gebruik die plaaslike gasheeradres en 'n willekeurige poortnommer. Poortnommer moet in die reeks van 0 tot 65535 (ingesluit) wees. Poortnommers wat u moet vermy, wissel egter van 0 tot 1023 (insluitend) omdat dit gereserveerde stelselpoort is.

openbare klas NetworkAppExample {public static void main (String args) gooi uitsondering {String host = "localhost"; int poort = 10430; }}

Skep 'n netwerktoepassing in Java Step4
Skep 'n netwerktoepassing in Java Step4

Stap 4. Skep 'n bediener

Die bediener is gebind aan die adres en poort en luister na inkomende verbindings. In Java,

ServerSocket

verteenwoordig die eindpunt van die bediener en die funksie daarvan is om nuwe verbindings te aanvaar.

ServerSocket

het geen strome om data te lees en te stuur nie, omdat dit nie die verbinding tussen 'n bediener en 'n kliënt verteenwoordig nie.

voer java.net. InetAddress in; invoer java.net. ServerSocket; openbare klas NetworkAppExample {public static void main (String args) gooi uitsondering {String host = "localhost"; int poort = 10430; ServerSocket -bediener = nuwe ServerSocket (poort, 50, InetAddress.getByName (gasheer)); }}

Skep 'n netwerktoepassing in Java Step5
Skep 'n netwerktoepassing in Java Step5

Stap 5. Log bediener begin

Druk vir aanmelddoeleindes na die konsole dat die bediener begin is.

voer java.net. InetAddress in; invoer java.net. ServerSocket; openbare klas NetworkAppExample {public static void main (String args) gooi uitsondering {String host = "localhost"; int poort = 10430; ServerSocket -bediener = nuwe ServerSocket (poort, 50, InetAddress.getByName (gasheer)); System.out.println ("bediener begin."); }}

Skep 'n netwerktoepassing in Java Step6
Skep 'n netwerktoepassing in Java Step6

Stap 6. Skep 'n kliënt

Kliënt is gebind aan die adres en poort van 'n bediener en luister na pakkies (boodskappe) nadat die verbinding tot stand gebring is. In Java,

Sok

verteenwoordig óf 'n eindpunt aan die kant van die kliënt wat aan die bediener gekoppel is, óf 'n verbinding (van bediener) na die kliënt en word gebruik om met die party aan die ander kant te kommunikeer.

voer java.net. InetAddress in; invoer java.net. ServerSocket; invoer java.net. Socket; openbare klas NetworkAppExample {public static void main (String args) gooi uitsondering {String host = "localhost"; int poort = 10430; ServerSocket -bediener = nuwe ServerSocket (poort, 50, InetAddress.getByName (gasheer)); System.out.println ("bediener begin."); Socket -kliënt = nuwe Socket (gasheer, poort); }}

Skep 'n netwerktoepassing in Java Step7
Skep 'n netwerktoepassing in Java Step7

Stap 7. Log verbindingspoging

Vir aanmelddoeleindes, druk aan die konsole dat verbinding probeer is.

voer java.net. InetAddress in; invoer java.net. ServerSocket; invoer java.net. Socket; openbare klas NetworkAppExample {public static void main (String args) gooi uitsondering {String host = "localhost"; int poort = 10430; ServerSocket -bediener = nuwe ServerSocket (poort, 50, InetAddress.getByName (gasheer)); System.out.println ("bediener begin."); Socket -kliënt = nuwe Socket (gasheer, poort); System.out.println ("Koppel aan bediener …"); }}

Skep 'n netwerktoepassing in Java Step8
Skep 'n netwerktoepassing in Java Step8

Stap 8. Maak verbinding

Kliënte sal nooit kontak maak nie, tensy die bediener na verbindings luister en dit aanvaar, met ander woorde. In Java word verbindings tot stand gebring met behulp van

aanvaar ()

metode van

ServerSocket

klas. Die metode sal die uitvoering blokkeer totdat 'n kliënt verbind is.

voer java.net. InetAddress in; invoer java.net. ServerSocket; invoer java.net. Socket; openbare klas NetworkAppExample {public static void main (String args) gooi uitsondering {String host = "localhost"; int poort = 10430; ServerSocket -bediener = nuwe ServerSocket (poort, 50, InetAddress.getByName (gasheer)); System.out.println ("bediener begin."); Socket -kliënt = nuwe Socket (gasheer, poort); System.out.println ("Koppel aan bediener …"); Socketverbinding = server.accept (); }}

Skep 'n netwerktoepassing in Java Step9
Skep 'n netwerktoepassing in Java Step9

Stap 9. Meld gevestigde verbinding aan

Vir aanmelddoeleindes, druk die konsole tussen die bediener en die kliënt op die konsole af.

voer java.net. InetAddress in; invoer java.net. ServerSocket; invoer java.net. Socket; openbare klas NetworkAppExample {public static void main (String args) gooi uitsondering {String host = "localhost"; int poort = 10430; ServerSocket -bediener = nuwe ServerSocket (poort, 50, InetAddress.getByName (gasheer)); System.out.println ("bediener begin."); Socket -kliënt = nuwe Socket (gasheer, poort); System.out.println ("Koppel aan bediener …"); Socketverbinding = server.accept (); System.out.println ("Verbinding tot stand gebring."); }}

Skep 'n netwerktoepassing in Java Step10
Skep 'n netwerktoepassing in Java Step10

Stap 10. Berei kommunikasiestrome voor

Kommunikasie geskied oor strome, en in hierdie toepassing moet rou strome van (verbinding vanaf) bediener (na kliënt) en kliënt aan data- of objekstrome vasgeketting word. Onthou, beide partye moet dieselfde stroomtipe gebruik.

  • Datastrome

    voer java.io. DataInputStream in; voer java.io. DataOutputStream in; voer java.net. InetAddress in; invoer java.net. ServerSocket; invoer java.net. Socket; openbare klas NetworkAppExample {public static void main (String args) gooi uitsondering {String host = "localhost"; int poort = 10430; ServerSocket -bediener = nuwe ServerSocket (poort, 50, InetAddress.getByName (gasheer)); System.out.println ("bediener begin."); Socket -kliënt = nuwe Socket (gasheer, poort); System.out.println ("Koppel aan bediener …"); Socketverbinding = server.accept (); System.out.println ("Verbinding tot stand gebring."); DataOutputStream clientOut = nuwe DataOutputStream (client.getOutputStream ()); DataInputStream clientIn = nuwe DataInputStream (client.getInputStream ()); DataOutputStream serverOut = nuwe DataOutputStream (connection.getOutputStream ()); DataInputStream serverIn = nuwe DataInputStream (connection.getInputStream ()); }}

  • Voorwerpstrome

    As verskeie voorwerpstrome gebruik word, moet insetstrome in dieselfde volgorde as uitvoerstrome geïnitialiseer word

    ObjectOutputStream

    stuur 'n opskrif na die ander party en

    ObjectInputStream

    blokkeer uitvoering totdat dit die opskrif lees.

    voer java.io. ObjectInputStream in; voer java.io. ObjectOutputStream in; voer java.net. InetAddress in; invoer java.net. ServerSocket; invoer java.net. Socket; openbare klas NetworkAppExample {public static void main (String args) gooi uitsondering {String host = "localhost"; int poort = 10430; ServerSocket -bediener = nuwe ServerSocket (poort, 50, InetAddress.getByName (gasheer)); System.out.println ("bediener begin."); Socket -kliënt = nuwe Socket (gasheer, poort); System.out.println ("Koppel aan bediener …"); Socketverbinding = server.accept (); System.out.println ("Verbinding tot stand gebring."); ObjectOutputStream clientOut = nuwe ObjectOutputStream (client.getOutputStream ()); ObjectOutputStream serverOut = nuwe ObjectOutputStream (connection.getOutputStream ()); ObjectInputStream clientIn = nuwe ObjectInputStream (client.getInputStream ()); ObjectInputStream serverIn = nuwe ObjectInputStream (connection.getInputStream ()); }}

    Die volgorde soos gespesifiseer in die kode hierbo is miskien makliker om te onthou - initialiseer eers uitsetstrome en voer dan strome in dieselfde volgorde in. 'N Ander bevel vir die inisialisering van objekstrome is egter die volgende:

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

Skep 'n netwerktoepassing in Java Step11
Skep 'n netwerktoepassing in Java Step11

Stap 11. Teken aan dat die kommunikasie gereed is

Vir aanmelddoeleindes, druk aan die konsole dat die kommunikasie gereed is.

// kode weggelaat invoer java.net. InetAddress; invoer java.net. ServerSocket; invoer java.net. Socket; openbare klas NetworkAppExample {public static void main (String args) gooi uitsondering {String host = "localhost"; int poort = 10430; ServerSocket -bediener = nuwe ServerSocket (poort, 50, InetAddress.getByName (gasheer)); System.out.println ("bediener begin."); Socket -kliënt = nuwe Socket (gasheer, poort); System.out.println ("Koppel aan bediener …"); Socketverbinding = server.accept (); System.out.println ("Verbinding tot stand gebring."); // kode weggelaat System.out.println ("Kommunikasie is gereed."); }}

Skep 'n netwerktoepassing in Java Step12
Skep 'n netwerktoepassing in Java Step12

Stap 12. Skep 'n boodskap

In hierdie aansoek,

Hello Wêreld

teks sal na die bediener gestuur word óf as

byte

of

String

. Verklaar 'n veranderlike van die tipe wat afhang van die stroom wat gebruik word. Gebruik

byte

vir datastrome en

String

vir voorwerpstrome.

  • Datastrome

    Met behulp van datastrome word serialisering gedoen deur voorwerpe om te skakel in primitiewe datatipes of a

    String

    . In hierdie geval,

    String

    word omgeskakel na

    byte

    in plaas van geskryf met

    skryfBytes ()

    metode om aan te toon hoe dit met ander voorwerpe, soos beelde of ander lêers, gedoen sou word.

    voer java.io. DataInputStream in; voer java.io. DataOutputStream in; voer java.net. InetAddress in; invoer java.net. ServerSocket; invoer java.net. Socket; openbare klas NetworkAppExample {public static void main (String args) gooi uitsondering {String host = "localhost"; int poort = 10430; ServerSocket -bediener = nuwe ServerSocket (poort, 50, InetAddress.getByName (gasheer)); System.out.println ("bediener begin."); Socket -kliënt = nuwe Socket (gasheer, poort); System.out.println ("Koppel aan bediener …"); Socketverbinding = server.accept (); System.out.println ("Verbinding tot stand gebring."); DataOutputStream clientOut = nuwe DataOutputStream (client.getOutputStream ()); DataInputStream clientIn = nuwe DataInputStream (client.getInputStream ()); DataOutputStream serverOut = nuwe DataOutputStream (connection.getOutputStream ()); DataInputStream serverIn = nuwe DataInputStream (connection.getInputStream ()); System.out.println ("Kommunikasie is gereed."); byte messageOut = "Hello World".getBytes (); }}

  • Voorwerpstrome

    voer java.io. ObjectInputStream in; voer java.io. ObjectOutputStream in; voer java.net. InetAddress in; invoer java.net. ServerSocket; invoer java.net. Socket; openbare klas NetworkAppExample {public static void main (String args) gooi uitsondering {String host = "localhost"; int poort = 10430; ServerSocket -bediener = nuwe ServerSocket (poort, 50, InetAddress.getByName (gasheer)); System.out.println ("bediener begin."); Socket -kliënt = nuwe Socket (gasheer, poort); System.out.println ("Koppel aan bediener …"); Socketverbinding = server.accept (); System.out.println ("Verbinding tot stand gebring."); ObjectOutputStream clientOut = nuwe ObjectOutputStream (client.getOutputStream ()); ObjectOutputStream serverOut = nuwe ObjectOutputStream (connection.getOutputStream ()); ObjectInputStream clientIn = nuwe ObjectInputStream (client.getInputStream ()); ObjectInputStream serverIn = nuwe ObjectInputStream (connection.getInputStream ()); System.out.println ("Kommunikasie is gereed."); String messageOut = "Hallo wêreld"; }}

Skep 'n netwerktoepassing in Java Step13
Skep 'n netwerktoepassing in Java Step13

Stap 13. Stuur die boodskap

Skryf data na die uitsetstroom en spoel die stroom om te verseker dat die data volledig geskryf is.

  • Datastrome

    Die lengte van 'n boodskap moet eers gestuur word sodat die ander party weet hoeveel grepe dit moet lees. Nadat die lengte gestuur is as 'n primitiewe heelgetal, kan grepe gestuur word.

    voer java.io. DataInputStream in; voer java.io. DataOutputStream in; voer java.net. InetAddress in; invoer java.net. ServerSocket; invoer java.net. Socket; openbare klas NetworkAppExample {public static void main (String args) gooi uitsondering {String host = "localhost"; int poort = 10430; ServerSocket -bediener = nuwe ServerSocket (poort, 50, InetAddress.getByName (gasheer)); System.out.println ("bediener begin."); Socket -kliënt = nuwe Socket (gasheer, poort); System.out.println ("Koppel aan bediener …"); Socketverbinding = server.accept (); System.out.println ("Verbinding tot stand gebring."); DataOutputStream clientOut = nuwe DataOutputStream (client.getOutputStream ()); DataInputStream clientIn = nuwe DataInputStream (client.getInputStream ()); DataOutputStream serverOut = nuwe DataOutputStream (connection.getOutputStream ()); DataInputStream serverIn = nuwe DataInputStream (connection.getInputStream ()); System.out.println ("Kommunikasie is gereed."); byte messageOut = "Hello World".getBytes (); clientOut.writeInt (messageOut.length); clientOut.write (messageOut); clientOut.flush (); }}

  • Voorwerpstrome

    voer java.io. ObjectInputStream in; voer java.io. ObjectOutputStream in; voer java.net. InetAddress in; invoer java.net. ServerSocket; invoer java.net. Socket; openbare klas NetworkAppExample {public static void main (String args) gooi uitsondering {String host = "localhost"; int poort = 10430; ServerSocket -bediener = nuwe ServerSocket (poort, 50, InetAddress.getByName (gasheer)); System.out.println ("bediener begin."); Socket -kliënt = nuwe Socket (gasheer, poort); System.out.println ("Koppel aan bediener …"); Socketverbinding = server.accept (); System.out.println ("Verbinding tot stand gebring."); ObjectOutputStream clientOut = nuwe ObjectOutputStream (client.getOutputStream ()); ObjectOutputStream serverOut = nuwe ObjectOutputStream (connection.getOutputStream ()); ObjectInputStream clientIn = nuwe ObjectInputStream (client.getInputStream ()); ObjectInputStream serverIn = nuwe ObjectInputStream (connection.getInputStream ()); System.out.println ("Kommunikasie is gereed."); String messageOut = "Hallo wêreld"; clientOut.writeObject (messageOut); clientOut.flush (); }}

Skep 'n netwerktoepassing in Java Step14
Skep 'n netwerktoepassing in Java Step14

Stap 14. Stuur boodskap gestuur

Vir aanmelddoeleindes, druk die boodskap na die konsole uit.

  • Datastrome

    voer java.io. DataInputStream in; voer java.io. DataOutputStream in; voer java.net. InetAddress in; invoer java.net. ServerSocket; invoer java.net. Socket; openbare klas NetworkAppExample {public static void main (String args) gooi uitsondering {String host = "localhost"; int poort = 10430; ServerSocket -bediener = nuwe ServerSocket (poort, 50, InetAddress.getByName (gasheer)); System.out.println ("bediener begin."); Socket -kliënt = nuwe Socket (gasheer, poort); System.out.println ("Koppel aan bediener …"); Socketverbinding = server.accept (); System.out.println ("Verbinding tot stand gebring."); DataOutputStream clientOut = nuwe DataOutputStream (client.getOutputStream ()); DataInputStream clientIn = nuwe DataInputStream (client.getInputStream ()); DataOutputStream serverOut = nuwe DataOutputStream (connection.getOutputStream ()); DataInputStream serverIn = nuwe DataInputStream (connection.getInputStream ()); System.out.println ("Kommunikasie is gereed."); byte messageOut = "Hello World".getBytes (); clientOut.writeInt (messageOut.length); clientOut.write (messageOut); clientOut.flush (); System.out.println ("Boodskap gestuur na bediener:" + nuwe string (messageOut)); }}

  • Voorwerpstrome

    voer java.io. ObjectInputStream in; voer java.io. ObjectOutputStream in; voer java.net. InetAddress in; invoer java.net. ServerSocket; invoer java.net. Socket; openbare klas NetworkAppExample {public static void main (String args) gooi uitsondering {String host = "localhost"; int poort = 10430; ServerSocket -bediener = nuwe ServerSocket (poort, 50, InetAddress.getByName (gasheer)); System.out.println ("bediener begin."); Socket -kliënt = nuwe Socket (gasheer, poort); System.out.println ("Koppel aan bediener …"); Socketverbinding = server.accept (); System.out.println ("Verbinding tot stand gebring."); ObjectOutputStream clientOut = nuwe ObjectOutputStream (client.getOutputStream ()); ObjectOutputStream serverOut = nuwe ObjectOutputStream (connection.getOutputStream ()); ObjectInputStream clientIn = nuwe ObjectInputStream (client.getInputStream ()); ObjectInputStream serverIn = nuwe ObjectInputStream (connection.getInputStream ()); System.out.println ("Kommunikasie is gereed."); String messageOut = "Hallo wêreld"; clientOut.writeObject (messageOut); clientOut.flush (); System.out.println ("Boodskap gestuur na bediener:" + messageOut); }}

Skep 'n netwerktoepassing in Java Step15
Skep 'n netwerktoepassing in Java Step15

Stap 15. Lees die boodskap

Lees data uit die invoerstroom en omskep dit. Aangesien ons presies die tipe gestuurde data weet, sal ons óf 'n

String

van

byte

of gegooi

Voorwerp

aan

String

sonder om te kontroleer, afhangende van die stroom wat gebruik word.

  • Datastrome

    Aangesien lengte eers gestuur is en grepe daarna, moet in dieselfde volgorde gelees word. As die lengte nul is, is daar niks om te lees nie. Voorwerp word gedeserialiseer wanneer grepe teruggeskakel word in 'n voorbeeld, in hierdie geval van

    String

    voer java.io. DataInputStream in; voer java.io. DataOutputStream in; voer java.net. InetAddress in; invoer java.net. ServerSocket; invoer java.net. Socket; openbare klas NetworkAppExample {public static void main (String args) gooi uitsondering {String host = "localhost"; int poort = 10430; ServerSocket -bediener = nuwe ServerSocket (poort, 50, InetAddress.getByName (gasheer)); System.out.println ("bediener begin."); Socket -kliënt = nuwe Socket (gasheer, poort); System.out.println ("Koppel aan bediener …"); Socketverbinding = server.accept (); System.out.println ("Verbinding tot stand gebring."); DataOutputStream clientOut = nuwe DataOutputStream (client.getOutputStream ()); DataInputStream clientIn = nuwe DataInputStream (client.getInputStream ()); DataOutputStream serverOut = nuwe DataOutputStream (connection.getOutputStream ()); DataInputStream serverIn = nuwe DataInputStream (connection.getInputStream ()); System.out.println ("Kommunikasie is gereed."); byte messageOut = "Hello World".getBytes (); clientOut.writeInt (messageOut.length); clientOut.write (messageOut); clientOut.flush (); System.out.println ("Boodskap gestuur na bediener:" + nuwe string (messageOut)); int length = serverIn.readInt (); if (lengte> 0) {byte messageIn = nuwe byte [lengte]; serverIn.readFully (messageIn, 0, messageIn.length); }}}

  • Voorwerpstrome

    voer java.io. ObjectInputStream in; voer java.io. ObjectOutputStream in; voer java.net. InetAddress in; invoer java.net. ServerSocket; invoer java.net. Socket; openbare klas NetworkAppExample {public static void main (String args) gooi uitsondering {String host = "localhost"; int poort = 10430; ServerSocket -bediener = nuwe ServerSocket (poort, 50, InetAddress.getByName (gasheer)); System.out.println ("bediener begin."); Socket -kliënt = nuwe Socket (gasheer, poort); System.out.println ("Koppel aan bediener …"); Socketverbinding = server.accept (); System.out.println ("Verbinding tot stand gebring."); ObjectOutputStream clientOut = nuwe ObjectOutputStream (client.getOutputStream ()); ObjectOutputStream serverOut = nuwe ObjectOutputStream (connection.getOutputStream ()); ObjectInputStream clientIn = nuwe ObjectInputStream (client.getInputStream ()); ObjectInputStream serverIn = nuwe ObjectInputStream (connection.getInputStream ()); System.out.println ("Kommunikasie is gereed."); String messageOut = "Hallo wêreld"; clientOut.writeObject (messageOut); clientOut.flush (); System.out.println ("Boodskap gestuur na bediener:" + messageOut); String messageIn = (String) serverIn.readObject (); }}

Skep 'n netwerktoepassing in Java Step16
Skep 'n netwerktoepassing in Java Step16

Stap 16. Log gelees boodskap

Druk vir aanmelddoeleindes na die konsole dat die boodskap ontvang is en druk die inhoud daarvan af.

  • Datastrome

    voer java.io. DataInputStream in; voer java.io. DataOutputStream in; voer java.net. InetAddress in; invoer java.net. ServerSocket; invoer java.net. Socket; openbare klas NetworkAppExample {public static void main (String args) gooi uitsondering {String host = "localhost"; int poort = 10430; ServerSocket -bediener = nuwe ServerSocket (poort, 50, InetAddress.getByName (gasheer)); System.out.println ("bediener begin."); Socket -kliënt = nuwe Socket (gasheer, poort); System.out.println ("Koppel aan bediener …"); Socketverbinding = server.accept (); System.out.println ("Verbinding tot stand gebring."); DataOutputStream clientOut = nuwe DataOutputStream (client.getOutputStream ()); DataInputStream clientIn = nuwe DataInputStream (client.getInputStream ()); DataOutputStream serverOut = nuwe DataOutputStream (connection.getOutputStream ()); DataInputStream serverIn = nuwe DataInputStream (connection.getInputStream ()); System.out.println ("Kommunikasie is gereed."); byte messageOut = "Hello World".getBytes (); clientOut.writeInt (messageOut.length); clientOut.write (messageOut); clientOut.flush (); System.out.println ("Boodskap gestuur na bediener:" + nuwe string (messageOut)); int lengte = serverIn.readInt (); if (lengte> 0) {byte messageIn = nuwe byte [lengte]; serverIn.readFully (messageIn, 0, messageIn.length); System.out.println ("Boodskap ontvang van kliënt:" + nuwe string (messageIn)); }}}

  • Voorwerpstrome

    voer java.io. ObjectInputStream in; voer java.io. ObjectOutputStream in; voer java.net. InetAddress in; invoer java.net. ServerSocket; invoer java.net. Socket; openbare klas NetworkAppExample {public static void main (String args) gooi uitsondering {String host = "localhost"; int poort = 10430; ServerSocket -bediener = nuwe ServerSocket (poort, 50, InetAddress.getByName (gasheer)); System.out.println ("bediener begin."); Socket -kliënt = nuwe Socket (gasheer, poort); System.out.println ("Koppel aan bediener …"); Socketverbinding = server.accept (); System.out.println ("Verbinding tot stand gebring."); ObjectOutputStream clientOut = nuwe ObjectOutputStream (client.getOutputStream ()); ObjectOutputStream serverOut = nuwe ObjectOutputStream (connection.getOutputStream ()); ObjectInputStream clientIn = nuwe ObjectInputStream (client.getInputStream ()); ObjectInputStream serverIn = nuwe ObjectInputStream (connection.getInputStream ()); System.out.println ("Kommunikasie is gereed."); String messageOut = "Hallo wêreld"; clientOut.writeObject (messageOut); clientOut.flush (); System.out.println ("Boodskap gestuur na bediener:" + messageOut); String messageIn = (String) serverIn.readObject (); System.out.println ("Boodskap ontvang van kliënt:" + messageIn); }}

Skep 'n netwerktoepassing in Java Step17
Skep 'n netwerktoepassing in Java Step17

Stap 17. Ontkoppel verbindings

Verbinding word ontkoppel as een party sy strome sluit. In Java word die gepaardgaande aansluiting en invoerstroom ook gesluit deur die uitvoerstroom te sluit. Sodra 'n party aan die ander kant agterkom dat die verbinding dood is, moet dit ook die uitsetstroom sluit om geheue lek te voorkom.

// kode weggelaat invoer java.net. InetAddress; invoer java.net. ServerSocket; invoer java.net. Socket; openbare klas NetworkAppExample {public static void main (String args) gooi uitsondering {String host = "localhost"; int poort = 10430; ServerSocket -bediener = nuwe ServerSocket (poort, 50, InetAddress.getByName (gasheer)); System.out.println ("bediener begin."); Socket -kliënt = nuwe Socket (gasheer, poort); System.out.println ("Koppel aan bediener …"); Socketverbinding = server.accept (); System.out.println ("Verbinding tot stand gebring."); // kode weggelaat System.out.println ("Kommunikasie is gereed."); // kode weggelaat clientOut.close (); serverOut.close (); }}

Skep 'n netwerktoepassing in Java Step18 V2
Skep 'n netwerktoepassing in Java Step18 V2

Stap 18. Log ontkoppeling

Vir aanmelddoeleindes is die verbinding met die afdruk na die konsole ontkoppel.

// kode weggelaat invoer java.net. InetAddress; invoer java.net. ServerSocket; invoer java.net. Socket; openbare klas NetworkAppExample {public static void main (String args) gooi uitsondering {String host = "localhost"; int poort = 10430; ServerSocket -bediener = nuwe ServerSocket (poort, 50, InetAddress.getByName (gasheer)); System.out.println ("bediener begin."); Socket -kliënt = nuwe Socket (gasheer, poort); System.out.println ("Koppel aan bediener …"); Socketverbinding = server.accept (); System.out.println ("Verbinding tot stand gebring."); // kode weggelaat System.out.println ("Kommunikasie is gereed."); // kode weggelaat clientOut.close (); serverOut.close (); System.out.println ("Verbindings gesluit."); }}

Skep 'n netwerktoepassing in Java Step19
Skep 'n netwerktoepassing in Java Step19

Stap 19. Beëindig bediener

Verbindings word ontkoppel, maar bediener is steeds aan die gang. Soos

ServerSocket

word nie met enige stroom geassosieer nie, moet dit uitdruklik gesluit word deur te bel

naby()

metode.

// kode weggelaat invoer java.net. InetAddress; invoer java.net. ServerSocket; invoer java.net. Socket; openbare klas NetworkAppExample {public static void main (String args) gooi uitsondering {String host = "localhost"; int poort = 10430; ServerSocket -bediener = nuwe ServerSocket (poort, 50, InetAddress.getByName (gasheer)); System.out.println ("bediener begin."); Socket -kliënt = nuwe Socket (gasheer, poort); System.out.println ("Koppel aan bediener …"); Socketverbinding = server.accept (); System.out.println ("Verbinding tot stand gebring."); // kode weggelaat System.out.println ("Kommunikasie is gereed."); // kode weggelaat clientOut.close (); serverOut.close (); System.out.println ("Verbindings gesluit."); server.close (); }}

Skep 'n netwerktoepassing in Java Step20
Skep 'n netwerktoepassing in Java Step20

Stap 20. Beëindiging van die logbediener

Om aan te meld, is die druk na die konsole -bediener beëindig.

// kode weggelaat invoer java.net. InetAddress; invoer java.net. ServerSocket; invoer java.net. Socket; openbare klas NetworkAppExample {public static void main (String args) gooi uitsondering {String host = "localhost"; int poort = 10430; ServerSocket -bediener = nuwe ServerSocket (poort, 50, InetAddress.getByName (gasheer)); System.out.println ("bediener begin."); Socket -kliënt = nuwe Socket (gasheer, poort); System.out.println ("Koppel aan bediener …"); Socketverbinding = server.accept (); System.out.println ("Verbinding tot stand gebring."); // kode weggelaat System.out.println ("Kommunikasie is gereed."); // kode weggelaat clientOut.close (); serverOut.close (); System.out.println ("Verbindings gesluit."); server.close (); System.out.println ("Bediener beëindig."); }}

Skep 'n netwerktoepassing in Java Step21
Skep 'n netwerktoepassing in Java Step21

Stap 21. Stel op en voer uit

Deur aan te meld, kon ons weet of die toepassing suksesvol was of nie. Verwagte uitset:

Bediener begin. Koppel tans aan bediener … Verbinding tot stand gebring. Kommunikasie is gereed. Boodskap na bediener gestuur: Hello World Boodskap van kliënt ontvang: Hello World Connections gesluit. Bediener beëindig.

As u uitset nie soos hierbo lyk nie, wat waarskynlik nie sal gebeur nie, is daar 'n paar oplossings:

  • As die uitset by die lyn stop

    Verbinding tot stand gebring.

    en voorwerpstrome word gebruik, spoel elkeen

    ObjectOutputStream

  • onmiddellik na die inisialisering omdat opskrifte om een of ander rede nie gestuur is nie.
  • As die uitvoer gedruk word

    java.net. BindException: Adres wat reeds gebruik word

  • kies 'n ander poortnommer omdat die gespesifiseerde reeds gebruik word.

Wenke

  • Koppel aan 'n bediener op 'n ander netwerk word gedoen deur aan te sluit op die eksterne IP -adres van 'n toestel met 'n bediener met 'n aangestuurde poort.
  • Koppel aan 'n bediener op dieselfde netwerk word gedoen deur óf aan te sluit op die privaat IP -adres van 'n toestel wat die bediener bestuur, óf 'n poort aan te stuur en aan die eksterne IP -adres van die toestel te koppel.
  • Daar is sagteware, soos Hamachi, wat die verbinding met die bediener op 'n ander netwerk moontlik maak sonder om 'n poort aan te stuur, maar dit vereis dat die sagteware op beide toestelle geïnstalleer word.

Voorbeelde

Netwerktoepassings wat blokkeer -invoer/-uitsette gebruik, moet drade gebruik. Die volgende voorbeelde toon 'n minimalistiese implementering van bedieners en kliënte met drade. Netwerkkode is in wese dieselfde as in die artikel, behalwe dat sommige brokkies gesinchroniseer is, in drade ingeskuif en uitsonderings hanteer word.

Server.java

invoer java.io. IOException; voer java.net. InetAddress in; invoer java.net. ServerSocket; voer java.net. SocketException in; voer java.net. UnknownHostException in; voer java.util. ArrayList in; invoer java.util. Collections; invoer java.util. List; /*** Die klas {@code Server} verteenwoordig 'n bediener-eindpunt in 'n netwerk. {@code Server} is eenmaal gebind aan 'n sekere IP * -adres en -poort, skep verbindings met kliënte en kan met hulle kommunikeer of dit ontkoppel. *

* Hierdie klas is draadloos. * * @versie 1.0 * @see -kliënt * @see -verbinding */ openbare klas bediener implementeer Runnable {private ServerSocket -bediener; privaat lys verbindings; privaat draaddraad; private finale Object connectionsLock = nuwe Object (); /** * Bou 'n {@code Server} wat met kliënte in wisselwerking tree op die gespesifiseerde gasheernaam en poort met die gespesifiseerde * verlangde maksimum lengte van 'n tou inkomende kliënte. * * @param -gasheer Gasheeradres om te gebruik. * @param -poort Poortnommer om te gebruik. * @param agterstand Gevraagde maksimum lengte van die tou van inkomende kliënte. * @gooi NetworkException As 'n fout opduik tydens die begin van 'n bediener. */ public Server (String -gasheer, int -poort, int -agterstand) gooi NetworkException {probeer {server = nuwe ServerSocket (poort, agterstand, InetAddress.getByName (gasheer)); } catch (UnknownHostException e) {gooi nuwe NetworkException ("Gasheernaam kon nie opgelos word nie:" + gasheer, e); } catch (IllegalArgumentException e) {gooi nuwe NetworkException ("Poortnommer moet tussen 0 en 65535 (insluitend) wees:" + poort); } catch (IOException e) {gooi nuwe NetworkException ("Server kon nie begin word nie.", e); } verbindings = Collections.synchronizedList (nuwe ArrayList ()); thread = new Thread (hierdie); thread.start (); } /*** Bou 'n {@code Server} wat met kliënte op die gespesifiseerde gasheernaam en poort in wisselwerking tree. * * @param -gasheer Gasheeradres om te bind. * @param -poort Poortnommer om te bind. * @gooi NetworkException As daar foute voorkom tydens die begin van 'n bediener. */ public Server (String -gasheer, int -poort) gooi NetworkException {hierdie (gasheer, poort, 50); } /*** Luister na, aanvaar en registreer inkomende verbindings van kliënte. */ @Overheers openbare leegloop () {terwyl (! Server.isClosed ()) {probeer {connections.add (nuwe verbinding (server.accept ())); } catch (SocketException e) {if (! e.getMessage (). is gelyk ("Socket gesluit")) {e.printStackTrace (); }} catch (NetworkException | IOException e) {e.printStackTrace (); }}} /*** Stuur data aan alle geregistreerde kliënte. * * @param data Data om te stuur. * @gooi IllegalStateException As probeer word om data te skryf as die bediener vanlyn is. * @gooi IllegalArgumentException As data wat gestuur moet word, ongeldig is. */ openbare nietige uitsending (objekdata) {if (server.isClosed ()) {gooi nuwe IllegalStateException ("Data nie gestuur nie, bediener is vanlyn."); } if (data == null) {gooi nuwe IllegalArgumentException ("nul data"); } gesinchroniseer (connectionsLock) {vir (Verbindingsverbinding: verbindings) {probeer {connection.send (data); System.out.println ("Data suksesvol na kliënt gestuur."); } vang (NetworkException e) {e.printStackTrace (); }}}}} /*** Stuur 'n ontkoppelingsboodskap en ontkoppel die spesifieke kliënt. * * @param -verbinding Kliënt moet ontkoppel. * @gooi NetworkException As 'n fout opduik tydens die sluiting van die verbinding. */ openbare leemte ontkoppel (verbinding verbinding) gooi NetworkException {if (connections.remove (verbinding)) {connection.close (); }} /*** Stuur 'n ontkoppelingsboodskap aan alle kliënte, koppel hulle en beëindig die bediener. */ public void close () gooi NetworkException {synchronized (connectionsLock) {vir (Verbindingsverbinding: verbindings) {probeer {connection.close (); } vang (NetworkException e) {e.printStackTrace (); }}} connections.clear (); probeer {server.close (); } catch (IOException e) {gooi nuwe NetworkException ("Fout tydens sluiting van bediener."); } uiteindelik {thread.interrupt (); }} /*** Wys of die bediener aanlyn is of nie. * * @return Waar as bediener aanlyn is. Onwaar, anders. */ public boolean isOnline () {return! server.isClosed (); } /*** Wys 'n verskeidenheid geregistreerde kliënte. */ public Connection getConnections () {synchronized (connectionsLock) {return connections.toArray (new Connection [connections.size ()]); }}}

Kliënt.java

invoer java.io. IOException; invoer java.net. Socket; voer java.net. UnknownHostException in; /*** Die klas {@code Client} verteenwoordig 'n eindpunt van 'n kliënt in 'n netwerk. {@code Client}, sodra dit aan 'n sekere * bediener gekoppel is, kan slegs met die bediener kommunikeer. Of ander kliënte die data * ontvang of nie, hang af van die implementering van die bediener. *

* Hierdie klas is draadloos. * * @versie 1.0 * @see Server * @see Connection */ public class Client {private Connection connection; /*** Bou 'n {@code Client} wat op die gespesifiseerde gasheer en poort aan die bediener gekoppel is. * * @param -gasheer Gasheeradres om te bind. * @param -poort Poortnommer om te bind. * @gooi NetworkException As 'n fout opduik tydens die begin van 'n bediener. */ public Client (String -gasheer, int -poort) gooi NetworkException {try {verbinding = nuwe verbinding (nuwe Socket (gasheer, poort)); } catch (UnknownHostException e) {gooi nuwe NetworkException ("Gasheernaam kon nie opgelos word nie:" + gasheer, e); } catch (IllegalArgumentException e) {gooi nuwe NetworkException ("Poortnommer moet tussen 0 en 65535 (insluitend) wees:" + poort); } catch (IOException e) {gooi nuwe NetworkException ("Server kon nie begin word nie.", e); }} /*** Stuur data aan die ander party. * * @param data Data om te stuur. * @gooi NetworkException As skryf na uitvoerstroom misluk. * @gooi IllegalStateException As probeer word om data te skryf wanneer die verbinding gesluit is. * @gooi IllegalArgumentException As data wat gestuur moet word, ongeldig is. * @throws UnsupportedOperationException As probeer word om nie -ondersteunde datatipe te stuur. */ public void send (Object data) gooi NetworkException {connection.send (data); } /*** Stuur 'n ontkoppelingsboodskap na die bediener en sluit die verbinding met die bediener. */ public void close () gooi NetworkException {connection.close (); } /*** Wys of die kliënt aan die bediener gekoppel is al dan nie. * * @return Waar as die kliënt gekoppel is. Onwaar, anders. */ public boolean isOnline () {return connection.isConnected (); } /*** Wys die {@link Connection} -voorkoms van die kliënt. */ public Connection getConnection () {terugkeer verbinding; }}

Verbinding.java

voer java.io. DataInputStream in; voer java.io. DataOutputStream in; invoer java.io. IOException; invoer java.net. Socket; voer java.net. SocketException in; /** * Die klas {@code Connection} verteenwoordig óf 'n verbinding van bediener tot kliënt, óf 'n eindpunt van 'n kliënt in 'n netwerk * {@code Connection} kan, nadat dit gekoppel is, data met ander partye of partye uitruil op 'n bediener * implementering. *

* Hierdie klas is draadloos. * * @versie 1.0 * @see bediener * @see kliënt */ openbare klas Verbinding implementeer Runnable {private Socket socket; private DataOutputStream uit; private DataInputStream in; privaat draaddraad; private finale Object writeLock = nuwe Object (); private finale Object readLock = nuwe Object (); /*** Bou {@code Connection} met strome van 'n gespesifiseerde {@link Socket}. * * @param -aansluiting Sok om die strome uit te haal.*/ public Connection (Socket socket) gooi NetworkException {if (socket == null) {gooi nuwe IllegalArgumentException ("null socket"); } hierdie.socket = sok; probeer {out = nuwe DataOutputStream (socket.getOutputStream ()); } catch (IOException e) {gooi nuwe NetworkException ("Kon nie toegang tot die uitsetstroom kry nie.", e); } probeer {in = nuwe DataInputStream (socket.getInputStream ()); } catch (IOException e) {gooi nuwe NetworkException ("Kon nie toegang tot invoerstroom kry nie.", e); } draad = nuwe draad (hierdie); thread.start (); } /*** Lees boodskappe terwyl die verbinding met die ander party bestaan. */ @Overheers openbare leegloop () {terwyl (! Socket.isClosed ()) {probeer {int identifiseerder; byte grepe; gesinchroniseer (readLock) {identifier = in.readInt (); int lengte = in.readInt (); as (lengte> 0) {grepe = nuwe greep [lengte]; in.readFully (grepe, 0, grepe.lengte); } anders {vervolg; }} switch (identifier) {case Identifier. INTERNAL: String command = new String (grepe); if (command.equals ("ontkoppel")) {if (! socket.isClosed ()) {System.out.println ("Ontkoppelingspakket ontvang."); probeer {close (); } vang (NetworkException e) {opgawe; } } } breek; case Identifier. TEXT: System.out.println ("Boodskap ontvang:" + nuwe string (grepe)); breek; standaard: System.out.println ("Onherkenbare data ontvang."); }} catch (SocketException e) {if (! e.getMessage (). equals ("Socket closed")) {e.printStackTrace (); }} vang (IOException e) {e.printStackTrace (); }}} /*** Stuur data aan die ander party. * * @param data Data om te stuur. * @gooi NetworkException As skryf na uitvoerstroom misluk. * @gooi IllegalStateException As probeer word om data te skryf wanneer die verbinding gesluit is. * @gooi IllegalArgumentException As data wat gestuur moet word, ongeldig is. * @throws UnsupportedOperationException As probeer word om nie -ondersteunde datatipe te stuur. */ public void send (Object data) gooi NetworkException {if (socket.isClosed ()) {gooi nuwe IllegalStateException ("Data nie gestuur nie, verbinding is gesluit."); } if (data == null) {gooi nuwe IllegalArgumentException ("nul data"); } int identifiseerder; byte grepe; as (data -instansie van string) {identifier = Identifier. TEXT; grepe = ((String) data).getBytes (); } anders {gooi nuwe UnsupportedOperationException ("Ongesteunde datatipe:" + data.getClass ()); } probeer {synchronized (writeLock) {out.writeInt (identifiseerder); out.writeInt (grepe.lengte); out.write (grepe); uit.spoel (); }} catch (IOException e) {gooi nuwe NetworkException ("Data kon nie gestuur word nie.", e); }} /*** Stuur 'n ontbrekingsboodskap na die verbinding en sluit die verbinding met die ander party. */ public void close () gooi NetworkException {if (socket.isClosed ()) {gooi nuwe IllegalStateException ("Verbinding is reeds gesluit."); } probeer {byte message = "ontkoppel".getBytes (); gesinchroniseer (writeLock) {out.writeInt (Identifier. INTERNAL); out.writeInt (boodskap.lengte); uit.skryf (boodskap); uit.spoel (); }} catch (IOException e) {System.out.println ("Ontkoppelingsboodskap kon nie gestuur word nie."); } probeer {synchronized (writeLock) {out.close (); }} catch (IOException e) {gooi nuwe NetworkException ("Fout tydens die sluiting van verbinding.", e); } uiteindelik {thread.interrupt (); }} /*** Wys of die verbinding met die ander party bestaan of nie. * * @return Waar as die verbinding lewendig is. Onwaar, anders. */ public boolean isConnected () {return! socket.isClosed (); }}

Identifier.java

/** * Die klas {@code Identifier} bevat konstantes wat deur {@link Connection} gebruik word om die data * wat oor die netwerk gestuur is, te serialiseer en te deserialiseer. * * @versie 1.0 * @sien verbinding * / openbare finale klas -identifiseerder { / ** * identifiseerder vir interne boodskappe. */ public static final int INTERNAL = 1; /*** Identifiseerder vir teksboodskappe. */ public static final int TEKS = 2; }

NetworkException.java

/*** Die klas {@code NetworkException} dui 'n fout aan wat verband hou met die netwerk. * / openbare klas NetworkException brei uitsondering uit { / *** Konstrueer 'n {@code NetworkException} met {@code null} as boodskap. * / public NetworkException () {} / *** Bou 'n {@code NetworkException} met die gespesifiseerde boodskap. * * @param -boodskap 'n Boodskap om die fout te beskryf. */ public NetworkException (string boodskap) {super (boodskap); } /*** Stel 'n {@code NetworkException} saam met die gespesifiseerde boodskap en oorsaak. * * @param -boodskap 'n Boodskap om die fout te beskryf. * @param oorsaak 'n Oorsaak van fout. */ public NetworkException (String -boodskap, oorsaak wat veroorsaak kan word) {super (boodskap, oorsaak); } /*** Bou 'n {@code NetworkException} met die gespesifiseerde oorsaak. * * @param oorsaak 'n Oorsaak van fout. */ public NetworkException (oorsaak wat veroorsaak kan word) {super (oorsaak); }}

Gebruiksvoorbeeld.java

/*** Die klas {@code UsageExample} toon die gebruik van {@link Server} en {@link Client}. Hierdie voorbeelde gebruik * {@link Thread#sleep (long)} om te verseker dat elke segment uitgevoer word, omdat sommige * segmente nie vinnig begin en sluit nie. * * @versie 1.0 * @see bediener * @see kliënt */ openbare klas UsageExample {openbare statiese leemte hoof (String args) gooi uitsondering {String host = "localhost"; int poort = 10430; Bedienerbediener = nuwe bediener (gasheer, poort); Kliëntkliënt = nuwe kliënt (gasheer, poort); Draad. Slaap (100L); client.send ("Hallo."); server.broadcast ("Hey, ou!"); Draad. Slaap (100L); server.disconnect (server.getConnections () [0]); // of client.close () om van die server.close () af te skakel; }}

Aanbeveel: