Chat em java usando Socket e Thread

é esse codigo ai desculpa mandei o codigo errado

A resposta pra sua dúvida está exatamente em cima da sua pergunta.

Cara,mapear o servidor seria fazer com que ele saiba quem esta conectado nele ? e quando eu mandar uma menssagem para um determinado cliente ou pessoa ele reconheça essa pessoa na lista de clientes e entregue esa mensagem a essa pessoa ? mas os clientes ja estão numa lista todos conectados,como saber que tal cliente esta em tal posição da lista,ou em tal index da lista ? como indentificar um usuario na lista ? a lista guarda que informação do usuario ? o ip ?acho que não é o ip, deve ter uma especie de id auto increment pois ela guarda usuarios com o mesmo ip caso estejamos executando o chat na mesma maquina de começo acho que eu deveria imprimir uma lista de todos os clientes conectados com o seu respectivo index e apelido por exemplo no qual eu vou de começo digitar o index do destinatario.Como faço para pegar o index da lista ? Se tiver algum material pra indicar pra eu dar uma olhada desde ja grato abraço Cara

Você tem que elaborar um protocolo:
http://www.guj.com.br/posts/list/136538.java#735860

Depois disso, crie um Map no seu servidor, que relaciona uma conexão socket cliente à um ID. Se você está fazendo um servidor de chat, você pode usar como ID o próprio nick de quem está naquela conexão, desde que o servidor recuse duas conexões com o mesmo id. O seu protocolo também terá que conter mensagens de “fulano entrou”, “fulano saiu”, etc.

Ai Galera, boa tarde ,esquecendo um pouco a parte de enviar mensagem somente para um cliente.Eu achei um exemplo na net com formulario e tudo, pois tava osso de implementar os forms,o exemplo ta prontinho com form e tudo porem existe somente um cliente e servidor e o cliente manda mensagem para o servidor.tentei fazer com que exista mais de um cliente e que ele faça um broadcast(mande uma mensagem enviada por um cliente para todos os clientes).TA DANDO ERRO NO METODO MAIN DO SERVIDOR E NO PROTECT VOID FINALIZE.segue o codigo se alguem puder dizer onde eu estou errando desde ja GRATO

public class socketcliente extends JFrame implements ActionListener {
	 /**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	JLabel text,clicked;
     JButton botao;
     JPanel painel;
     JTextField campotexto;
     Socket socket = null;
     PrintWriter saida = null;
     BufferedReader entrada = null;
     
     socketcliente() //iniciamos o constructor
     {
             text = new JLabel("Texto a enviar por socket:");
             campotexto= new JTextField(30);
             botao = new JButton("Enviar!");
             botao.addActionListener(this);
             
             painel = new JPanel();
             painel.setLayout(new BorderLayout());
             painel.setBackground(Color.white);
             getContentPane().add(painel);
             painel.add("North", text);
             painel.add("Center", campotexto);
             painel.add("South", botao);
     }
     @Override
     public void actionPerformed(ActionEvent event) 
     {
             Object fonte = event.getSource();
             
             if (fonte == botao) //Envia informacao pelo socket
             {
                     String text = campotexto.getText();
                     saida.println(text);
                     campotexto.setText(new String("")); //recebe do servidor
                     
                     try{
                             String linha = entrada.readLine();
                             System.out.println("Texto recebido: " + linha);
                     }
                     catch (IOException e)
                     {
                             System.out.println("Falha na leitura!");
                             System.exit(1);
                     }
             }
     }
     
     public void EscutaSocket() //cria ligacao de socket
     {
    	 class Recebedor implements Runnable {
    		 
    		  private InputStream servidor;
    		 
    		  public Recebedor(InputStream servidor) {
    		  this.servidor = servidor;
    		  }

			@Override
			public void run() {
				// recebe msgs do servidor e imprime na tela
				 Scanner s = new Scanner(this.servidor);
				 while (s.hasNextLine()) {
				System.out.println(s.nextLine());
				}
				 
				
			}
    	 }
    	 try
             {
                     Socket cliente = new Socket("127.0.0.1", 85); //aqui decidimos qual o IP e a sua porta, neste caso 127.0.0.1:85
                     saida = new PrintWriter(cliente.getOutputStream(), true);
                     entrada = new BufferedReader(new InputStreamReader(cliente.getInputStream()));
                     
                     //thread para receber mensagens do servidor
                      Recebedor r = new Recebedor(cliente.getInputStream());
                      new Thread(r).start();
                      
                   // le msgs do teclado e manda pro servidor
                      Scanner teclado = new Scanner(System.in);
                      PrintStream saida = new PrintStream(cliente.getOutputStream());
                      while (teclado.hasNextLine()) {
                      saida.println(teclado.nextLine());
                       }
                     
             }
             catch(UnknownHostException e)
             {
                     System.out.println("Host desconhecido: localhost");
                     System.exit(1);
             }
             catch (IOException e)
             {
                     System.out.println("Não Existe Entrada nem Saída de informação");
                     System.exit(1);
                     }
             }
        public static void main(String[] args) {
		socketcliente frame = new socketcliente();
        frame.setTitle("Cliente");
        WindowListener ls = new WindowAdapter()
        {
                public void windowClosing(WindowEvent e)
                {
                        System.exit(0);
                }
        };
        frame.addWindowListener(ls);
        frame.pack();
        frame.setVisible(true);
        frame.EscutaSocket();
}
}

[code]
public class SocketServidor extends JFrame implements ActionListener {
/**
*
*/
private static final long serialVersionUID = 1L;
JButton botao;
JLabel label = new JLabel(“Texto Recebido:”);
JPanel painel;
JTextArea campotexto = new JTextArea();
ServerSocket servidor = null;
Socket cliente = null;
BufferedReader entrada = null;
PrintWriter saida = null;
String linha;

