Aplicación de chat de subprocesos múltiples en Java | Conjunto 2 (Programación del lado del cliente)

Requisitos previos: introducción de subprocesos en la programación de sockets , aplicación de chat multiproceso | Serie 1

Este artículo brinda la implementación del programa cliente para la aplicación de chat de subprocesos múltiples. Hasta ahora, todos los ejemplos de programación de sockets asumen que el cliente primero envía alguna información y luego el servidor u otros clientes responden a esa información.
En el mundo real, este podría no ser el caso. No es necesario enviar un mensaje a alguien para poder recibir uno. Un cliente debe recibir fácilmente un mensaje siempre que se le entregue, es decir, el envío y la recepción deben implementarse como actividades separadas en lugar de secuenciales .
Hay una solución muy simple que utiliza subprocesos para lograr esta funcionalidad. En la implementación del lado del cliente crearemos dos hilos:

  1. SendMessage: este hilo se utilizará para enviar el mensaje a otros clientes. El funcionamiento es muy simple, se necesita ingresar el mensaje para enviar y el destinatario para entregar. Tenga en cuenta que esta implementación asume que el mensaje tiene el formato mensaje # destinatario , donde destinatario es el nombre del destinatario. Luego escribe el mensaje en su flujo de salida que está conectado al controlador para este cliente. El controlador divide el mensaje y la parte del destinatario y los entrega a un destinatario en particular. Veamos cómo se puede implementar este hilo.

    Thread sendMessage = new Thread(new Runnable() {
                @Override
                public void run() {
                    while (true) {
      
                        // read the message to deliver.
                        String msg = sc.nextLine();
                        try {
      
                            // write on the output stream
                            dos.writeUTF(msg);
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            });
  2. readMessage: se toma un enfoque similar para crear un hilo para recibir los mensajes. Cuando cualquier cliente intenta escribir en el flujo de entrada de este cliente, usamos el método readUTF() para leer ese mensaje. El siguiente fragmento de código de cómo se implementa este hilo se muestra a continuación:

    Thread readMessage = new Thread(new Runnable() {
      
                @Override
                public void run() {
      
                    while (true) {
                        try {
      
                            // read the message sent to this client
                            String msg = dis.readUTF();
                            System.out.println(msg);
                        } catch (IOException e) {
      
                            e.printStackTrace();
                        }
                    }
                }
            });

Los pasos restantes de la programación del lado del cliente son similares a los ejemplos anteriores. Una breve explicación es la siguiente:

  1. Establecer una conexión de socket
  2. Comunicación
    La comunicación se produce con la ayuda de los subprocesos readMessage y sendMessage. Los subprocesos separados para leer y escribir garantizan el envío y la recepción simultáneos de mensajes.
// Java implementation for multithreaded chat client
// Save file as Client.java
  
import java.io.*;
import java.net.*;
import java.util.Scanner;
  
public class Client 
{
    final static int ServerPort = 1234;
  
    public static void main(String args[]) throws UnknownHostException, IOException 
    {
        Scanner scn = new Scanner(System.in);
          
        // getting localhost ip
        InetAddress ip = InetAddress.getByName("localhost");
          
        // establish the connection
        Socket s = new Socket(ip, ServerPort);
          
        // obtaining input and out streams
        DataInputStream dis = new DataInputStream(s.getInputStream());
        DataOutputStream dos = new DataOutputStream(s.getOutputStream());
  
        // sendMessage thread
        Thread sendMessage = new Thread(new Runnable() 
        {
            @Override
            public void run() {
                while (true) {
  
                    // read the message to deliver.
                    String msg = scn.nextLine();
                      
                    try {
                        // write on the output stream
                        dos.writeUTF(msg);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
          
        // readMessage thread
        Thread readMessage = new Thread(new Runnable() 
        {
            @Override
            public void run() {
  
                while (true) {
                    try {
                        // read the message sent to this client
                        String msg = dis.readUTF();
                        System.out.println(msg);
                    } catch (IOException e) {
  
                        e.printStackTrace();
                    }
                }
            }
        });
  
        sendMessage.start();
        readMessage.start();
  
    }
}

Salida:
Del cliente 0:

hello#client 1
client 1 : heya
how are you#client 1
client 1 : fine..how about you
logout

Del cliente 1:

client 0 : hello
heya#client 0
client 0 : how are you
fine..how about you#client 0
logout

Puntos importantes :

  • Para enviar un mensaje desde cualquier cliente, escriba el mensaje, seguido de un «#» y luego el nombre del cliente destinatario. Tenga en cuenta que esta implementación proporciona nombres como «cliente 0», «cliente 1″… «cliente n» y, por lo tanto, se deben agregar cuidadosamente los nombres al final. Después de eso, presione la tecla Enter.
  • Una vez que se envía un mensaje, el controlador de este cliente recibirá el mensaje y se entregará al cliente especificado.
  • Si algún cliente envía un mensaje a este cliente, el subproceso readMessage imprimirá automáticamente el mensaje en la consola.
  • Una vez que un cliente termina de chatear, puede enviar un mensaje de «cierre de sesión» sin ningún nombre de destinatario para que el servidor sepa que este cliente ha cerrado la sesión del sistema. Se recomienda enviar un mensaje de cierre de sesión antes de cerrar la terminal para que el cliente evite cualquier error.

¿Cómo ejecutar el programa anterior?

De manera similar a los ejemplos anteriores, primero ejecute el servidor y luego ejecute varias instancias del cliente. De cada uno de los clientes, intente enviarse un mensaje entre sí. Asegúrese de enviar el mensaje solo a un cliente válido, es decir, al cliente disponible en la lista activa.

Mejoras sugeridas

Esta fue solo la parte explicativa de cómo se pueden usar los subprocesos y la programación de sockets para crear programas poderosos. Hay algunas mejoras sugeridas a las implementaciones anteriores para los lectores interesados:

  • Cree una interfaz gráfica de usuario para clientes para enviar y recibir mensajes. Se puede usar una herramienta como Netbeans para diseñar rápidamente una interfaz
  • Actualmente, los nombres están codificados como cliente 0, cliente 1. Esto se puede mejorar para usar apodos dados por el usuario.
  • Esta implementación se puede mejorar aún más para proporcionar al cliente la lista de usuarios activos actuales para que pueda saber quiénes son todos sus amigos en línea. Se puede implementar un método simple para este propósito que, cuando se invoca, imprime los nombres en la lista activa.

Este artículo es una contribución de Rishabh Mahrsee . Si le gusta GeeksforGeeks y le gustaría contribuir, también puede escribir un artículo usando contribuya.geeksforgeeks.org o envíe su artículo por correo a contribuya@geeksforgeeks.org. Vea su artículo que aparece en la página principal de GeeksforGeeks y ayude a otros Geeks.

Escriba comentarios si encuentra algo incorrecto o si desea compartir más información sobre el tema tratado anteriormente.

Publicación traducida automáticamente

Artículo escrito por GeeksforGeeks-1 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *