Servidores multiproceso en Java

Prerrequisitos: Programación de sockets en Java

Servidor de subprocesos múltiples: un servidor que tiene más de un subproceso se conoce como servidor de subprocesos múltiples. Cuando un cliente envía la solicitud, se genera un hilo a través del cual un usuario puede comunicarse con el servidor. Necesitamos generar múltiples subprocesos para aceptar múltiples requests de múltiples clientes al mismo tiempo. 

Multithreaded Servers

Ventajas del servidor multiproceso:

  • Rápido y eficiente: el servidor multiproceso podría responder de manera eficiente y rápida a las crecientes consultas de los clientes rápidamente.
  • El tiempo de espera para los usuarios disminuye: en un servidor de subproceso único, otros usuarios tenían que esperar hasta que se completara el proceso en ejecución, pero en servidores de subprocesos múltiples, todos los usuarios pueden obtener una respuesta a la vez, por lo que ningún usuario tiene que esperar a que finalicen otros procesos. .
  • Los hilos son independientes entre sí: no hay relación entre dos hilos. Cuando un cliente está conectado, se genera un nuevo hilo cada vez.
  • El problema en un subproceso no afecta a otros subprocesos: si se produce algún error en cualquiera de los subprocesos, ningún otro subproceso se verá afectado, todos los demás procesos seguirán ejecutándose con normalidad. En un servidor de subproceso único, todos los demás clientes tenían que esperar si ocurría algún problema en el subproceso.

Desventajas del servidor multiproceso:

  • Código complicado: es difícil escribir el código del servidor multihilo. Estos programas no se pueden crear fácilmente.
  • La depuración es difícil: analizar la razón principal y el origen del error es difícil.

vista rápida

Creamos dos archivos java, Client.java y Server.java . contiene Cliente

MultiThreaded Server Programming

Programa del lado del cliente: un cliente puede comunicarse con un servidor utilizando este código. Esto involucra 

  1. Establecer una conexión de socket
  2. Comunicación

Java

import java.io.*;
import java.net.*;
import java.util.*;
  
// Client class
class Client {
    
    // driver code
    public static void main(String[] args)
    {
        // establish a connection by providing host and port
        // number
        try (Socket socket = new Socket("localhost", 1234)) {
            
            // writing to server
            PrintWriter out = new PrintWriter(
                socket.getOutputStream(), true);
  
            // reading from server
            BufferedReader in
                = new BufferedReader(new InputStreamReader(
                    socket.getInputStream()));
  
            // object of scanner class
            Scanner sc = new Scanner(System.in);
            String line = null;
  
            while (!"exit".equalsIgnoreCase(line)) {
                
                // reading from user
                line = sc.nextLine();
  
                // sending the user input to server
                out.println(line);
                out.flush();
  
                // displaying server reply
                System.out.println("Server replied "
                                   + in.readLine());
            }
            
            // closing the scanner object
            sc.close();
        }
        catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Programa del lado del servidor: cuando se conecta un nuevo cliente y envía el mensaje al servidor.

1. Clase de servidor: los pasos involucrados en el lado del servidor son similares a los del artículo Programación de sockets en Java con un ligero cambio para crear el objeto de subproceso después de obtener los flujos y el número de puerto.

  • Establecimiento de la conexión: el objeto de socket del servidor se inicializa y, dentro de un ciclo while, un objeto de socket acepta continuamente una conexión entrante.
  • Obtención de los flujos: el objeto de flujo de entrada y el objeto de flujo de salida se extraen del objeto de socket de las requests actuales.
  • Creación de un objeto controlador: después de obtener los flujos y el número de puerto, se crea un nuevo objeto clientHandler (la clase anterior) con estos parámetros.
  • Invocación del método start() : El método start() se invoca en este objeto de subproceso recién creado.

2. Clase ClientHandler: como usaremos subprocesos separados para cada solicitud, comprendamos el funcionamiento y la implementación de la clase ClientHandler que implementa Runnable. Un objeto de esta clase actúa como un objetivo ejecutable para un nuevo hilo.

  • Primero, esta clase implementa la interfaz Runnable para que pueda pasarse como un objetivo Runnable al crear un nuevo Thread .
  • En segundo lugar, el constructor de esta clase toma un parámetro, que puede identificar de forma única cualquier solicitud entrante, es decir, un Socket .
  • Dentro del método run() de esta clase, lee el mensaje del cliente y responde.

Java

import java.io.*;
import java.net.*;
  
// Server class
class Server {
    public static void main(String[] args)
    {
        ServerSocket server = null;
  
        try {
  
            // server is listening on port 1234
            server = new ServerSocket(1234);
            server.setReuseAddress(true);
  
            // running infinite loop for getting
            // client request
            while (true) {
  
                // socket object to receive incoming client
                // requests
                Socket client = server.accept();
  
                // Displaying that new client is connected
                // to server
                System.out.println("New client connected"
                                   + client.getInetAddress()
                                         .getHostAddress());
  
                // create a new thread object
                ClientHandler clientSock
                    = new ClientHandler(client);
  
                // This thread will handle the client
                // separately
                new Thread(clientSock).start();
            }
        }
        catch (IOException e) {
            e.printStackTrace();
        }
        finally {
            if (server != null) {
                try {
                    server.close();
                }
                catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
  
    // ClientHandler class
    private static class ClientHandler implements Runnable {
        private final Socket clientSocket;
  
        // Constructor
        public ClientHandler(Socket socket)
        {
            this.clientSocket = socket;
        }
  
        public void run()
        {
            PrintWriter out = null;
            BufferedReader in = null;
            try {
                    
                  // get the outputstream of client
                out = new PrintWriter(
                    clientSocket.getOutputStream(), true);
  
                  // get the inputstream of client
                in = new BufferedReader(
                    new InputStreamReader(
                        clientSocket.getInputStream()));
  
                String line;
                while ((line = in.readLine()) != null) {
  
                    // writing the received message from
                    // client
                    System.out.printf(
                        " Sent from the client: %s\n",
                        line);
                    out.println(line);
                }
            }
            catch (IOException e) {
                e.printStackTrace();
            }
            finally {
                try {
                    if (out != null) {
                        out.close();
                    }
                    if (in != null) {
                        in.close();
                        clientSocket.close();
                    }
                }
                catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

Pasos:

  • Compile los programas Cliente y Servidor.
  • Ejecute primero el servidor y luego el Cliente.

Producción

Publicación traducida automáticamente

Artículo escrito por prateekc231 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 *