Multi-thread in Java Socket

1

I do not have experience with Java, so once again I go to the Stack to help me, I have a basic code from a server that receives a message from a client via socket and the client's code, I need to modify both, to accept connections of more customers.

/**
 * Classe Servidor - responsável por criar a conexão e receber as conexões dos clientes.
 * Exibe a informação enviada pelo cliente.
 */

import java.io.IOException;
import java.net.*;
import java.util.Scanner;

public class Servidor {

    public static void main(String[] args)  throws IOException{     

        //Cria um socket na porta 12345
        ServerSocket servidor = new ServerSocket (12345);
        System.out.println("Porta 12345 aberta!");

        // Aguarda alguém se conectar. A execução do servidor
        // fica bloqueada na chamada do método accept da classe
        // ServerSocket. Quando alguém se conectar ao servidor, o
        // método desbloqueia e retorna com um objeto da classe
        // Socket, que é uma porta da comunicação.

        System.out.print("Aguardando conexão do cliente...");       

        System.out.println("Nova conexao com o cliente " + cliente.getInetAddress().getHostAddress());


        //Recebe a mensagem enviada pelo cliente
        Scanner s = new Scanner(cliente.getInputStream());

        //Exibe mensagem no console
        while(s.hasNextLine())
        {
            System.out.println(s.nextLine());
        }

        //Finaliza objetos
        s.close();
        cliente.close();
        servidor.close();
        System.out.println("Fim do Servidor!");
    }
}


import java.io.IOException;
import java.io.PrintStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;


public class Cliente extends thread{

    public static void main(String args[]) throws UnknownHostException, IOException 
    {

        // para se conectar ao servidor, cria-se objeto Socket.
        // O primeiro parâmetro é o IP ou endereço da máquina que
        // se quer conectar e o segundo é a porta da aplicação.
        // Neste caso, usa-se o IP da máquina local (127.0.0.1)
        // e a porta da aplicação ServidorDeEco (12345).

        Socket cliente = new Socket("127.0.0.1", 12345);
        System.out.println("O cliente conectou ao servidor");

        //Prepara para leitura do teclado
        Scanner teclado = new Scanner(System.in);

        //Cria  objeto para enviar a mensagem ao servidor
        PrintStream saida = new PrintStream(cliente.getOutputStream());

        //Envia mensagem ao servidor
        while(teclado.hasNextLine())
        {
            saida.println(teclado.nextLine());          
        }

        saida.close();
        teclado.close();
        cliente.close();
        System.out.println("Fim do cliente!");
    }
}

Could anyone give me an idea? I'm really lost with these exercises.

    
asked by anonymous 06.12.2014 / 20:29

1 answer

3

Well, so you can accept more client connections on your server, one solution is to adapt your server to work with Multithread .

The concept of Multithread , speaking in simplicity, makes it possible to execute several tasks of the same application at the same time.

Returning to your problem, the solution may be as follows, you can create your server as a Thread and instantiate it for each new client, by persisting the client socket in a variable to be managed later.

Server Class:

public class Server implements Runnable{
    public Socket cliente;

    public Server(Socket cliente){
        this.cliente = cliente;
    }

    public static void main(String[] args)  throws IOException{     

        //Cria um socket na porta 12345
        ServerSocket servidor = new ServerSocket (12345);
        System.out.println("Porta 12345 aberta!");

        // Aguarda alguém se conectar. A execução do servidor
        // fica bloqueada na chamada do método accept da classe
        // ServerSocket. Quando alguém se conectar ao servidor, o
        // método desbloqueia e retorna com um objeto da classe
        // Socket, que é uma porta da comunicação.
        System.out.println("Aguardando conexão do cliente...");   

        while (true) {
          Socket cliente = servidor.accept();
          // Cria uma thread do servidor para tratar a conexão
          Server tratamento = new Server(cliente);
          Thread t = new Thread(tratamento);
          // Inicia a thread para o cliente conectado
          t.start();
        }
    }

    /* A classe Thread, que foi instancia no servidor, implementa Runnable.
       Então você terá que implementar sua lógica de troca de mensagens dentro deste método 'run'.
    */
    public void run(){
        System.out.println("Nova conexao com o cliente " + this.cliente.getInetAddress().getHostAddress());

        try {
            Scanner s = null;
            s = new Scanner(this.cliente.getInputStream());

            //Exibe mensagem no console
            while(s.hasNextLine()){
                System.out.println(s.nextLine());
            }

            //Finaliza objetos
            s.close();
            this.cliente.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Client Class:

//Prefira implementar a interface Runnable do que extender a classe Thread, pois neste caso utilizaremos apena o método run.
public class Cliente implements Runnable{

    private Socket cliente;

    public Cliente(Socket cliente){
        this.cliente = cliente;
    }

    public static void main(String args[]) throws UnknownHostException, IOException {

        // para se conectar ao servidor, cria-se objeto Socket.
        // O primeiro parâmetro é o IP ou endereço da máquina que
        // se quer conectar e o segundo é a porta da aplicação.
        // Neste caso, usa-se o IP da máquina local (127.0.0.1)
        // e a porta da aplicação ServidorDeEco (12345).
        Socket socket = new Socket("127.0.0.1", 12345);

        /*Cria um novo objeto Cliente com a conexão socket para que seja executado em um novo processo.
        Permitindo assim a conexão de vário clientes com o servidor.*/
        Cliente c = new Cliente(socket);
        Thread t = new Thread(c);
        t.start();
    }

    public void run() {
        try {
            PrintStream saida;
            System.out.println("O cliente conectou ao servidor");

            //Prepara para leitura do teclado
            Scanner teclado = new Scanner(System.in);

            //Cria  objeto para enviar a mensagem ao servidor
            saida = new PrintStream(this.cliente.getOutputStream());

            //Envia mensagem ao servidor
            while(teclado.hasNextLine()){
                saida.println(teclado.nextLine());          
            }

            saida.close();
            teclado.close();
            this.cliente.close();
            System.out.println("Fim do cliente!");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
    
07.12.2014 / 17:53