Com es crea una aplicació de xarxa a Java (amb imatges)

Taula de continguts:

Com es crea una aplicació de xarxa a Java (amb imatges)
Com es crea una aplicació de xarxa a Java (amb imatges)

Vídeo: Com es crea una aplicació de xarxa a Java (amb imatges)

Vídeo: Com es crea una aplicació de xarxa a Java (amb imatges)
Vídeo: Como hacer una captura de pantalla con gestos SIN USAR BOTONES 2024, Abril
Anonim

Escriure codi que s’executa en un determinat dispositiu és molt satisfactori. Però escriure codi que s’executa en diversos dispositius que es comuniquen entre si és simplement afirmar la vida. Aquest article us ensenyarà a connectar i intercanviar missatges per xarxa mitjançant el protocol de control de transmissió (TCP).

En aquest article, configurareu una aplicació que connectarà l’ordinador a si mateix i, essencialment, el tornarà boig: parleu amb ell mateix. També aprendreu la diferència entre els dos fluxos més utilitzats per a la creació de xarxes a Java i el seu funcionament.

Fluxos de dades i objectes

Abans de capbussar-vos en el codi, cal distingir la diferència entre els dos corrents utilitzats a l'article.

Fluxos de dades

Els fluxos de dades processen tipus i cadenes de dades primitives. Les dades enviades a través de fluxos de dades han de ser serialitzades i deserialitzades manualment, cosa que dificulta la transferència de dades complexes. Però els fluxos de dades poden comunicar-se amb servidors i clients escrits en altres idiomes diferents de Java. Els fluxos bruts són similars als fluxos de dades en aquest aspecte, però els fluxos de dades asseguren que les dades es formaten de manera independent de la plataforma, cosa que resulta beneficiosa perquè les dues parts podran llegir les dades enviades.

Corrents d'objectes

Els fluxos d'objectes processen tipus de dades primitius i objectes que implementen

Serialitzable

interfície. Les dades enviades per fluxos d'objectes es serialitzen i deserialitzen automàticament, cosa que facilita la transferència de dades complexes. Però els fluxos d'objectes només es poden comunicar amb servidors i clients escrits en Java. A més,

ObjectOutputStream

després de la inicialització, envia una capçalera a

InputStream

de l’altra part que, en inicialitzar-la, bloqueja l’execució fins que es rep la capçalera.

Passos

Creeu una aplicació de xarxa a Java Step1
Creeu una aplicació de xarxa a Java Step1

Pas 1. Creeu una classe

Creeu una classe i anomeneu-la com vulgueu. En aquest article, s’anomenarà

NetworkAppExample

classe pública NetworkAppExample {}

Creeu una aplicació de xarxa a Java Step2
Creeu una aplicació de xarxa a Java Step2

Pas 2. Creeu un mètode principal

Creeu un mètode principal i declareu que pot generar excepcions de

Excepció

tipus i qualsevol subclasse d’aquest, totes excepcions. Es considera una mala pràctica, però és acceptable per als exemples de barebone.

classe pública NetworkAppExample {public static void main (String args) throws Exception {}}

Creeu una aplicació de xarxa a Java Step3
Creeu una aplicació de xarxa a Java Step3

Pas 3. Declareu l'adreça del servidor

En aquest exemple s'utilitzarà l'adreça d'amfitrió local i un número de port arbitrari. El número de port ha d’estar entre 0 i 65535 (inclosos). Tanmateix, els números de ports per evitar oscil·len entre 0 i 1023 (inclosos) perquè són ports del sistema reservats.

classe pública NetworkAppExample {public static void main (String args) llança Excepció {String host = "localhost"; int port = 10430; }}

Creeu una aplicació de xarxa a Java Step4
Creeu una aplicació de xarxa a Java Step4

Pas 4. Creeu un servidor

El servidor està vinculat a l'adreça i al port i escolta les connexions entrants. A Java,

ServerSocket

representa el punt final del servidor i la seva funció és acceptar noves connexions.

ServerSocket

no té fluxos per llegir i enviar dades perquè no representa la connexió entre un servidor i un client.

importació java.net. InetAddress; importar java.net. ServerSocket; classe pública NetworkAppExample {public static void main (String args) llança Excepció {String host = "localhost"; int port = 10430; ServerSocket server = ServerSocket nou (port, 50, InetAddress.getByName (host)); }}

Creeu una aplicació de xarxa a Java Step5
Creeu una aplicació de xarxa a Java Step5

Pas 5. Creació del servidor de registre

A efectes de registre, imprimiu a la consola que s'ha iniciat el servidor.

importació java.net. InetAddress; importar java.net. ServerSocket; classe pública NetworkAppExample {public static void main (String args) llança Excepció {String host = "localhost"; int port = 10430; ServerSocket server = ServerSocket nou (port, 50, InetAddress.getByName (host)); System.out.println ("S'ha iniciat el servidor"); }}

Creeu una aplicació de xarxa a Java Step6
Creeu una aplicació de xarxa a Java Step6

Pas 6. Creeu un client

El client està lligat a l'adreça i al port d'un servidor i escolta els paquets (missatges) després que s'estableixi la connexió. A Java,

Endoll

representa un punt final del costat del client connectat al servidor o una connexió (des del servidor) al client i s'utilitza per comunicar-se amb la part de l'altre extrem.

importació java.net. InetAddress; importar java.net. ServerSocket; importació de java.net. Socket; classe pública NetworkAppExample {public static void main (String args) llança Excepció {String host = "localhost"; int port = 10430; ServerSocket server = ServerSocket nou (port, 50, InetAddress.getByName (host)); System.out.println ("S'ha iniciat el servidor"); Socket client = nou socket (host, port); }}

Creeu una aplicació de xarxa a Java Step7
Creeu una aplicació de xarxa a Java Step7

Pas 7. Intent de connexió de registre

A efectes de registre, imprimiu a la consola que s'ha intentat la connexió.

importació java.net. InetAddress; importar java.net. ServerSocket; importació de java.net. Socket; classe pública NetworkAppExample {public static void main (String args) llança Excepció {String host = "localhost"; int port = 10430; ServerSocket server = ServerSocket nou (port, 50, InetAddress.getByName (host)); System.out.println ("S'ha iniciat el servidor"); Socket client = nou socket (host, port); System.out.println ("Connexió al servidor …"); }}

Creeu una aplicació de xarxa a Java Step8
Creeu una aplicació de xarxa a Java Step8

Pas 8. Establir connexió

Els clients no es connectaran mai tret que el servidor escolti i accepti connexions, és a dir, que estableixi. A Java, les connexions s’estableixen mitjançant

acceptar ()

mètode de

ServerSocket

classe. El mètode bloquejarà l'execució fins que es connecti un client.

importació java.net. InetAddress; importar java.net. ServerSocket; importació de java.net. Socket; classe pública NetworkAppExample {public static void main (String args) llança Excepció {String host = "localhost"; int port = 10430; ServerSocket server = ServerSocket nou (port, 50, InetAddress.getByName (host)); System.out.println ("S'ha iniciat el servidor"); Socket client = nou socket (host, port); System.out.println ("Connexió al servidor …"); Connexió de sòcol = server.accept (); }}

Creeu una aplicació de xarxa a Java Step9
Creeu una aplicació de xarxa a Java Step9

Pas 9. Registre de la connexió establerta

A efectes de registre, imprimiu a la consola que s'ha establert la connexió entre el servidor i el client.

importació java.net. InetAddress; importar java.net. ServerSocket; importació de java.net. Socket; classe pública NetworkAppExample {public static void main (String args) llança Excepció {String host = "localhost"; int port = 10430; ServerSocket server = ServerSocket nou (port, 50, InetAddress.getByName (host)); System.out.println ("S'ha iniciat el servidor"); Socket client = nou socket (host, port); System.out.println ("Connexió al servidor …"); Connexió de sòcol = server.accept (); System.out.println ("Connexió establerta"); }}

Creeu una aplicació de xarxa a Java Step10
Creeu una aplicació de xarxa a Java Step10

Pas 10. Prepareu corrents de comunicació

La comunicació es fa a través de fluxos i, en aquesta aplicació, els fluxos bruts de (connexió des) del servidor (al client) i del client han de ser encadenats a fluxos de dades o objectes. Recordeu que les dues parts han d’utilitzar el mateix tipus de flux.

  • Fluxos de dades

    importació java.io. DataInputStream; importació java.io. DataOutputStream; importació java.net. InetAddress; importar java.net. ServerSocket; importació de java.net. Socket; classe pública NetworkAppExample {public static void main (String args) llança Excepció {String host = "localhost"; int port = 10430; ServerSocket server = ServerSocket nou (port, 50, InetAddress.getByName (host)); System.out.println ("S'ha iniciat el servidor"); Socket client = nou socket (host, port); System.out.println ("Connexió al servidor …"); Connexió de sòcol = server.accept (); System.out.println ("Connexió establerta"); DataOutputStream clientOut = new DataOutputStream (client.getOutputStream ()); DataInputStream clientIn = new DataInputStream (client.getInputStream ()); DataOutputStream serverOut = new DataOutputStream (connection.getOutputStream ()); DataInputStream serverIn = new DataInputStream (connection.getInputStream ()); }}

  • Corrents d'objectes

    Quan s'utilitzen múltiples fluxos d'objectes, els fluxos d'entrada s'han d'inicialitzar en el mateix ordre que els fluxos de sortida perquè

    ObjectOutputStream

    envia una capçalera a l'altra part i

    ObjectInputStream

    bloqueja l'execució fins que llegeixi la capçalera.

    importació java.io. ObjectInputStream; importació java.io. ObjectOutputStream; importació java.net. InetAddress; importar java.net. ServerSocket; importació de java.net. Socket; classe pública NetworkAppExample {public static void main (String args) llança Excepció {String host = "localhost"; int port = 10430; ServerSocket server = ServerSocket nou (port, 50, InetAddress.getByName (host)); System.out.println ("S'ha iniciat el servidor"); Socket client = nou socket (host, port); System.out.println ("Connexió al servidor …"); Connexió de sòcol = server.accept (); System.out.println ("Connexió establerta"); ObjectOutputStream clientOut = new ObjectOutputStream (client.getOutputStream ()); ObjectOutputStream serverOut = nou ObjectOutputStream (connection.getOutputStream ()); ObjectInputStream clientIn = nou ObjectInputStream (client.getInputStream ()); ObjectInputStream serverIn = nou ObjectInputStream (connection.getInputStream ()); }}

    És possible que sigui més fàcil de recordar l’ordre tal com s’especifica al codi anterior: inicialitzeu primer els fluxos de sortida i després els fluxos d’entrada en el mateix ordre. Tanmateix, un altre ordre d'inicialització dels fluxos d'objectes és el següent:

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

Creeu una aplicació de xarxa a Java Step11
Creeu una aplicació de xarxa a Java Step11

Pas 11. Registreu que la comunicació estigui preparada

A efectes de registre, imprimiu a la consola que la comunicació estigui preparada.

// codi omès importació java.net. InetAddress; importar java.net. ServerSocket; importació de java.net. Socket; classe pública NetworkAppExample {public static void main (String args) llança Excepció {String host = "localhost"; int port = 10430; ServerSocket server = ServerSocket nou (port, 50, InetAddress.getByName (host)); System.out.println ("S'ha iniciat el servidor"); Socket client = nou socket (host, port); System.out.println ("Connexió al servidor …"); Connexió de sòcol = server.accept (); System.out.println ("Connexió establerta"); // codi omès System.out.println ("La comunicació està preparada"); }}

Creeu una aplicació de xarxa a Java Step12
Creeu una aplicació de xarxa a Java Step12

Pas 12. Creeu un missatge

En aquesta aplicació,

Hola món

el text s'enviarà al servidor com a

byte

o bé

Corda

. Declareu una variable del tipus que depèn del flux utilitzat. Ús

byte

per a fluxos de dades i

Corda

per a corrents d'objectes.

  • Fluxos de dades

    Utilitzant fluxos de dades, la serialització es fa convertint objectes en tipus de dades primitius o a

    Corda

    . En aquest cas,

    Corda

    es converteix a

    byte

    en lloc d’escriure amb

    writeBytes ()

    mètode per mostrar com es faria amb altres objectes, com ara imatges o altres fitxers.

    importació java.io. DataInputStream; importació java.io. DataOutputStream; importació java.net. InetAddress; importar java.net. ServerSocket; importació de java.net. Socket; classe pública NetworkAppExample {public static void main (String args) llança Excepció {String host = "localhost"; int port = 10430; ServerSocket server = ServerSocket nou (port, 50, InetAddress.getByName (host)); System.out.println ("S'ha iniciat el servidor"); Socket client = nou socket (host, port); System.out.println ("Connexió al servidor …"); Connexió de sòcol = server.accept (); System.out.println ("Connexió establerta"); DataOutputStream clientOut = new DataOutputStream (client.getOutputStream ()); DataInputStream clientIn = new DataInputStream (client.getInputStream ()); DataOutputStream serverOut = new DataOutputStream (connection.getOutputStream ()); DataInputStream serverIn = new DataInputStream (connection.getInputStream ()); System.out.println ("La comunicació està preparada"); byte messageOut = "Hello World".getBytes (); }}

  • Corrents d'objectes

    importació java.io. ObjectInputStream; importació java.io. ObjectOutputStream; importació java.net. InetAddress; importar java.net. ServerSocket; importació de java.net. Socket; classe pública NetworkAppExample {public static void main (String args) llança Excepció {String host = "localhost"; int port = 10430; ServerSocket server = ServerSocket nou (port, 50, InetAddress.getByName (host)); System.out.println ("S'ha iniciat el servidor"); Socket client = nou socket (host, port); System.out.println ("Connexió al servidor …"); Connexió de sòcol = server.accept (); System.out.println ("Connexió establerta"); ObjectOutputStream clientOut = new ObjectOutputStream (client.getOutputStream ()); ObjectOutputStream serverOut = nou ObjectOutputStream (connection.getOutputStream ()); ObjectInputStream clientIn = nou ObjectInputStream (client.getInputStream ()); ObjectInputStream serverIn = nou ObjectInputStream (connection.getInputStream ()); System.out.println ("La comunicació està preparada"); String messageOut = "Hola món"; }}

Creeu una aplicació de xarxa a Java Step13
Creeu una aplicació de xarxa a Java Step13

Pas 13. Envieu el missatge

Escriviu dades al flux de sortida i netegeu-lo per assegurar-vos que les dades s’han escrit completament.

  • Fluxos de dades

    Primer s’ha d’enviar la longitud d’un missatge perquè l’altra part sàpiga quants bytes ha de llegir. Després d'enviar la longitud com a tipus enter primitiu, es poden enviar bytes.

    importació java.io. DataInputStream; importació java.io. DataOutputStream; importació java.net. InetAddress; importar java.net. ServerSocket; importació de java.net. Socket; classe pública NetworkAppExample {public static void main (String args) llança Excepció {String host = "localhost"; int port = 10430; ServerSocket server = ServerSocket nou (port, 50, InetAddress.getByName (host)); System.out.println ("S'ha iniciat el servidor"); Socket client = nou socket (host, port); System.out.println ("Connexió al servidor …"); Connexió de sòcol = server.accept (); System.out.println ("Connexió establerta"); DataOutputStream clientOut = new DataOutputStream (client.getOutputStream ()); DataInputStream clientIn = new DataInputStream (client.getInputStream ()); DataOutputStream serverOut = new DataOutputStream (connection.getOutputStream ()); DataInputStream serverIn = new DataInputStream (connection.getInputStream ()); System.out.println ("La comunicació està preparada"); byte messageOut = "Hello World".getBytes (); clientOut.writeInt (messageOut.length); clientOut.write (messageOut); clientOut.flush (); }}

  • Corrents d'objectes

    importació java.io. ObjectInputStream; importació java.io. ObjectOutputStream; importació java.net. InetAddress; importar java.net. ServerSocket; importació de java.net. Socket; classe pública NetworkAppExample {public static void main (String args) llança Excepció {String host = "localhost"; int port = 10430; ServerSocket server = ServerSocket nou (port, 50, InetAddress.getByName (host)); System.out.println ("S'ha iniciat el servidor"); Socket client = nou socket (host, port); System.out.println ("Connexió al servidor …"); Connexió de sòcol = server.accept (); System.out.println ("Connexió establerta"); ObjectOutputStream clientOut = nou ObjectOutputStream (client.getOutputStream ()); ObjectOutputStream serverOut = nou ObjectOutputStream (connection.getOutputStream ()); ObjectInputStream clientIn = nou ObjectInputStream (client.getInputStream ()); ObjectInputStream serverIn = nou ObjectInputStream (connection.getInputStream ()); System.out.println ("La comunicació està preparada"); String messageOut = "Hola món"; clientOut.writeObject (messageOut); clientOut.flush (); }}

Creeu una aplicació de xarxa a Java Step14
Creeu una aplicació de xarxa a Java Step14

Pas 14. Registre del missatge enviat

A efectes de registre, imprimiu a la consola que s'ha enviat el missatge.

  • Fluxos de dades

    importació java.io. DataInputStream; importació java.io. DataOutputStream; importació java.net. InetAddress; importar java.net. ServerSocket; importació de java.net. Socket; classe pública NetworkAppExample {public static void main (String args) llança Excepció {String host = "localhost"; int port = 10430; ServerSocket server = ServerSocket nou (port, 50, InetAddress.getByName (host)); System.out.println ("S'ha iniciat el servidor"); Socket client = nou socket (host, port); System.out.println ("Connexió al servidor …"); Connexió de sòcol = server.accept (); System.out.println ("Connexió establerta"); DataOutputStream clientOut = new DataOutputStream (client.getOutputStream ()); DataInputStream clientIn = new DataInputStream (client.getInputStream ()); DataOutputStream serverOut = new DataOutputStream (connection.getOutputStream ()); DataInputStream serverIn = new DataInputStream (connection.getInputStream ()); System.out.println ("La comunicació està preparada"); byte messageOut = "Hello World".getBytes (); clientOut.writeInt (messageOut.length); clientOut.write (messageOut); clientOut.flush (); System.out.println ("Missatge enviat al servidor:" + nova cadena (messageOut)); }}

  • Corrents d'objectes

    importació java.io. ObjectInputStream; importació java.io. ObjectOutputStream; importació java.net. InetAddress; importar java.net. ServerSocket; importació de java.net. Socket; classe pública NetworkAppExample {public static void main (String args) llança Excepció {String host = "localhost"; int port = 10430; ServerSocket server = ServerSocket nou (port, 50, InetAddress.getByName (host)); System.out.println ("S'ha iniciat el servidor"); Socket client = nou socket (host, port); System.out.println ("Connexió al servidor …"); Connexió de sòcol = server.accept (); System.out.println ("Connexió establerta"); ObjectOutputStream clientOut = nou ObjectOutputStream (client.getOutputStream ()); ObjectOutputStream serverOut = nou ObjectOutputStream (connection.getOutputStream ()); ObjectInputStream clientIn = nou ObjectInputStream (client.getInputStream ()); ObjectInputStream serverIn = nou ObjectInputStream (connection.getInputStream ()); System.out.println ("La comunicació està preparada"); String messageOut = "Hola món"; clientOut.writeObject (messageOut); clientOut.flush (); System.out.println ("Missatge enviat al servidor:" + messageOut); }}

Creeu una aplicació de xarxa a Java Step15
Creeu una aplicació de xarxa a Java Step15

Pas 15. Llegiu el missatge

Llegiu les dades del flux d’entrada i convertiu-les. Com que sabem exactament el tipus de dades enviades, crearem un fitxer

Corda

des de

byte

o repartiment

Objecte

a

Corda

sense comprovar-ho, segons el flux utilitzat.

  • Fluxos de dades

    Com que la longitud s'envia primer i els bytes després, la lectura s'ha de fer en el mateix ordre. En cas que la longitud sigui zero, no hi ha res a llegir. L'objecte es deserialitza quan els bytes es tornen a convertir en una instància, en aquest cas, de

    Corda

    importació java.io. DataInputStream; importació java.io. DataOutputStream; importació java.net. InetAddress; importar java.net. ServerSocket; importació de java.net. Socket; classe pública NetworkAppExample {public static void main (String args) llança Excepció {String host = "localhost"; int port = 10430; ServerSocket server = ServerSocket nou (port, 50, InetAddress.getByName (host)); System.out.println ("S'ha iniciat el servidor"); Socket client = nou socket (host, port); System.out.println ("Connexió al servidor …"); Connexió de sòcol = server.accept (); System.out.println ("Connexió establerta"); DataOutputStream clientOut = new DataOutputStream (client.getOutputStream ()); DataInputStream clientIn = new DataInputStream (client.getInputStream ()); DataOutputStream serverOut = new DataOutputStream (connection.getOutputStream ()); DataInputStream serverIn = new DataInputStream (connection.getInputStream ()); System.out.println ("La comunicació està preparada"); byte messageOut = "Hello World".getBytes (); clientOut.writeInt (messageOut.length); clientOut.write (messageOut); clientOut.flush (); System.out.println ("Missatge enviat al servidor:" + nova cadena (messageOut)); int length = serverIn.readInt (); if (longitud> 0) {byte messageIn = new byte [length]; serverIn.readFully (messageIn, 0, messageIn.length); }}}

  • Corrents d'objectes

    importació java.io. ObjectInputStream; importació java.io. ObjectOutputStream; importació java.net. InetAddress; importar java.net. ServerSocket; importació de java.net. Socket; classe pública NetworkAppExample {public static void main (String args) llança Excepció {String host = "localhost"; int port = 10430; ServerSocket server = ServerSocket nou (port, 50, InetAddress.getByName (host)); System.out.println ("S'ha iniciat el servidor"); Socket client = nou socket (host, port); System.out.println ("Connexió al servidor …"); Connexió de sòcol = server.accept (); System.out.println ("Connexió establerta"); ObjectOutputStream clientOut = nou ObjectOutputStream (client.getOutputStream ()); ObjectOutputStream serverOut = nou ObjectOutputStream (connection.getOutputStream ()); ObjectInputStream clientIn = nou ObjectInputStream (client.getInputStream ()); ObjectInputStream serverIn = nou ObjectInputStream (connection.getInputStream ()); System.out.println ("La comunicació està preparada"); String messageOut = "Hola món"; clientOut.writeObject (messageOut); clientOut.flush (); System.out.println ("Missatge enviat al servidor:" + messageOut); String messageIn = (String) serverIn.readObject (); }}

Creeu una aplicació de xarxa a Java Step16
Creeu una aplicació de xarxa a Java Step16

Pas 16. Registre de missatge de lectura

A efectes de registre, imprimiu a la consola que s'ha rebut el missatge i imprimiu-ne el contingut.

  • Fluxos de dades

    importació java.io. DataInputStream; importació java.io. DataOutputStream; importació java.net. InetAddress; importar java.net. ServerSocket; importació de java.net. Socket; classe pública NetworkAppExample {public static void main (String args) llança Excepció {String host = "localhost"; int port = 10430; ServerSocket server = ServerSocket nou (port, 50, InetAddress.getByName (host)); System.out.println ("S'ha iniciat el servidor"); Socket client = nou socket (host, port); System.out.println ("Connexió al servidor …"); Connexió de sòcol = server.accept (); System.out.println ("Connexió establerta"); DataOutputStream clientOut = new DataOutputStream (client.getOutputStream ()); DataInputStream clientIn = new DataInputStream (client.getInputStream ()); DataOutputStream serverOut = new DataOutputStream (connection.getOutputStream ()); DataInputStream serverIn = new DataInputStream (connection.getInputStream ()); System.out.println ("La comunicació està preparada"); byte messageOut = "Hello World".getBytes (); clientOut.writeInt (messageOut.length); clientOut.write (messageOut); clientOut.flush (); System.out.println ("Missatge enviat al servidor:" + nova cadena (messageOut)); int length = serverIn.readInt (); if (longitud> 0) {byte messageIn = new byte [length]; serverIn.readFully (messageIn, 0, messageIn.length); System.out.println ("Missatge rebut del client:" + nova cadena (messageIn)); }}}

  • Corrents d'objectes

    importació java.io. ObjectInputStream; importació java.io. ObjectOutputStream; importació java.net. InetAddress; importar java.net. ServerSocket; importació de java.net. Socket; classe pública NetworkAppExample {public static void main (String args) llança Excepció {String host = "localhost"; int port = 10430; ServerSocket server = ServerSocket nou (port, 50, InetAddress.getByName (host)); System.out.println ("S'ha iniciat el servidor"); Socket client = nou socket (host, port); System.out.println ("Connexió al servidor …"); Connexió de sòcol = server.accept (); System.out.println ("Connexió establerta"); ObjectOutputStream clientOut = nou ObjectOutputStream (client.getOutputStream ()); ObjectOutputStream serverOut = nou ObjectOutputStream (connection.getOutputStream ()); ObjectInputStream clientIn = nou ObjectInputStream (client.getInputStream ()); ObjectInputStream serverIn = nou ObjectInputStream (connection.getInputStream ()); System.out.println ("La comunicació està preparada"); String messageOut = "Hola món"; clientOut.writeObject (messageOut); clientOut.flush (); System.out.println ("Missatge enviat al servidor:" + messageOut); String messageIn = (String) serverIn.readObject (); System.out.println ("Missatge rebut del client:" + messageIn); }}

Creeu una aplicació de xarxa a Java Step17
Creeu una aplicació de xarxa a Java Step17

Pas 17. Desconnecteu les connexions

La connexió es desconnecta quan una de les parts tanca els seus fluxos. A Java, en tancar el flux de sortida, també es tanquen el sòcol i el flux d’entrada associats. Una vegada que un grup de l'altre extrem descobreix que la connexió està morta, també ha de tancar el flux de sortida per evitar fuites de memòria.

// codi omès importació java.net. InetAddress; importar java.net. ServerSocket; importació de java.net. Socket; classe pública NetworkAppExample {public static void main (String args) llança Excepció {String host = "localhost"; int port = 10430; ServerSocket server = ServerSocket nou (port, 50, InetAddress.getByName (host)); System.out.println ("S'ha iniciat el servidor"); Socket client = nou socket (host, port); System.out.println ("Connexió al servidor …"); Connexió de sòcol = server.accept (); System.out.println ("Connexió establerta"); // codi omès System.out.println ("La comunicació està preparada"); // codi omès clientOut.close (); serverOut.close (); }}

Creeu una aplicació de xarxa a Java Step18 V2
Creeu una aplicació de xarxa a Java Step18 V2

Pas 18. Desconnexió del registre

A efectes de registre, s'ha desconnectat la impressió a les connexions de la consola.

// codi omès importació java.net. InetAddress; importar java.net. ServerSocket; importació de java.net. Socket; classe pública NetworkAppExample {public static void main (String args) llança Excepció {String host = "localhost"; int port = 10430; ServerSocket server = ServerSocket nou (port, 50, InetAddress.getByName (host)); System.out.println ("S'ha iniciat el servidor"); Socket client = nou socket (host, port); System.out.println ("Connexió al servidor …"); Connexió de sòcol = server.accept (); System.out.println ("Connexió establerta"); // codi omès System.out.println ("La comunicació està preparada"); // codi omès clientOut.close (); serverOut.close (); System.out.println ("Connexions tancades"); }}

Creeu una aplicació de xarxa a Java Step19
Creeu una aplicació de xarxa a Java Step19

Pas 19. Finalitzeu el servidor

Les connexions estan desconnectades, però el servidor encara està en funcionament. Com

ServerSocket

no s’associa a cap flux, s’ha de tancar explícitament trucant

Tanca()

mètode.

// codi omès importació java.net. InetAddress; importar java.net. ServerSocket; importació de java.net. Socket; classe pública NetworkAppExample {public static void main (String args) llança Excepció {String host = "localhost"; int port = 10430; ServerSocket server = ServerSocket nou (port, 50, InetAddress.getByName (host)); System.out.println ("S'ha iniciat el servidor"); Socket client = nou socket (host, port); System.out.println ("Connexió al servidor …"); Connexió de sòcol = server.accept (); System.out.println ("Connexió establerta"); // codi omès System.out.println ("La comunicació està preparada"); // codi omès clientOut.close (); serverOut.close (); System.out.println ("Connexions tancades"); server.close (); }}

Creeu una aplicació de xarxa a Java Step20
Creeu una aplicació de xarxa a Java Step20

Pas 20. Terminació del servidor de registre

A efectes de registre, s'ha finalitzat la impressió al servidor de la consola.

// codi omès importació java.net. InetAddress; importar java.net. ServerSocket; importació de java.net. Socket; classe pública NetworkAppExample {public static void main (String args) llança Excepció {String host = "localhost"; int port = 10430; ServerSocket server = ServerSocket nou (port, 50, InetAddress.getByName (host)); System.out.println ("S'ha iniciat el servidor"); Socket client = nou socket (host, port); System.out.println ("Connexió al servidor …"); Connexió de sòcol = server.accept (); System.out.println ("Connexió establerta"); // codi omès System.out.println ("La comunicació està preparada"); // codi omès clientOut.close (); serverOut.close (); System.out.println ("Connexions tancades"); server.close (); System.out.println ("Servidor finalitzat"); }}

Creeu una aplicació de xarxa a Java Step21
Creeu una aplicació de xarxa a Java Step21

Pas 21. Compileu i executeu

El registre ens ha permès saber si l’aplicació ha estat correcta o no. Sortida prevista:

S'ha iniciat el servidor. Connexió al servidor … Connexió establerta. La comunicació està a punt. Missatge enviat al servidor: Hello World Missatge rebut del client: Hello World Connections tancades. Servidor finalitzat.

En cas que la vostra producció no sigui com l'anterior, cosa que és improbable que passi, hi ha algunes solucions:

  • Si la sortida s’atura a la línia

    Connexió establerta.

    i s’utilitzen corrents d’objectes, netejant cadascun

    ObjectOutputStream

  • immediatament després de la inicialització perquè les capçaleres, per alguna raó, no s’han enviat.
  • Si s’imprimeix la sortida

    java.net. BindException: adreça ja en ús

  • trieu un número de port diferent perquè ja s’utilitza el número especificat.

Consells

  • La connexió a un servidor d'una xarxa diferent es realitza mitjançant la connexió a l'adreça IP externa d'un dispositiu que executa el servidor que té un port reenviat.
  • La connexió a un servidor de la mateixa xarxa es realitza mitjançant la connexió a l'adreça IP privada d'un dispositiu que executa el servidor o el reenviament d'un port i la connexió a l'adreça IP externa del dispositiu.
  • Hi ha programari, com Hamachi, que permet connectar-se al servidor en una xarxa diferent sense reenviar un port, però requereix la instal·lació del programari als dos dispositius.

Exemples

Les aplicacions de xarxa que utilitzen l'entrada / sortida de bloqueig han d'utilitzar fils. Els exemples següents mostren una implementació minimalista de servidor i client amb fils. El codi de xarxa és essencialment el mateix que a l'article, tret que alguns fragments es van sincronitzar, es van moure a fils i es gestionen les excepcions.

Server.java

importació java.io. IOException; importació java.net. InetAddress; importar java.net. ServerSocket; importació java.net. SocketException; importació java.net. UnknownHostException; importa java.util. ArrayList; importar java.util. Collections; importa java.util. List; / ** * La classe {@code Server} representa un punt final del servidor en una xarxa. {@code Server} un cop vinculat a una determinada adreça i port IP *, estableix connexions amb els clients i pot comunicar-se amb ells o desconnectar-los. *

* Aquesta classe és segura per a fils. * * @version 1.0 * @see Client * @see Connection * / public class El servidor implementa Runnable {private ServerSocket server; Llista privada connexions; fil privat del fil; private final Object connectionsLock = new Object (); / ** * Construeix un {@code Server} que interactua amb els clients al nom i al port d'amfitrió especificats amb la longitud màxima sol·licitada * especificada d'una cua de clients entrants. * * @param Adreça d'amfitrió de l'amfitrió per utilitzar. * Port @param Número de port a utilitzar. * @param backlog Sol·licitat la longitud màxima de la cua de clients entrants. * @throws NetworkException Si es produeix un error en iniciar un servidor. * / Servidor públic (amfitrió de cadenes, port int, backlog int) genera NetworkException {try {server = ServerSocket nou (port, backlog, InetAddress.getByName (host)); } catch (UnknownHostException e) {llançar una nova NetworkException ("No s'ha pogut resoldre el nom de l'amfitrió:" + amfitrió, e); } catch (IllegalArgumentException e) {throw New NetworkException ("El número de port ha d'estar entre 0 i 65535 (inclosos):" + port); } catch (IOException e) {throw new NetworkException ("El servidor no s'ha pogut iniciar.", e); } connections = Collections.synchronizedList (new ArrayList ()); fil = fil nou (això); thread.start (); } / ** * Construeix un {@code Server} que interactua amb els clients al nom i al port d'amfitrió especificats. * * @param Adreça de l'amfitrió de l'amfitrió per lligar. * Port @param Número de port per lligar. * @throws NetworkException Si es produeixen errors en iniciar un servidor. * / servidor públic (host de cadena, port int) genera NetworkException {això (host, port, 50); } / ** * Escolta, accepta i registra les connexions entrants dels clients. * / @Override public void run () {while (! Server.isClosed ()) {try {connections.add (nova connexió (server.accept ())); } catch (SocketException e) {if (! e.getMessage (). equals ("Socket closed")) {e.printStackTrace (); }} catch (NetworkException | IOException e) {e.printStackTrace (); }}} / ** * Envia dades a tots els clients registrats. * * Dades @param Dades per enviar. * @throws IllegalStateException Si s'intenta escriure dades quan el servidor està fora de línia. * @throws IllegalArgumentException Si les dades que cal enviar són nul·les. * / public void broadcast (dades de l'objecte) {if (server.isClosed ()) {llançar una nova excepció IllegalStateException ("Les dades no s'han enviat, el servidor està fora de línia."); } if (data == null) {llança una nova excepció IllegalArgumentException ("dades nul·les"); } sincronitzat (connectionsLock) {per a (Connection connection: connections) {try {connection.send (data); System.out.println ("Dades enviades al client amb èxit."); } catch (NetworkException e) {e.printStackTrace (); }}}} / ** * Envia un missatge de desconnexió i desconnecta el client especificat. * * Connexió @param Client per desconnectar. * @throws NetworkException Si es produeix un error en tancar la connexió. * / public void disconnect (connexió de connexió) genera NetworkException {if (connections.remove (connection)) {connection.close (); }} / ** * Envia un missatge de desconnexió a tots els clients, els desconnecta i finalitza el servidor. * / public void close () llança NetworkException {sincronitzada (connectionsLock) {per (Connection connection: connections) {try {connection.close (); } catch (NetworkException e) {e.printStackTrace (); }}} connections.clear (); proveu {server.close (); } catch (IOException e) {llançament de NetworkException nova ("Error en tancar el servidor."); } finalment {thread.interrupt (); }} / ** * Torna si el servidor està en línia o no. * * @return True si el servidor està en línia. Fals, en cas contrari. * / public boolean isOnline () {return! server.isClosed (); } / ** * Retorna una sèrie de clients registrats. * / public Connection getConnections () {synchronized (connectionsLock) {return connections.toArray (nova connexió [connections.size ()]); }}}

Client.java

importació java.io. IOException; importació de java.net. Socket; importació java.net. UnknownHostException; / ** * La classe {@code Client} representa un punt final del client en una xarxa. {@code Client}, un cop connectat a un servidor * determinat, es garanteix que només podrà comunicar-se amb el servidor. Que altres clients rebin les dades * o no depèn de la implementació del servidor. *

* Aquesta classe és segura per a fils. * * @version 1.0 * @see Server * @see Connection * / public class Client {private Connection connection; / ** * Construeix un {@code Client} connectat al servidor a l'amfitrió i al port especificats. * * @param Adreça de l'amfitrió de l'amfitrió per lligar. * Port @param Número de port per lligar. * @throws NetworkException Si es produeix un error en iniciar un servidor. * / Client públic (amfitrió de cadena, port int) llença NetworkException {try {connection = new Connection (socket nou (host, port)); } catch (UnknownHostException e) {llançar una nova NetworkException ("No s'ha pogut resoldre el nom de l'amfitrió:" + amfitrió, e); } catch (IllegalArgumentException e) {throw New NetworkException ("El número de port ha d'estar entre 0 i 65535 (inclosos):" + port); } catch (IOException e) {throw new NetworkException ("El servidor no s'ha pogut iniciar.", e); }} / ** * Envia dades a l'altra part. * * Dades @param Dades per enviar. * @throws NetworkException Si falla l'escriptura al flux de sortida. * @throws IllegalStateException Si s'intenta escriure dades quan es tanca la connexió. * @throws IllegalArgumentException Si les dades que cal enviar són nul·les. * @throws UnsupportedOperationException Si s'intenta enviar tipus de dades no compatibles. * / l'enviament de buits públics (dades d'objectes) genera NetworkException {connection.send (dades); } / ** * Envia un missatge de desconnexió al servidor i tanca la connexió amb ell. * / public void close () llança NetworkException {connection.close (); } / ** * Torna si el client està connectat o no al servidor. * * @return True si el client està connectat. Fals, en cas contrari. * / public boolean isOnline () {return connection.isConnected (); } / ** * Retorna la instància {@link Connection} del client. * / public Connection getConnection () {retorn de la connexió; }}

Connection.java

importació java.io. DataInputStream; importació java.io. DataOutputStream; importació java.io. IOException; importació de java.net. Socket; importació java.net. SocketException; / ** * La classe {@code Connection} representa una connexió del servidor al client o un punt final del client en una xarxa * {@code Connection}, un cop connectat, pot intercanviar dades amb altres parts, segons en una implementació de servidor *. *

* Aquesta classe és segura per a fils. * * @version 1.0 * @see Server * @see Client * / public class La implementació de la connexió és executable {socket socket privat; privat DataOutputStream out; DataInputStream privat a; fil privat del fil; private final Object writeLock = new Object (); private final Object readLock = new Object (); / ** * Construeix {@code Connection} mitjançant fluxos d'un {@link Socket} especificat. * * @param socket Socket per obtenir els fluxos.* / Connexió pública (socket socket) genera NetworkException {if (socket == null) {llança una nova excepció IllegalArgumentException ("socket nul"); } this.socket = sòcol; proveu {out = new DataOutputStream (socket.getOutputStream ()); } catch (IOException e) {throw new NetworkException ("No s'ha pogut accedir al flux de sortida", e); } try {in = new DataInputStream (socket.getInputStream ()); } catch (IOException e) {throw new NetworkException ("No s'ha pogut accedir al flux d'entrada.", e); } fil = fil nou (això); thread.start (); } / ** * Llegeix els missatges mentre la connexió amb l'altra part està activa. * / @Override public void run () {while (! Socket.isClosed ()) {try {int identificador; byte bytes; sincronitzat (readLock) {identificador = in.readInt (); int length = in.readInt (); if (longitud> 0) {bytes = byte nou [longitud]; in.readFully (bytes, 0, bytes.length); } else {continue; }} commutador (identificador) {cas Identificador. INTERN: ordre de cadena = cadena nova (bytes); if (command.equals ("disconnect")) {{((socket.isClosed ()) {System.out.println ("Paquet de desconnexió rebut."); provar {close (); } catch (NetworkException e) {return; } } } trencar; case Identifier. TEXT: System.out.println ("Missatge rebut:" + nova cadena (bytes)); trencar; per defecte: System.out.println ("Dades no reconegudes rebudes."); }} catch (SocketException e) {if (! e.getMessage (). equals ("Socket closed")) {e.printStackTrace (); }} catch (IOException e) {e.printStackTrace (); }}} / ** * Envia dades a l'altra part. * * Dades @param Dades per enviar. * @throws NetworkException Si falla l'escriptura al flux de sortida. * @throws IllegalStateException Si s'intenta escriure dades quan es tanca la connexió. * @throws IllegalArgumentException Si les dades que cal enviar són nul·les. * @throws UnsupportedOperationException Si s'intenta enviar tipus de dades no compatibles. * / public void send (dades de l'objecte) genera NetworkException {if (socket.isClosed ()) {throw new IllegalStateException ("Les dades no s'han enviat, la connexió està tancada."); } if (data == null) {llança una nova excepció IllegalArgumentException ("dades nul·les"); } identificador int; byte bytes; if (instància de dades de la cadena) {identificador = Identificador. TEXT; bytes = ((String) data).getBytes (); } else {throw new UnsupportedOperationException ("Tipus de dades no admès:" + data.getClass ()); } proveu {sincronitzat (writeLock) {out.writeInt (identificador); out.writeInt (bytes.length); out.write (bytes); out.flush (); }} catch (IOException e) {throw new NetworkException ("No s'han pogut enviar les dades", e); }} / ** * Envia un missatge de desconnexió a i tanca la connexió amb l'altra part. * / public void close () llança NetworkException {if (socket.isClosed ()) {llança una nova IllegalStateException ("La connexió ja està tancada."); } try {byte message = "disconnect".getBytes (); sincronitzat (writeLock) {out.writeInt (Identificador. INTERNAL); out.writeInt (message.length); out.write (missatge); out.flush (); }} catch (IOException e) {System.out.println ("No s'ha pogut enviar el missatge de desconnexió"); } proveu {synchronized (writeLock) {out.close (); }} catch (IOException e) {llançament de NetworkException nova ("Error en tancar la connexió", e); } finalment {thread.interrupt (); }} / ** * Torna si la connexió amb l'altra part és activa o no. * * @return True si la connexió és viva. Fals, en cas contrari. * / public boolean isConnected () {return! socket.isClosed (); }}

Identificador.java

/ ** * La classe {@code Identifier} conté constants que utilitza {@link Connection} per serialitzar i deserialitzar les dades * enviades per la xarxa. * * @version 1.0 * @vege Connection * / Public final class Identifier {/ ** * Identificador per als missatges interns. * / public static final int INTERN = 1; / ** * Identificador per als missatges textuals. * / public static final int TEXT = 2; }

NetworkException.java

/ ** * La classe {@code NetworkException} indica un error relacionat amb la xarxa. * / public class NetworkException extends Exception {/ ** * Construeix un {@code NetworkException} amb {@code null} com a missatge. * / public NetworkException () {} / ** * Construeix un {@code NetworkException} amb el missatge especificat. * * @param message Un missatge per descriure l'error. * / public NetworkException (missatge de cadena) {super (missatge); } / ** * Construeix un {@code NetworkException} amb el missatge i la causa especificats. * * @param message Un missatge per descriure l'error. * @param causa Una causa d'error. * / public NetworkException (missatge de cadena, causa llançable) {super (missatge, causa); } / ** * Construeix un {@code NetworkException} amb la causa especificada. * * @param causa Una causa d'error. * / public NetworkException (causa llançable) {super (causa); }}

UsageExample.java

/ ** * La classe {@code UsageExample} mostra l'ús de {@link Server} i {@link Client}. En aquests exemples s'utilitza * {@link Thread # sleep (long)} per assegurar-se que cada segment s'executa perquè l'inici i el tancament ràpids fan que alguns segments * no s'executin. * * @version 1.0 * @see Server * @see Client * / public class UsageExample {public static void main (String args) throws Exception {String host = "localhost"; int port = 10430; Servidor servidor = Servidor nou (host, port); Client client = client nou (amfitrió, port); Thread.sleep (100L); client.send ("Hola"); server.broadcast ("Ei, amic!"); Thread.sleep (100L); server.disconnect (server.getConnections () [0]); // o client.close () per desconnectar del servidor.close () del client; }}

Recomanat: