Cómo crear una aplicación de red en Java (con imágenes)

Tabla de contenido:

Cómo crear una aplicación de red en Java (con imágenes)
Cómo crear una aplicación de red en Java (con imágenes)

Video: Cómo crear una aplicación de red en Java (con imágenes)

Video: Cómo crear una aplicación de red en Java (con imágenes)
Video: Como hacer una captura de pantalla con gestos SIN USAR BOTONES 2024, Abril
Anonim

Escribir código que se ejecute en un dispositivo determinado es muy satisfactorio. Pero escribir código que se ejecuta en varios dispositivos que se comunican entre sí es simplemente una afirmación de la vida. Este artículo le enseñará cómo conectarse e intercambiar mensajes a través de la red utilizando el protocolo de control de transmisión (TCP).

En este artículo, configurará una aplicación que conectará su computadora consigo misma y, esencialmente, la volverá loca: hablar consigo misma. También aprenderá la diferencia entre los dos flujos más utilizados para redes en Java y cómo funcionan.

Flujos de datos y objetos

Antes de sumergirse en el código, es necesario distinguir la diferencia entre las dos corrientes utilizadas en el artículo.

Flujos de datos

Los flujos de datos procesan cadenas y tipos de datos primitivos. Los datos enviados a través de flujos de datos deben serializarse y deserializarse manualmente, lo que dificulta la transferencia de datos complejos. Pero los flujos de datos pueden comunicarse con servidores y clientes escritos en otros lenguajes además de Java. Los flujos sin procesar son similares a los flujos de datos en ese aspecto, pero los flujos de datos garantizan que los datos se formatee de una manera independiente de la plataforma, lo cual es beneficioso porque ambas partes podrán leer los datos enviados.

Flujos de objetos

Los flujos de objetos procesan tipos de datos primitivos y objetos que implementan

Serializable

interfaz. Los datos enviados a través de secuencias de objetos se serializan y deserializan automáticamente, lo que facilita la transferencia de datos complejos. Pero, los flujos de objetos solo pueden comunicarse con servidores y clientes escritos en Java. También,

ObjectOutputStream

tras la inicialización, envía un encabezado al

Flujo de entrada

de la otra parte que, tras la inicialización, bloquea la ejecución hasta que se recibe el encabezado.

Pasos

Crear una aplicación de red en Java Step1
Crear una aplicación de red en Java Step1

Paso 1. Crea una clase

Crea una clase y nómbrala como quieras. En este artículo, se llamará

NetworkAppExample

clase pública NetworkAppExample {}

Crear una aplicación de red en Java Step2
Crear una aplicación de red en Java Step2

Paso 2. Cree un método principal

Cree un método principal y declare que podría generar excepciones de

Excepción

type y cualquier subclase del mismo - todas las excepciones. Esto se considera una mala práctica, pero es aceptable para ejemplos básicos.

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

Crear una aplicación de red en Java Step3
Crear una aplicación de red en Java Step3

Paso 3. Declare la dirección del servidor

Este ejemplo utilizará la dirección de host local y un número de puerto arbitrario. El número de puerto debe estar en un rango de 0 a 65535 (inclusive). Sin embargo, los números de puerto que se deben evitar van de 0 a 1023 (inclusive) porque son puertos del sistema reservados.

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

Crear una aplicación de red en Java Step4
Crear una aplicación de red en Java Step4

Paso 4. Cree un servidor

El servidor está vinculado a la dirección y al puerto y escucha las conexiones entrantes. En Java,

ServerSocket

representa el punto final del lado del servidor y su función es aceptar nuevas conexiones.

ServerSocket

no tiene flujos para leer y enviar datos porque no representa una conexión entre un servidor y un cliente.

import java.net. InetAddress; import java.net. ServerSocket; public class NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; int puerto = 10430; ServerSocket servidor = nuevo ServerSocket (puerto, 50, InetAddress.getByName (host)); }}

Cree una aplicación de red en Java Step5
Cree una aplicación de red en Java Step5

Paso 5. Iniciar sesión en el servidor

Para fines de registro, imprima en la consola que el servidor se ha iniciado.

import java.net. InetAddress; import java.net. ServerSocket; public class NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; int puerto = 10430; ServerSocket servidor = nuevo ServerSocket (puerto, 50, InetAddress.getByName (host)); System.out.println ("Servidor iniciado"); }}

Cree una aplicación de red en Java Step6
Cree una aplicación de red en Java Step6

Paso 6. Cree un cliente

El cliente está vinculado a la dirección y al puerto de un servidor y escucha los paquetes (mensajes) después de que se establece la conexión. En Java,

Enchufe

representa un punto final del lado del cliente conectado al servidor o una conexión (desde el servidor) al cliente y se utiliza para comunicarse con la parte en el otro extremo.

import java.net. InetAddress; import java.net. ServerSocket; import java.net. Socket; public class NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; int puerto = 10430; ServerSocket servidor = nuevo ServerSocket (puerto, 50, InetAddress.getByName (host)); System.out.println ("Servidor iniciado"); Cliente de socket = nuevo Socket (host, puerto); }}

Cree una aplicación de red en Java Step7
Cree una aplicación de red en Java Step7

Paso 7. Registre el intento de conexión

Para fines de registro, imprima en la consola que se ha intentado la conexión.

import java.net. InetAddress; import java.net. ServerSocket; import java.net. Socket; public class NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; int puerto = 10430; ServerSocket servidor = nuevo ServerSocket (puerto, 50, InetAddress.getByName (host)); System.out.println ("Servidor iniciado"); Cliente de socket = nuevo Socket (host, puerto); System.out.println ("Conectando al servidor …"); }}

Cree una aplicación de red en Java Step8
Cree una aplicación de red en Java Step8

Paso 8. Establezca la conexión

Los clientes nunca se conectarán a menos que el servidor escuche y acepte, en otras palabras, establezca conexiones. En Java, las conexiones se establecen utilizando

aceptar()

método de

ServerSocket

clase. El método bloqueará la ejecución hasta que un cliente se conecte.

import java.net. InetAddress; import java.net. ServerSocket; import java.net. Socket; public class NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; int puerto = 10430; ServerSocket servidor = nuevo ServerSocket (puerto, 50, InetAddress.getByName (host)); System.out.println ("Servidor iniciado"); Cliente de socket = nuevo Socket (host, puerto); System.out.println ("Conectando al servidor …"); Conexión de socket = server.accept (); }}

Cree una aplicación de red en Java Step9
Cree una aplicación de red en Java Step9

Paso 9. Registre la conexión establecida

Para fines de registro, imprima en la consola que se ha establecido la conexión entre el servidor y el cliente.

import java.net. InetAddress; import java.net. ServerSocket; import java.net. Socket; public class NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; int puerto = 10430; ServerSocket servidor = nuevo ServerSocket (puerto, 50, InetAddress.getByName (host)); System.out.println ("Servidor iniciado"); Cliente de socket = nuevo Socket (host, puerto); System.out.println ("Conectando al servidor …"); Conexión de socket = server.accept (); System.out.println ("Conexión establecida"); }}

Cree una aplicación de red en Java Step10
Cree una aplicación de red en Java Step10

Paso 10. Prepare los flujos de comunicación

La comunicación se realiza a través de flujos y, en esta aplicación, los flujos sin procesar del (conexión desde) el servidor (al cliente) y el cliente deben estar encadenados a flujos de datos o de objetos. Recuerde, ambas partes deben utilizar el mismo tipo de transmisión.

  • Flujos de datos

    import java.io. DataInputStream; import java.io. DataOutputStream; import java.net. InetAddress; import java.net. ServerSocket; import java.net. Socket; public class NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; int puerto = 10430; ServerSocket servidor = nuevo ServerSocket (puerto, 50, InetAddress.getByName (host)); System.out.println ("Servidor iniciado"); Cliente de socket = nuevo Socket (host, puerto); System.out.println ("Conectando al servidor …"); Conexión de socket = server.accept (); System.out.println ("Conexión establecida"); DataOutputStream clientOut = nuevo DataOutputStream (client.getOutputStream ()); DataInputStream clientIn = nuevo DataInputStream (client.getInputStream ()); DataOutputStream serverOut = nuevo DataOutputStream (connection.getOutputStream ()); DataInputStream serverIn = nuevo DataInputStream (connection.getInputStream ()); }}

  • Flujos de objetos

    Cuando se utilizan múltiples flujos de objetos, los flujos de entrada deben inicializarse en el mismo orden que los flujos de salida porque

    ObjectOutputStream

    envía un encabezado a la otra parte y

    ObjectInputStream

    bloquea la ejecución hasta que lee el encabezado.

    import java.io. ObjectInputStream; import java.io. ObjectOutputStream; import java.net. InetAddress; import java.net. ServerSocket; import java.net. Socket; public class NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; int puerto = 10430; ServerSocket servidor = nuevo ServerSocket (puerto, 50, InetAddress.getByName (host)); System.out.println ("Servidor iniciado"); Cliente de socket = nuevo Socket (host, puerto); System.out.println ("Conectando al servidor …"); Conexión de socket = server.accept (); System.out.println ("Conexión establecida"); ObjectOutputStream clientOut = nuevo ObjectOutputStream (client.getOutputStream ()); ObjectOutputStream serverOut = nuevo ObjectOutputStream (connection.getOutputStream ()); ObjectInputStream clientIn = nuevo ObjectInputStream (client.getInputStream ()); ObjectInputStream serverIn = nuevo ObjectInputStream (conexión.getInputStream ()); }}

    El orden como se especifica en el código anterior puede ser más fácil de recordar: primero inicialice los flujos de salida y luego los flujos de entrada en el mismo orden. Sin embargo, otro orden para la inicialización de flujos de objetos es el siguiente:

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

Cree una aplicación de red en Java Step11
Cree una aplicación de red en Java Step11

Paso 11. Registre que la comunicación está lista

Para fines de registro, imprima en la consola que la comunicación está lista.

// código omitido import java.net. InetAddress; import java.net. ServerSocket; import java.net. Socket; public class NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; int puerto = 10430; ServerSocket servidor = nuevo ServerSocket (puerto, 50, InetAddress.getByName (host)); System.out.println ("Servidor iniciado"); Cliente de socket = nuevo Socket (host, puerto); System.out.println ("Conectando al servidor …"); Conexión de socket = server.accept (); System.out.println ("Conexión establecida"); // código omitido System.out.println ("La comunicación está lista"); }}

Cree una aplicación de red en Java Step12
Cree una aplicación de red en Java Step12