   SocketServidor(){ //Constructor
     botao = new JButton("Receber!");
     botao.addActionListener(this);

     painel = new JPanel();
     painel.setLayout(new BorderLayout());
     painel.setBackground(Color.white);
     getContentPane().add(painel);
     painel.add("North", label);
     painel.add("Center", campotexto);
     painel.add("South", botao);

   } 
  private boolean encerrar;
  private List<PrintStream> clientes;
  public void actionPerformed(ActionEvent event) 
       {
       Object source = event.getSource();

     if(source == botao)
       {
         campotexto.setText(linha);
       }
       }
     public void EscutaSocket() throws IOException{

    try{
      servidor = new ServerSocket(85); //Definição da porta que vai ficar à escuta, neste caso : porta 85
    } catch (IOException e) {
      System.out.println("Não é possivel escutar na porta 85");
      System.exit(-1);
    }
    try{
        cliente = servidor.accept();
      } catch (IOException e) {
        System.out.println("Servidor não aceitou: 85"); //
        System.exit(-1);
      }
      try{
	      entrada = new BufferedReader(new InputStreamReader(cliente.getInputStream()));
	      saida = new PrintWriter(cliente.getOutputStream(), true);
	    } catch (IOException e) {
	      System.out.println("Falha de permissão: 85");
	      System.exit(-1);
	    }
	 
	    while(true){
	      try{
	        linha = entrada.readLine();
	//Send data back to cliente
	        saida.println(linha);
	      } catch (IOException e) {
	        System.out.println("Falha de Leitura!");
	        System.exit(-1);
	      }
	    }
	    protected void finalize()
		  {
		//Clean up 
		     try{
		        entrada.close();
		        saida.close();
		        servidor.close();
		    } catch (IOException e) {
		        System.out.println("Não é possivel fechar!.");
		        System.exit(-1);
		    }
		  }
	    public static void main(String[] args) throws IOException {
			SocketServidor frame = new SocketServidor();
	        frame.setTitle("Servidor");
	        WindowListener ls = new WindowAdapter() {
	                public void windowClosing(WindowEvent e) {
	                        System.exit(0);
	                }
	        };
	        frame.addWindowListener(ls);
	        frame.pack();
	        frame.setVisible(true);
	        frame.EscutaSocket();
		}
     
    while (!encerrar) {
    	 // aceita um cliente
    	 Socket cliente = servidor.accept();
    	 System.out.println("Nova conexão com o cliente " +
    	 cliente.getInetAddress().getHostAddress()
    	 );
    //try{
      //cliente = servidor.accept();
  
      // adiciona saida do cliente à lista
      
      PrintStream ps = new PrintStream(cliente.getOutputStream());
     this.clientes.add(ps);
     
       // cria tratador de cliente numa nova thread
     
     TrataCliente tc = new TrataCliente(cliente.getInputStream(), this);
     new Thread().start();}}

    
     public void distribuiMensagem(String msg) {
 		// envia msg para todo mundo
 		   for (PrintStream cliente1 : this.clientes) {
 		   cliente1.println(msg);
 		  }
 		   }
     class TrataCliente implements Runnable {
	    	
	    	private InputStream cliente;
	    	 private SocketServidor servidor;
	    	
	    	 public TrataCliente(InputStream cliente, SocketServidor servidor) {
	    	this.cliente = cliente;
	    	 this.servidor = servidor;
	    	 }
           public void run() {
				// quando chegar uma msg, distribui pra todos
				 Scanner s = new Scanner(this.cliente);
				
				while (s.hasNextLine()) {
				servidor.distribuiMensagem(s.nextLine());
				}
				s.close();
				}
     }	

}
[/code]

Seria muito interessante você dizer que erro tá dando, especialmente se você ainda destacar a linha que o erro acusa.

Então ta dando esse erro na linha 84 da classe SocketServidor(a segunda classe)

Multiple markers at this line
- Syntax error, insert “;” to complete
LocalVariableDeclarationStatement
- Syntax error on token “(”, ; expected

E ta dando esse erro aqui na linha 72 da mesma classe SocketServidor

Multiple markers at this line
- Syntax error on token “void”, @ expected
- Syntax error, insert “enum Identifier” to complete
EnumHeaderName

Esses erros geralmente acontecem quando você:

a) Esquece de fechar chaves (ou fecha chaves demais);
b) Esquece de fechar parênteses ou aspas;

Não sei se era sua intenção, mas o método finalize() é usado pelo garbage collector, e você ali está fazendo uma sobrecarga.
Você queria isso mesmo?

Outra coisa… essas linhas se referem ao código que vc postou aqui no GUJ? Digo, se eu olhar o seu post lá atrás, vou ver a mesma linha que está acusando na IDE aí?

Ai Galera

[quote=cassiojoselito]Valeu pela dica, retirei o finalize, e agora ta sem errro,mas como juntei um código que tava com formulario e tinha um cliente que mandava mensagem para um servidor com um exemplo que não tinha formularios porem tinha varios clientes que podiam mandar broadcast para todos os clientes passando pelo servidor meu código agora que segue abaixo abre o formulario do servidor abre mais de um formulario de cliente mas não se comunica,se alguem puder me dar uma dica dizendo onde estou errando,desde ja grato.Abraço

 import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.io.*; // pacote de streams
import java.net.*; // pacote de sockets
import java.util.Scanner;

public class socketcliente extends JFrame implements ActionListener {
	 private static final long serialVersionUID = 1L;
	 JLabel text,clicked;
     JButton botao;
     JPanel painel;
     JTextField campotexto;
     Socket socket = null;
     PrintWriter saida = null;
     BufferedReader entrada = null;
     
     socketcliente(){ //iniciamos o constructor
          text = new JLabel("Texto a enviar por socket:");
          campotexto= new JTextField(30);
          botao = new JButton("Enviar!");
          botao.addActionListener(this);
          painel = new JPanel();
          painel.setLayout(new BorderLayout());
          painel.setBackground(Color.white);
          getContentPane().add(painel);
          painel.add("North", text);
          painel.add("Center", campotexto);
          painel.add("South", botao);
     }
    public void actionPerformed(ActionEvent event) 
         {
          Object fonte = event.getSource();
                if (fonte == botao) //Envia informacao pelo socket
                     {
                         String text = campotexto.getText();
                         saida.println(text);
                         campotexto.setText(new String("")); //recebe do servidor
                         try{
                             String linha = entrada.readLine();
                             System.out.println("Texto recebido: " + linha);
                            }
                         catch (IOException e)
                             {
                               System.out.println("Falha na leitura!");
                               System.exit(1);
                             }
                    }
        }
     public void EscutaSocket() //cria ligacao de socket
          {
    	    class Recebedor implements Runnable {
    		    private InputStream servidor;
    		    public Recebedor(InputStream servidor) {
    		         this.servidor = servidor;
    		    }
                public void run() {
				     // recebe msgs do servidor e imprime na tela
				     Scanner s = new Scanner(this.servidor);
				     while (s.hasNextLine()) {
				     System.out.println(s.nextLine());
				                              }
				                  }
    	                                         }
    	  try
             {
                Socket cliente = new Socket("127.0.0.1", 85); //aqui decidimos qual o IP e a sua porta, neste caso 127.0.0.1:85
                saida = new PrintWriter(cliente.getOutputStream(), true);
                entrada = new BufferedReader(new InputStreamReader(cliente.getInputStream()));
                //thread para receber mensagens do servidor
                Recebedor r = new Recebedor(cliente.getInputStream());
                new Thread(r).start();
                // le msgs do teclado e manda pro servidor
                Scanner teclado = new Scanner(System.in);
                PrintStream saida = new PrintStream(cliente.getOutputStream());
                while (teclado.hasNextLine()) {
                	saida.println(teclado.nextLine());
                                              }
              }
             catch(UnknownHostException e)
                 {
                     System.out.println("Host desconhecido: localhost");
                     System.exit(1);
                 }
             catch (IOException e)
             {
                     System.out.println("Não Existe Entrada nem Saída de informação");
                     System.exit(1);
                     }
             }
     public static void main(String[] args) {
		  socketcliente frame = new socketcliente();
		  frame.setTitle("Cliente");
		  WindowListener ls = new WindowAdapter(){
                public void windowClosing(WindowEvent e)
                {
                        System.exit(0);
                }
                                                  };
          frame.addWindowListener(ls);
          frame.pack();
          frame.setVisible(true);
          frame.EscutaSocket();
}
}
import java.awt.Color;
import java.awt.BorderLayout;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
import java.net.*;
import java.util.List;

public class SocketServidor extends JFrame implements ActionListener {
	 private static final long serialVersionUID = 1L;
	       JButton botao;
	       JLabel label = new JLabel("Texto Recebido:");
	       JPanel painel;
	       JTextArea campotexto = new JTextArea();
	       ServerSocket servidor = null;
	       Socket cliente = null;
	       BufferedReader entrada = null;
	       PrintWriter saida = null;
	       String linha;

	 SocketServidor(){ //Constructor
		  botao = new JButton("Receber!");
	      botao.addActionListener(this);
          painel = new JPanel();
	      painel.setLayout(new BorderLayout());
	      painel.setBackground(Color.white);
	      getContentPane().add(painel);
	      painel.add("North", label);
	      painel.add("Center", campotexto);
	      painel.add("South", botao);
         } 
     private boolean encerrar;
     private List<PrintStream> clientes;
	 public void actionPerformed(ActionEvent event){
	       Object source = event.getSource();
          if(source == botao)
	       {
	         campotexto.setText(linha);
	       }
	       }
	 public void EscutaSocket() throws IOException{
        try{
	      servidor = new ServerSocket(85); //Definição da porta que vai ficar à escuta, neste caso : porta 85
	      while (!encerrar) {
		      // aceita um cliente
		      Socket cliente = servidor.accept();
		      System.out.println("Nova conexão com o cliente " +
		      cliente.getInetAddress().getHostAddress()
		    	 );
		    
		      //cliente = servidor.accept();
		  
		      // adiciona saida do cliente à lista
		      
		      PrintStream ps = new PrintStream(cliente.getOutputStream());
		      this.clientes.add(ps);
		     
		       // cria tratador de cliente numa nova thread
		     
		     new Thread().start();}
	    } catch (IOException e) {
	      System.out.println("Não é possivel escutar na porta 85");
	      System.exit(-1);
	    }
	    try{
	        cliente = servidor.accept();
	      } catch (IOException e) {
	        System.out.println("Servidor não aceitou: 85"); //
	        System.exit(-1);
	    }
	    try{
		    entrada = new BufferedReader(new InputStreamReader(cliente.getInputStream()));
		    saida = new PrintWriter(cliente.getOutputStream(), true);
		    } catch (IOException e) {
		      System.out.println("Falha de permissão: 85");
		      System.exit(-1);
		    }
		 while(true){
		      try{
		        linha = entrada.readLine();
		//Send data back to cliente
		        saida.println(linha);
		      } catch (IOException e) {
		        System.out.println("Falha de Leitura!");
		        System.exit(-1);
		      }
		    }
		   }
		 public void distribuiMensagem(String msg) {
		      // envia msg para todo mundo
		 	  for (PrintStream cliente : this.clientes) {
		 		  cliente.println(msg);
		 		  }
		 		   }
		 public static void main(String[] args) throws IOException {
			  SocketServidor frame = new SocketServidor();
		      frame.setTitle("Servidor");
		      WindowListener ls = new WindowAdapter() {
		            public void windowClosing(WindowEvent e) {
		                    System.exit(0);
		                }
		        };
		      frame.addWindowListener(ls);
		      frame.pack();
		      frame.setVisible(true);
		      frame.EscutaSocket();
		    }
}

[/quote]

Não entendi nada. Talvez essas dicas possam te ajudar.

Então cara acontece o seguinte: ja dei um arrumada no código lá, tirando o finalize e acertei os devidos parênteses, agora o código que ta sem erro de sintaxe, esta criando os formularios dos clientes e do servidor, porem não comunicam-se.O que tentei fazer nesse codigo é juntar 2 aplicações que eu tinha como exemplo de sockets, uma que tinha um cliente comunicando-se com o servidor com os seus respectivos formulario, e outra sem formularios, que tinha varios clientes que mandavam mensagens uns aos outros atravez de multcast, ou seja um cliente não se comunicava somente com outro cliente, mas sim mandava uma mensagem para todos os outros clientes.O que to tentando fazer no código acima é fazer um multcast com formularios em que o cliente manda mensagem aos outros passando pelo servidor,desde ja grato, Abraço

Não entendi nada. Talvez essas dicas possam te ajudar.[/quote]

haha boa!

Não sei se ajuda, mas to mandando um link com um chat que fiz. Está simples, devido ao curto intervalo de tempo para fazer.
O anexo contém o programa e um artigo. vlw.

http://sites.google.com/site/diogooliveiramonte/trabalhos-e-artigos

ola a todos!
gostaria se for possível alguém dar.me uma ajudinha!
estou a fazer um chat em java utilizando JRMI
e estou com alguns problemas!
por exemplo quando um novo cliente entre, o primeiro que peço é que introduza um nick,
então eu mando isso para o servidor e ele vai verificar se existe, se existir tem de pedir novamente o nick, como faço isto para que sempre este a pedir o nick caso já exista um registado?
tive a tentar implementar algo do tipo um while (c.registo(nick)) que vai pedir o nick e enviar po servidor ate que nao seja verificado a condiçao! mas não estou a conseguir!
alguém poderia dar alguma dica?

muito obrigado a todos!

Preciso de uma ajuda criei uma Chat mas não tenho uma ideia de como posso fazer para gerencia-lo corretamente, pois preciso deixar que os usuarios possam criar as salas e é esse o meu problema.

[quote=ViniGodoy]Algumas dicas:

  1. O cliente não terá mais de uma thread. Só o server.
  2. O servidor terá 1 thread para esperar os clientes (método accept) e uma thread para cada cliente criado;
  3. Cada cliente que for criado deve ser colocado num List. Assim, quando uma mensagem chegar, você pode redistribuir para os outros clientes;
  4. Não utilize o ObjectOutputStream, no lugar, pense no DataOuputStream. Por lá tem um método readUTF, que deve ser mais fácil de usar no seu caso.[/quote]

Viny

Em outro post do forum , copiei um arquivo de simpleChat que disponibilizou , estou com uma dúvida nesse trecho de código.


private void talk(OutputStream outputStream) throws IOException{
		DataOutputStream output = new DataOutputStream(outputStream);
		String line = "";
		
		while (!line.equals("EXIT")){
			
			Scanner scan = new Scanner(System.in);        
			System.out.print(": ");
			line = scan.nextLine();
			output.writeInt(line.length());
			
			for (char ch : line.toCharArray())
				output.writeChar(ch);
				output.flush();
		}
	}

Gostaria de saber primeiramente por quê envia a linha output.writeInt(line.length()); e somente depois percorre a String line , enviando char por char ?
ao invés de usar o método writeChars(String s) DataOutputStream ?
Obrigado !

Porque a idéia desse código é demonstrar como se montar um protocolo de comunicação. Você irá fazer desse jeito para outros tipos de bytes, como envio de arquivos, imagens, etc.

ok Viny , obrigado !

Esse código eu montei em aula, com os alunos. Primeiro desenhamos um protocolo, e eu fui explicando os desafios de enviar e receber dados. Por que você precisa de tamanhos, como o socket funciona, como funcionam os reads e os writes. Depois programamos isso na frente da turma. E depois passei de lição para que eles adicionassem troca de arquivos no protocolo.

Foi muito interessante, a turma gostou muito. Geralmente eles gostam de ver professores “colocando a mão na massa”.