You are on page 1of 7

Chat Multi Usurios com Socket

Encontrei esse chat multi usurio que tive que fazer na poca da faculdade, acho que na matria de sistemas distribudos. Vou disponibilizar as duas classes, a classe servidor e a classe cliente.

Para us-lo, primeiro necessrio rodar a classe servidor, para ento rodar a classe cliente. Como multi usurio, por que tem implementao de Threads, possvel rodar varias instncias da classe cliente.

Na classe cliente possvel configurar a mquina que est rodando o servidor, est por padro como localhost, mas caso queira testar em alguma rede, s alterar para o IP da mquina em que est o servidor. As explicaes esto comentadas linha a linha no cdigo. Listagem 1. Classe Servidor import import import import import import import import import import java.io.BufferedReader; java.io.IOException; java.io.InputStreamReader; java.io.PrintStream; java.net.ServerSocket; java.net.Socket; java.util.ArrayList; java.util.Enumeration; java.util.List; java.util.Vector;

public class ServidorSocket extends Thread{ // Parte que controla as conexes por meio de threads. private static Vector CLIENTES; // socket deste cliente private Socket conexao; // nome deste cliente private String nomeCliente; // lista que armazena nome de CLIENTES private static List LISTA_DE_NOMES = new ArrayList(); // construtor que recebe o socket deste cliente public ServidorSocket(Socket socket) { this.conexao = socket; } //testa se nomes so iguais, se for retorna true public boolean armazena(String newName){ // System.out.println(LISTA_DE_NOMES); for (int i=0; i< LISTA_DE_NOMES.size(); i++){ if(LISTA_DE_NOMES.get(i).equals(newName)) return true; } //adiciona na lista apenas se no existir LISTA_DE_NOMES.add(newName); return false;

} //remove da lista os CLIENTES que j deixaram o chat

public void remove(String oldName) { for (int i=0; i< LISTA_DE_NOMES.size(); i++){ if(LISTA_DE_NOMES.get(i).equals(oldName)) LISTA_DE_NOMES.remove(oldName); } } public static void main(String[] args) { // instancia o vetor de CLIENTES conectados CLIENTES = new Vector(); try { // cria um socket que fica escutando a porta 5555. ServerSocket server = new ServerSocket(5555); System.out.println("ServidorSocket rodando na porta 5555"); // Loop principal. while (true) { // aguarda algum cliente se conectar. // A execuo do servidor fica bloqueada na chamada do mtodo accept da // classe ServerSocket at que algum cliente se conecte ao servidor. // O prprio mtodo desbloqueia e retorna com um objeto da classe Socket Socket conexao = server.accept(); // cria uma nova thread para tratar essa conexo Thread t = new ServidorSocket(conexao); t.start(); // voltando ao loop, esperando mais algum se conectar. } } catch (IOException e) { // caso ocorra alguma excesso de E/S, mostre qual foi. System.out.println("IOException: " + e); } } // execuo da thread

public void run()

{ try { // objetos que permitem controlar fluxo de comunicao que vem do cliente BufferedReader entrada = new BufferedReader(new InputStreamReader(this.conexao.getInputStream())); PrintStream saida = new PrintStream(this.conexao.getOutputStream()); // recebe o nome do cliente this.nomeCliente = entrada.readLine(); //chamada ao metodo que testa nomes iguais if (armazena(this.nomeCliente)){ saida.println("Este nome ja existe! Conecte novamente com outro Nome."); CLIENTES.add(saida); //fecha a conexao com este cliente this.conexao.close(); return; } else { //mostra o nome do cliente conectado ao servidor System.out.println(this.nomeCliente + " : Conectado ao Servidor!"); } //igual a null encerra a execuo if (this.nomeCliente == null) { return; } //adiciona os dados de saida do cliente no objeto CLIENTES CLIENTES.add(saida); //recebe a mensagem do cliente String msg = entrada.readLine(); // Verificar se linha null (conexo encerrada) // Se no for nula, mostra a troca de mensagens entre os CLIENTES while (msg != null && !(msg.trim().equals(""))) {

// reenvia a linha para todos os CLIENTES conectados sendToAll(saida, " escreveu: ", msg); // espera por uma nova linha. msg = entrada.readLine(); } //se cliente enviar linha em branco, mostra a saida no servidor System.out.println(this.nomeCliente + " saiu do bate-papo!"); //se cliente enviar linha em branco, servidor envia mensagem de saida do chat aos CLIENTES conectados sendToAll(saida, " saiu", " do bate-papo!"); //remove nome da lista remove(this.nomeCliente); //exclui atributos setados ao cliente CLIENTES.remove(saida); //fecha a conexao com este cliente this.conexao.close(); } catch (IOException e) { // Caso ocorra alguma excesso de E/S, mostre qual foi. System.out.println("Falha na Conexao... .. ."+" IOException: " + e); } } // enviar uma mensagem para todos, menos para o prprio public void sendToAll(PrintStream saida, String acao, String msg) throws IOException { Enumeration e = CLIENTES.elements(); while (e.hasMoreElements()) { // obtm o fluxo de sada de um dos CLIENTES PrintStream chat = (PrintStream) e.nextElement(); // envia para todos, menos para o prprio usurio if (chat != saida) { chat.println(this.nomeCliente + acao + msg);

} } // TODO Auto-generated method stub } }

Listagem 2. Classe Cliente

import import import import import

java.io.BufferedReader; java.io.IOException; java.io.InputStreamReader; java.io.PrintStream; java.net.Socket;

public class ClienteSocket extends Thread{ // parte que controla a recepo de mensagens do cliente private Socket conexao; // construtor que recebe o socket do cliente public ClienteSocket(Socket socket) { this.conexao = socket; } public static void main(String args[]) { try { //Instancia do atributo conexao do tipo Socket, conecta a IP do Servidor, Porta Socket socket = new Socket("127.0.0.1", 5555); //Instancia do atributo saida, obtem os objetos que permitem controlar o fluxo de comunicao PrintStream saida = new PrintStream(socket.getOutputStream()); BufferedReader teclado = new BufferedReader(new InputStreamReader(System.in)); System.out.print("Digite seu nome: "); String meuNome = teclado.readLine(); //envia o nome digitado para o servidor saida.println(meuNome.toUpperCase()); //instancia a thread para ip e porta conectados e depois inicia ela Thread thread = new ClienteSocket(socket); thread.start(); //Cria a variavel msg responsavel por enviar a mensagem para o servidor

String msg; while (true) { // cria linha para digitao da mensagem e a armazena na variavel msg System.out.print("Mensagem > "); msg = teclado.readLine(); // envia a mensagem para o servidor saida.println(msg); } } catch (IOException e) { System.out.println("Falha na Conexao... .. ." + " IOException: " + e); } } // execuo da thread public void run() { try { //recebe mensagens de outro cliente atravs do servidor BufferedReader entrada = new BufferedReader(new InputStreamReader(this.conexao.getInputStream())); //cria variavel de mensagem String msg; while (true) { // pega o que o servidor enviou msg = entrada.readLine(); //se a mensagem contiver dados, passa pelo if, caso contrario cai no break e encerra a conexao if (msg == null) { System.out.println("Conexo encerrada!"); System.exit(0); }

System.out.println(); //imprime a mensagem recebida System.out.println(msg); //cria uma linha visual para resposta System.out.print("Responder > "); } } catch (IOException e) { // caso ocorra alguma exceo de E/S, mostra qual foi. System.out.println("Ocorreu uma Falha... .. ." + " IOException: " + e); } } }

You might also like