Paso 12. Crea un mensaje

En esta aplicación,

Hola Mundo

El texto se enviará al servidor como

byte

o

Cuerda

. Declare una variable del tipo que depende del flujo utilizado. Usar

byte

para flujos de datos y

Cuerda

para flujos de objetos.

  • Flujos de datos

    Utilizando flujos de datos, la serialización se realiza convirtiendo objetos en tipos de datos primitivos o un

    Cuerda

    . En este caso,

    Cuerda

    se convierte en

    byte

    en lugar de escribir usando

    writeBytes ()

    método para mostrar cómo se haría con otros objetos, como imágenes u otros archivos.

    import java.io. DataInputStream; import java.io. DataOutputStream; import java.net. InetAddress; import java.net. ServerSocket; import java.net. Socket; public class NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; int puerto = 10430; ServerSocket servidor = nuevo ServerSocket (puerto, 50, InetAddress.getByName (host)); System.out.println ("Servidor iniciado"); Cliente de socket = nuevo Socket (host, puerto); System.out.println ("Conectando al servidor …"); Conexión de socket = server.accept (); System.out.println ("Conexión establecida"); DataOutputStream clientOut = nuevo DataOutputStream (client.getOutputStream ()); DataInputStream clientIn = nuevo DataInputStream (client.getInputStream ()); DataOutputStream serverOut = nuevo DataOutputStream (connection.getOutputStream ()); DataInputStream serverIn = nuevo DataInputStream (connection.getInputStream ()); System.out.println ("La comunicación está lista"); byte messageOut = "Hola mundo".getBytes (); }}

  • Flujos de objetos

    import java.io. ObjectInputStream; import java.io. ObjectOutputStream; import java.net. InetAddress; import java.net. ServerSocket; import java.net. Socket; public class NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; int puerto = 10430; ServerSocket servidor = nuevo ServerSocket (puerto, 50, InetAddress.getByName (host)); System.out.println ("Servidor iniciado"); Cliente de socket = nuevo Socket (host, puerto); System.out.println ("Conectando al servidor …"); Conexión de socket = server.accept (); System.out.println ("Conexión establecida"); ObjectOutputStream clientOut = nuevo ObjectOutputStream (client.getOutputStream ()); ObjectOutputStream serverOut = nuevo ObjectOutputStream (connection.getOutputStream ()); ObjectInputStream clientIn = nuevo ObjectInputStream (client.getInputStream ()); ObjectInputStream serverIn = nuevo ObjectInputStream (conexión.getInputStream ()); System.out.println ("La comunicación está lista"); String messageOut = "Hola mundo"; }}

Cree una aplicación de red en Java Step13
Cree una aplicación de red en Java Step13

Paso 13. Envíe el mensaje

Escriba datos en el flujo de salida y elimine el flujo para asegurarse de que los datos se hayan escrito por completo.

  • Flujos de datos

    La longitud de un mensaje debe enviarse primero para que la otra parte sepa cuántos bytes necesita leer. Una vez que la longitud se envía como un tipo de entero primitivo, se pueden enviar bytes.

    import java.io. DataInputStream; import java.io. DataOutputStream; import java.net. InetAddress; import java.net. ServerSocket; import java.net. Socket; public class NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; int puerto = 10430; ServerSocket servidor = nuevo ServerSocket (puerto, 50, InetAddress.getByName (host)); System.out.println ("Servidor iniciado"); Cliente de socket = nuevo Socket (host, puerto); System.out.println ("Conectando al servidor …"); Conexión de socket = server.accept (); System.out.println ("Conexión establecida"); DataOutputStream clientOut = nuevo DataOutputStream (client.getOutputStream ()); DataInputStream clientIn = nuevo DataInputStream (client.getInputStream ()); DataOutputStream serverOut = nuevo DataOutputStream (connection.getOutputStream ()); DataInputStream serverIn = nuevo DataInputStream (connection.getInputStream ()); System.out.println ("La comunicación está lista"); byte messageOut = "Hola mundo".getBytes (); clientOut.writeInt (messageOut.length); clientOut.write (messageOut); clientOut.flush (); }}

  • Flujos de objetos

    import java.io. ObjectInputStream; import java.io. ObjectOutputStream; import java.net. InetAddress; import java.net. ServerSocket; import java.net. Socket; public class NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; int puerto = 10430; ServerSocket servidor = nuevo ServerSocket (puerto, 50, InetAddress.getByName (host)); System.out.println ("Servidor iniciado"); Cliente de socket = nuevo Socket (host, puerto); System.out.println ("Conectando al servidor …"); Conexión de socket = server.accept (); System.out.println ("Conexión establecida"); ObjectOutputStream clientOut = nuevo ObjectOutputStream (client.getOutputStream ()); ObjectOutputStream serverOut = nuevo ObjectOutputStream (connection.getOutputStream ()); ObjectInputStream clientIn = nuevo ObjectInputStream (client.getInputStream ()); ObjectInputStream serverIn = nuevo ObjectInputStream (connection.getInputStream ()); System.out.println ("La comunicación está lista"); String messageOut = "Hola mundo"; clientOut.writeObject (messageOut); clientOut.flush (); }}

Cree una aplicación de red en Java Step14
Cree una aplicación de red en Java Step14

Paso 14. Registre el mensaje enviado

