Java Socket - Fechar socket ou finalizar Thread?

0 respostas
java
E

Olá pessoal.

Estou fazendo um programa de chat, bem simples, só para praticar sockets.
Enfim, minha dúvida é quanto ao tratamento dos clientes conectados. Para cada ServerSocket.accept() inicio uma nova Thread para receber as mensagens dos clientes.e trata-las.
Porém ao fechar meu ServerSocket, devo apenas iterar sobre as threads e interrompe-las, ou devo fechar cada socket primeiro?

Também gostaria de opiniões sobre meu código, para saber se estou no caminho certo ou estou fazendo muito errado.

Segue o código que tenho até agora do Server:

public class Server implements Runnable, EventHandler, Closeable{
    private final EventHandler evt;
    private final List<ClientHandler> clientes;
    private final PrintWriter pw;
    private ServerSocket serverSocket;
    private Thread thread;
    private boolean started;

    public Server (PrintWriter writer, EventHandler evt) {
        this.pw = writer;
        this.evt = evt != null?evt:this;
        this.clientes = new LinkedList<>();
    }
    
    public Server(){
        this(new PrintWriter(System.out), null);
    }

    public boolean hasStarted(){
        return started;
    }
    
    public synchronized void openServer(int port) throws IOException{
        if(started) return;

        pw.println("Iniciando servidor...");
        
        serverSocket = new ServerSocket(port);
        thread = new Thread(this);
        thread.start();
        started = true;
        
        pw.println("Servidor iniciado na porta "+ port);
    }

    @Override
    public synchronized void close() throws IOException{
        if(!started) return;
    
        pw.println("Interrompendo servidor...");
        serverSocket.close();
        closeClients();
        started = false;
        pw.println("Servidor parado");
        evt.warning("Servidor Parado", "O servidor foi interrompido.");
    }

    public void closeClients(){
        synchronized(clientes){
            for(Iterator<ClientHandler> it = clientes.iterator(); it.hasNext();){
                ClientHandler ch = it.next();
                try {    
                    ch.close();
                    it.remove();
                } catch (IOException ex) {
                    pw.println("Erro ao fechar cliente: "+ch.getHostName());
                    pw.println(ex);
                }
            }
        }
    }

    @Override
    public void run() {
        while (!serverSocket.isClosed()) {
            try {
                Socket cliente = serverSocket.accept();
                //clientes.add(cliente);
                pw.println("Nova conexão com o cliente " + cliente.getInetAddress().getHostAddress());
                evt.notify("Cliente Conectado","Nova conexão com o cliente " + cliente.getInetAddress().getHostAddress());

                ClientHandler c = new ClientHandler(cliente, pw);
                clientes.add(c);
                c.start();
            } catch (IOException ex) {
                pw.println(ex);
            }
        }
    }

    @Override
    public void notify(String title, String message) {
        String s = new StringBuilder("[Notify] ")
                    .append(title)
                    .append(": ")
                    .append(message)
                    .toString();
        pw.println(s);
    }

    @Override
    public void warning(String title, String message) {
        String s = new StringBuilder("[Warning] ")
                    .append(title)
                    .append(": ")
                    .append(message)
                    .toString();
        pw.println(s);
    }



    private static class ClientHandler extends Thread implements Closeable{
        private final InputStream in;
        private final PrintWriter pw;
        private final Socket client;

        public ClientHandler(Socket client, PrintWriter pw) throws IOException {
            this.client = client;
            this.in = client.getInputStream();
            this.pw = pw;
        }
    
        public String getHostName(){
            return client.getInetAddress().getHostAddress();
        }
    
        @Override
        public void close() throws IOException{
            client.close();
        }
    
        @Override
        public void run() {
            try (BufferedReader br = new BufferedReader(new InputStreamReader(in,Main.CHARSET))){
                String s;
                while ((s = br.readLine()) != null) {
                    pw.println(s);
                }
            } catch (IOException ex) {
                System.err.println(ex);
                pw.println(ex);
            }
            System.err.println("Thread Finalizada");
        }
    }
}
Criado 10 de janeiro de 2016
Respostas 0
Participantes 1