Para fines de registro, imprima en la consola el mensaje que se envió.

  • Flujos de datos

    import java.io. DataInputStream; import java.io. DataOutputStream; import java.net. InetAddress; import java.net. ServerSocket; import java.net. Socket; public class NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; int puerto = 10430; ServerSocket servidor = nuevo ServerSocket (puerto, 50, InetAddress.getByName (host)); System.out.println ("Servidor iniciado"); Cliente de socket = nuevo Socket (host, puerto); System.out.println ("Conectando al servidor …"); Conexión de socket = server.accept (); System.out.println ("Conexión establecida"); DataOutputStream clientOut = nuevo DataOutputStream (client.getOutputStream ()); DataInputStream clientIn = nuevo DataInputStream (client.getInputStream ()); DataOutputStream serverOut = nuevo DataOutputStream (connection.getOutputStream ()); DataInputStream serverIn = nuevo DataInputStream (connection.getInputStream ()); System.out.println ("La comunicación está lista"); byte messageOut = "Hola mundo".getBytes (); clientOut.writeInt (messageOut.length); clientOut.write (messageOut); clientOut.flush (); System.out.println ("Mensaje enviado al servidor:" + nueva Cadena (messageOut)); }}

  • Flujos de objetos

    import java.io. ObjectInputStream; import java.io. ObjectOutputStream; import java.net. InetAddress; import java.net. ServerSocket; import java.net. Socket; public class NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; int puerto = 10430; ServerSocket servidor = nuevo ServerSocket (puerto, 50, InetAddress.getByName (host)); System.out.println ("Servidor iniciado"); Cliente de socket = nuevo Socket (host, puerto); System.out.println ("Conectando al servidor …"); Conexión de socket = server.accept (); System.out.println ("Conexión establecida"); ObjectOutputStream clientOut = nuevo ObjectOutputStream (client.getOutputStream ()); ObjectOutputStream serverOut = nuevo ObjectOutputStream (connection.getOutputStream ()); ObjectInputStream clientIn = nuevo ObjectInputStream (client.getInputStream ()); ObjectInputStream serverIn = nuevo ObjectInputStream (conexión.getInputStream ()); System.out.println ("La comunicación está lista"); String messageOut = "Hola mundo"; clientOut.writeObject (messageOut); clientOut.flush (); System.out.println ("Mensaje enviado al servidor:" + messageOut); }}

Cree una aplicación de red en Java Step15
Cree una aplicación de red en Java Step15

Paso 15. Lea el mensaje

Lea los datos del flujo de entrada y conviértalos. Como sabemos exactamente el tipo de datos enviados, crearemos un

Cuerda

de

byte

o emitir

Objeto

para

Cuerda

sin comprobar, dependiendo de la secuencia utilizada.

  • Flujos de datos

    Como la longitud se envió primero y los bytes después, la lectura debe realizarse en el mismo orden. En caso de que la longitud sea cero, no hay nada que leer. El objeto se deserializa cuando los bytes se vuelven a convertir en una instancia, en este caso, de

    Cuerda

    import java.io. DataInputStream; import java.io. DataOutputStream; import java.net. InetAddress; import java.net. ServerSocket; import java.net. Socket; public class NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; int puerto = 10430; ServerSocket servidor = nuevo ServerSocket (puerto, 50, InetAddress.getByName (host)); System.out.println ("Servidor iniciado"); Cliente de socket = nuevo Socket (host, puerto); System.out.println ("Conectando al servidor …"); Conexión de socket = server.accept (); System.out.println ("Conexión establecida"); DataOutputStream clientOut = nuevo DataOutputStream (client.getOutputStream ()); DataInputStream clientIn = nuevo DataInputStream (client.getInputStream ()); DataOutputStream serverOut = nuevo DataOutputStream (connection.getOutputStream ()); DataInputStream serverIn = nuevo DataInputStream (connection.getInputStream ()); System.out.println ("La comunicación está lista"); byte messageOut = "Hola mundo".getBytes (); clientOut.writeInt (messageOut.length); clientOut.write (messageOut); clientOut.flush (); System.out.println ("Mensaje enviado al servidor:" + nueva Cadena (messageOut)); int longitud = serverIn.readInt (); if (longitud> 0) {byte mensajeIn = nuevo byte [longitud]; serverIn.readFully (messageIn, 0, messageIn.length); }}}

  • Flujos de objetos

    import java.io. ObjectInputStream; import java.io. ObjectOutputStream; import java.net. InetAddress; import java.net. ServerSocket; import java.net. Socket; public class NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; int puerto = 10430; ServerSocket servidor = nuevo ServerSocket (puerto, 50, InetAddress.getByName (host)); System.out.println ("Servidor iniciado"); Cliente de socket = nuevo Socket (host, puerto); System.out.println ("Conectando al servidor …"); Conexión de socket = server.accept (); System.out.println ("Conexión establecida"); ObjectOutputStream clientOut = nuevo ObjectOutputStream (client.getOutputStream ()); ObjectOutputStream serverOut = nuevo ObjectOutputStream (connection.getOutputStream ()); ObjectInputStream clientIn = nuevo ObjectInputStream (client.getInputStream ()); ObjectInputStream serverIn = nuevo ObjectInputStream (conexión.getInputStream ()); System.out.println ("La comunicación está lista"); String messageOut = "Hola mundo"; clientOut.writeObject (messageOut); clientOut.flush (); System.out.println ("Mensaje enviado al servidor:" + messageOut); String messageIn = (String) serverIn.readObject (); }}

Cree una aplicación de red en Java Step16
Cree una aplicación de red en Java Step16

Paso 16. Registrar mensaje leído

Para fines de registro, imprima en la consola el mensaje que se recibió e imprima su contenido.

  • Flujos de datos

    import java.io. DataInputStream; import java.io. DataOutputStream; import java.net. InetAddress; import java.net. ServerSocket; import java.net. Socket; public class NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; int puerto = 10430; ServerSocket servidor = nuevo ServerSocket (puerto, 50, InetAddress.getByName (host)); System.out.println ("Servidor iniciado"); Cliente de socket = nuevo Socket (host, puerto); System.out.println ("Conectando al servidor …"); Conexión de socket = server.accept (); System.out.println ("Conexión establecida"); DataOutputStream clientOut = nuevo DataOutputStream (client.getOutputStream ()); DataInputStream clientIn = nuevo DataInputStream (client.getInputStream ()); DataOutputStream serverOut = nuevo DataOutputStream (connection.getOutputStream ()); DataInputStream serverIn = nuevo DataInputStream (connection.getInputStream ()); System.out.println ("La comunicación está lista"); byte messageOut = "Hola mundo".getBytes (); clientOut.writeInt (messageOut.length); clientOut.write (messageOut); clientOut.flush (); System.out.println ("Mensaje enviado al servidor:" + nueva Cadena (messageOut)); int longitud = serverIn.readInt (); if (longitud> 0) {byte mensajeIn = nuevo byte [longitud]; serverIn.readFully (messageIn, 0, messageIn.length); System.out.println ("Mensaje recibido del cliente:" + nueva Cadena (messageIn)); }}}

  • Flujos de objetos

    import java.io. ObjectInputStream; import java.io. ObjectOutputStream; import java.net. InetAddress; import java.net. ServerSocket; import java.net. Socket; public class NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; int puerto = 10430; ServerSocket servidor = nuevo ServerSocket (puerto, 50, InetAddress.getByName (host)); System.out.println ("Servidor iniciado"); Cliente de socket = nuevo Socket (host, puerto); System.out.println ("Conectando al servidor …"); Conexión de socket = server.accept (); System.out.println ("Conexión establecida"); ObjectOutputStream clientOut = nuevo ObjectOutputStream (client.getOutputStream ()); ObjectOutputStream serverOut = nuevo ObjectOutputStream (connection.getOutputStream ()); ObjectInputStream clientIn = nuevo ObjectInputStream (client.getInputStream ()); ObjectInputStream serverIn = nuevo ObjectInputStream (conexión.getInputStream ()); System.out.println ("La comunicación está lista"); String messageOut = "Hola mundo"; clientOut.writeObject (messageOut); clientOut.flush (); System.out.println ("Mensaje enviado al servidor:" + messageOut); String messageIn = (String) serverIn.readObject (); System.out.println ("Mensaje recibido del cliente:" + messageIn); }}

Cree una aplicación de red en Java Step17
Cree una aplicación de red en Java Step17

Paso 17. Desconecte las conexiones

La conexión se desconecta cuando una de las partes cierra sus transmisiones. En Java, al cerrar el flujo de salida, el conector asociado y el flujo de entrada también se cierran. Una vez que una parte del otro extremo descubre que la conexión está muerta, también debe cerrar su flujo de salida para evitar pérdidas de memoria.

// código omitido import java.net. InetAddress; import java.net. ServerSocket; import java.net. Socket; public class NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; int puerto = 10430; ServerSocket servidor = nuevo ServerSocket (puerto, 50, InetAddress.getByName (host)); System.out.println ("Servidor iniciado"); Cliente de socket = nuevo Socket (host, puerto); System.out.println ("Conectando al servidor …"); Conexión de socket = server.accept (); System.out.println ("Conexión establecida"); // código omitido System.out.println ("La comunicación está lista"); // código omitido clientOut.close (); serverOut.close (); }}

Cree una aplicación de red en Java Step18 V2
Cree una aplicación de red en Java Step18 V2

Paso 18. Desconexión del registro

Para fines de registro, se han desconectado las conexiones de impresión a la consola.

// código omitido import java.net. InetAddress; import java.net. ServerSocket; import java.net. Socket; public class NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; int puerto = 10430; ServerSocket servidor = nuevo ServerSocket (puerto, 50, InetAddress.getByName (host)); System.out.println ("Servidor iniciado"); Cliente de socket = nuevo Socket (host, puerto); System.out.println ("Conectando al servidor …"); Conexión de socket = server.accept (); System.out.println ("Conexión establecida"); // código omitido System.out.println ("La comunicación está lista"); // código omitido clientOut.close (); serverOut.close (); System.out.println ("Conexiones cerradas"); }}

Cree una aplicación de red en Java Step19
Cree una aplicación de red en Java Step19

Paso 19. Termine el servidor

Las conexiones están desconectadas, pero el servidor aún está funcionando. Como

ServerSocket

no está asociado con ninguna secuencia, debe cerrarse explícitamente llamando

cerrar()

método.

// código omitido import java.net. InetAddress; import java.net. ServerSocket; import java.net. Socket; public class NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; int puerto = 10430; ServerSocket servidor = nuevo ServerSocket (puerto, 50, InetAddress.getByName (host)); System.out.println ("Servidor iniciado"); Cliente de socket = nuevo Socket (host, puerto); System.out.println ("Conectando al servidor …"); Conexión de socket = server.accept (); System.out.println ("Conexión establecida"); // código omitido System.out.println ("La comunicación está lista"); // código omitido clientOut.close (); serverOut.close (); System.out.println ("Conexiones cerradas"); server.close (); }}

Cree una aplicación de red en Java Step20
Cree una aplicación de red en Java Step20

Paso 20. Terminación del servidor de registros

Para fines de registro, la impresión en el servidor de la consola ha finalizado.

// código omitido import java.net. InetAddress; import java.net. ServerSocket; import java.net. Socket; public class NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; int puerto = 10430; ServerSocket servidor = nuevo ServerSocket (puerto, 50, InetAddress.getByName (host)); System.out.println ("Servidor iniciado"); Cliente de socket = nuevo Socket (host, puerto); System.out.println ("Conectando al servidor …"); Conexión de socket = server.accept (); System.out.println ("Conexión establecida"); // código omitido System.out.println ("La comunicación está lista"); // código omitido clientOut.close (); serverOut.close (); System.out.println ("Conexiones cerradas"); server.close (); System.out.println ("Servidor terminado"); }}

Cree una aplicación de red en Java Step21
Cree una aplicación de red en Java Step21

Paso 21. Compile y ejecute

El registro nos permitió saber si la aplicación fue exitosa o no. Rendimiento esperado:

Se inició el servidor. Conectando al servidor… Conexión establecida. La comunicación está lista. Mensaje enviado al servidor: Hello World Mensaje recibido del cliente: Hello World Connections cerradas. Servidor terminado.

En caso de que su salida no sea como la anterior, lo que es poco probable que suceda, existen algunas soluciones:

  • Si la salida se detiene en la línea

    Conexión establecida.

    y se utilizan flujos de objetos, vaciar cada

    ObjectOutputStream

  • inmediatamente después de la inicialización porque los encabezados, por alguna razón, no se enviaron.
  • Si la salida se imprime

    java.net. BindException: dirección ya en uso

  • elija un número de puerto diferente porque el especificado ya está en uso.

Consejos

  • La conexión a un servidor en una red diferente se realiza mediante la conexión a la dirección IP externa de un dispositivo que ejecuta el servidor que tiene un puerto reenviado.
  • La conexión a un servidor en la misma red se realiza conectándose a la dirección IP privada de un dispositivo que ejecuta el servidor o reenviando un puerto y conectándose a la dirección IP externa del dispositivo.
  • Existen software, como Hamachi, que permiten conectarse al servidor en una red diferente sin reenviar un puerto, pero requiere la instalación del software en ambos dispositivos.

Ejemplos de

Las aplicaciones de red que utilizan el bloqueo de entrada / salida deben utilizar subprocesos. Los siguientes ejemplos muestran una implementación minimalista de servidor y cliente con subprocesos. El código de red es esencialmente el mismo que en el artículo, excepto que algunos fragmentos se sincronizaron, se movieron a subprocesos y se manejan las excepciones.

Server.java

import java.io. IOException; import java.net. InetAddress; import java.net. ServerSocket; import java.net. SocketException; import java.net. UnknownHostException; import java.util. ArrayList; import java.util. Collections; import java.util. List; / ** * La clase {@code Server} representa un punto final de servidor en una red. {@code Server}, una vez vinculado a una determinada dirección IP * y puerto, establece conexiones con los clientes y puede comunicarse con ellos o desconectarlos. *

* Esta clase es segura para subprocesos. * * @version 1.0 * @see Client * @see Connection * / public class Server implementa Runnable {servidor ServerSocket privado; lista privada conexiones; hilo de hilo privado; Objeto final privado connectionsLock = new Object (); / ** * Construye un {@code Server} que interactúa con los clientes en el puerto y el nombre de host especificados con la longitud máxima especificada * solicitada de una cola de clientes entrantes. * * @param host Dirección de host a utilizar. * @param port Número de puerto a utilizar. * @param backlog Longitud máxima solicitada de la cola de clientes entrantes. * @throws NetworkException Si se produce un error al iniciar un servidor. * / public Server (String host, int port, int backlog) lanza NetworkException {try {server = new ServerSocket (puerto, backlog, InetAddress.getByName (host)); } catch (UnknownHostException e) {throw new NetworkException ("No se pudo resolver el nombre del host:" + host, e); } catch (IllegalArgumentException e) {throw new NetworkException ("El número de puerto debe estar entre 0 y 65535 (inclusive):" + puerto); } catch (IOException e) {lanzar nueva NetworkException ("No se pudo iniciar el servidor", e); } conexiones = Collections.synchronizedList (new ArrayList ()); hilo = nuevo hilo (esto); thread.start (); } / ** * Construye un {@code Server} que interactúa con los clientes en el puerto y el nombre de host especificados. * * @param host Dirección de host para enlazar. * @param port Número de puerto para enlazar. * @throws NetworkException Si se producen errores al iniciar un servidor. * / public Server (String host, int port) lanza NetworkException {this (host, puerto, 50); } / ** * Escucha, acepta y registra las conexiones entrantes de los clientes. * / @Override public void run () {while (! Server.isClosed ()) {try {connections.add (new Connection (server.accept ())); } catch (SocketException e) {if (! e.getMessage (). equals ("Socket cerrado")) {e.printStackTrace (); }} catch (NetworkException | IOException e) {e.printStackTrace (); }}} / ** * Envía datos a todos los clientes registrados. * * @param data Datos a enviar. * @throws IllegalStateException Si se intenta escribir datos cuando el servidor está fuera de línea. * @throws IllegalArgumentException Si los datos a enviar son nulos. * / public void broadcast (datos del objeto) {if (server.isClosed ()) {throw new IllegalStateException ("Datos no enviados, el servidor está desconectado"); } if (data == null) {lanzar nueva IllegalArgumentException ("datos nulos"); } sincronizado (connectionsLock) {para (Conexión conexión: conexiones) {prueba {conexión.enviar (datos); System.out.println ("Datos enviados al cliente correctamente"); } captura (NetworkException e) {e.printStackTrace (); }}}} / ** * Envía un mensaje de desconexión y desconecta al cliente especificado. * * @param connection Cliente para desconectar. * @throws NetworkException Si se produce un error al cerrar la conexión. * / public void desconectar (Conexión de conexión) lanza NetworkException {if (connections.remove (connection)) {connection.close (); }} / ** * Envía un mensaje de desconexión a todos los clientes, los desconecta y finaliza el servidor. * / public void close () lanza NetworkException {sincronizado (connectionsLock) {para (Conexión conexión: conexiones) {prueba {conexión.close (); } captura (NetworkException e) {e.printStackTrace (); }}} connections.clear (); intente {servidor.close (); } catch (IOException e) {lanzar una nueva NetworkException ("Error al cerrar el servidor"); } finalmente {thread.interrupt (); }} / ** * Devuelve si el servidor está en línea o no. * * @return True si el servidor está en línea. Falso, de lo contrario. * / public boolean isOnline () {return! server.isClosed (); } / ** * Devuelve una matriz de clientes registrados. * / conexión pública getConnections () {sincronizado (connectionsLock) {return connections.toArray (nueva conexión [connections.size ()]); }}}

Client.java

import java.io. IOException; import java.net. Socket; import java.net. UnknownHostException; / ** * La clase {@code Client} representa un punto final de cliente en una red. Se garantiza que {@code Client}, una vez conectado a un determinado * servidor, solo podrá comunicarse con el servidor. Si otros clientes reciben o no los datos * depende de la implementación del servidor. *

* Esta clase es segura para subprocesos. * * @version 1.0 * @see Server * @see Connection * / public class Client {conexión de conexión privada; / ** * Construye un {@code Client} conectado al servidor en el host y puerto especificados. * * @param host Dirección de host para enlazar. * @param port Número de puerto para enlazar. * @throws NetworkException Si se produce un error al iniciar un servidor. * / public Client (String host, int port) lanza NetworkException {try {connection = new Connection (new Socket (host, port)); } catch (UnknownHostException e) {throw new NetworkException ("No se pudo resolver el nombre del host:" + host, e); } catch (IllegalArgumentException e) {throw new NetworkException ("El número de puerto debe estar entre 0 y 65535 (inclusive):" + puerto); } catch (IOException e) {lanzar una nueva NetworkException ("No se pudo iniciar el servidor", e); }} / ** * Envía datos a la otra parte. * * @param data Datos a enviar. * @throws NetworkException Si falla la escritura en el flujo de salida. * @throws IllegalStateException Si se intenta escribir datos cuando se cierra la conexión. * @throws IllegalArgumentException Si los datos a enviar son nulos. * @throws UnsupportedOperationException Si se intenta enviar un tipo de datos no admitido. * / public void send (datos del objeto) lanza NetworkException {connection.send (datos); } / ** * Envía un mensaje de desconexión y cierra la conexión con el servidor. * / public void close () lanza NetworkException {connection.close (); } / ** * Devuelve si el cliente está conectado al servidor o no. * * @return True si el cliente está conectado. Falso, de lo contrario. * / public boolean isOnline () {return connection.isConnected (); } / ** * Devuelve la instancia de {@link Connection} del cliente. * / public Connection getConnection () {conexión de retorno; }}

Connection.java

import java.io. DataInputStream; import java.io. DataOutputStream; import java.io. IOException; import java.net. Socket; import java.net. SocketException; / ** * La clase {@code Connection} representa una conexión del servidor al cliente o un punto final del cliente en una red * {@code Connection}, una vez conectado, puede intercambiar datos con otras partes, según en una implementación de servidor *. *

* Esta clase es segura para subprocesos. * * @version 1.0 * @see Server * @see Client * / clase pública Connection implementa Runnable {private Socket socket; salida de DataOutputStream privada; Private DataInputStream en; hilo de hilo privado; Objeto final privado writeLock = new Object (); Objeto final privado readLock = new Object (); / ** * Construye {@code Connection} usando transmisiones de un {@link Socket} especificado. * * @param socket Socket del que se obtienen las transmisiones.* / public Connection (Socket socket) lanza NetworkException {if (socket == null) {throw new IllegalArgumentException ("socket nulo"); } this.socket = socket; probar {fuera = nuevo DataOutputStream (socket.getOutputStream ()); } catch (IOException e) {lanzar nueva NetworkException ("No se pudo acceder al flujo de salida.", e); } try {in = new DataInputStream (socket.getInputStream ()); } catch (IOException e) {lanzar nueva NetworkException ("No se pudo acceder al flujo de entrada.", e); } hilo = nuevo hilo (esto); thread.start (); } / ** * Lee mensajes mientras la conexión con la otra parte está activa. * / @Override public void run () {while (! Socket.isClosed ()) {try {int identifier; byte bytes; sincronizado (readLock) {identificador = in.readInt (); int length = in.readInt (); if (longitud> 0) {bytes = nuevo byte [longitud]; in.readFully (bytes, 0, bytes.length); } else {continuar; }} interruptor (identificador) {identificador de caso. INTERNA: comando de cadena = nueva cadena (bytes); if (command.equals ("desconectar")) {if (! socket.isClosed ()) {System.out.println ("Paquete de desconexión recibido."); intente {cerrar (); } captura (NetworkException e) {return; } } } rotura; case Identifier. TEXT: System.out.println ("Mensaje recibido:" + nueva cadena (bytes)); rotura; predeterminado: System.out.println ("Se recibieron datos no reconocidos"); }} catch (SocketException e) {if (! e.getMessage (). equals ("Socket cerrado")) {e.printStackTrace (); }} catch (IOException e) {e.printStackTrace (); }}} / ** * Envía datos a la otra parte. * * @param data Datos a enviar. * @throws NetworkException Si falla la escritura en el flujo de salida. * @throws IllegalStateException Si se intenta escribir datos cuando se cierra la conexión. * @throws IllegalArgumentException Si los datos a enviar son nulos. * @throws UnsupportedOperationException Si se intenta enviar un tipo de datos no admitido. * / public void send (datos de objeto) lanza NetworkException {if (socket.isClosed ()) {lanza nueva IllegalStateException ("Datos no enviados, conexión cerrada."); } if (data == null) {lanzar nueva IllegalArgumentException ("datos nulos"); } int identifier; byte bytes; if (instancia de datos de String) {identifier = Identifier. TEXT; bytes = ((Cadena) datos).getBytes (); } else {lanzar nueva UnsupportedOperationException ("Tipo de datos no admitido:" + data.getClass ()); } probar {sincronizado (bloqueo de escritura) {out.writeInt (identificador); out.writeInt (bytes.length); out.write (bytes); out.flush (); }} catch (IOException e) {lanzar nueva NetworkException ("No se pudieron enviar los datos", e); }} / ** * Envía un mensaje de desconexión y cierra la conexión con la otra parte. * / public void close () lanza NetworkException {if (socket.isClosed ()) {throw new IllegalStateException ("La conexión ya está cerrada."); } intente {byte mensaje = "desconectar".getBytes (); sincronizado (bloqueo de escritura) {out.writeInt (Identificador. INTERNAL); out.writeInt (mensaje.longitud); out.write (mensaje); out.flush (); }} catch (IOException e) {System.out.println ("No se pudo enviar el mensaje de desconexión"); } try {sincronizado (writeLock) {out.close (); }} catch (IOException e) {lanzar una nueva NetworkException ("Error al cerrar la conexión", e); } finalmente {thread.interrupt (); }} / ** * Devuelve si la conexión con la otra parte está activa o no. * * @return True si la conexión está activa. Falso, de lo contrario. * / public boolean isConnected () {return! socket.isClosed (); }}

Identificador.java

/ ** * La clase {@code Identifier} contiene constantes que usa {@link Connection} para serializar y deserializar los datos * enviados a través de la red. * * @version 1.0 * @see Connection * / public final class Identifier {/ ** * Identificador para mensajes internos. * / public static final int INTERNAL = 1; / ** * Identificador para mensajes de texto. * / public static final int TEXT = 2; }

NetworkException.java

/ ** * La clase {@code NetworkException} indica un error relacionado con la red. * / public class NetworkException extiende la excepción {/ ** * Construye una {@code NetworkException} con {@code null} como su mensaje. * / public NetworkException () {} / ** * Construye una {@code NetworkException} con el mensaje especificado. * * @param message Un mensaje para describir el error. * / public NetworkException (String mensaje) {super (mensaje); } / ** * Construye una {@code NetworkException} con el mensaje y la causa especificados. * * @param message Un mensaje para describir el error. * @param cause Una causa de error. * / public NetworkException (mensaje de cadena, causa descartable) {super (mensaje, causa); } / ** * Construye una {@code NetworkException} con la causa especificada. * * @param cause Una causa de error. * / public NetworkException (causa descartable) {super (causa); }}

UsageExample.java

/ ** * La clase {@code UsageExample} muestra el uso de {@link Server} y {@link Client}. Este ejemplo usa * {@link Thread # sleep (long)} para garantizar que cada segmento se ejecute porque el inicio y el cierre rápidos hacen que algunos * segmentos no se ejecuten. * * @version 1.0 * @see Server * @see Client * / public class UsageExample {public static void main (String args) throws Exception {String host = "localhost"; int puerto = 10430; Servidor servidor = nuevo servidor (host, puerto); Cliente cliente = nuevo Cliente (host, puerto); Thread.sleep (100L); client.send ("Hola."); server.broadcast ("¡Hola, amigo!"); Thread.sleep (100L); server.disconnect (server.getConnections () [0]); // o client.close () para desconectarse del server.close () del lado del cliente; }}

Recomendado: