Chat em java usando Socket e Thread

Ola boa tarde eu sei que tem muita gente que não gosta disso mas preciso de uma ajuda o mais urgente possivel:eu sou aluno de segundo semestre de sistemas para internet(webdesigner) e tenho uma matéria chamada ambiente web aonde meu professor pediu o seguinte exercicio:
[size=18][b]Crie um chat com a linguagem de programação Java utilizando Socket e Thread.

Este programa deve ter um servidor que permita que vários cliente se conectem e conversem entre si. Quando o usuário A enviar uma mensagem para o servidor ela deve ser retransmitida para todos os clientes conectados.[/b][/size]

Este exercicio vale nota e como estou mal nessa materia e o professor masl explicou socjket e thread eu gostria se fosse possivel que vc me ajudasem enviando o código, se possivel antes do dia 21/11, pis como fui mal na prova corro o rusco de pegar dp, se puderem me ajudar agradeço se não agradeço do mesmo jeito

obrigado

victor hugo

1 curtida

mano, tu veio no forum errado, ngm aqui vai te passar o codigo pronto, mas…
se vc quiser tentar fazer e surgirem duvidas te garanto q elas serão resolvias pelo pessoal aqui :slight_smile:

obrigado cara, bom vamos ver eu fiz assim:
esse éo cliente:

import java.net.;
import java.io.
;

public class Cliente extends Thread
{
private String server;
private int porta;

 public Cliente(String server, int porta){   
     this.server = server;   
     this.porta = porta;   
 }   

 public static void main(String[] args){   
      try{   
           String server = "localhost";   
           int porta = 1000;   
           int numeroDeClientes = 3;   

           for(int i=0; i < numeroDeClientes; i++){   

               new Cliente(server, porta).start();   

        }   

      }catch(Exception e){   
           e.printStackTrace();   
      }   
 }   


 public void run(){   
      try{   

               while(true){   

                     Socket s = new Socket(server, porta);   

                     System.out.println("Conectado a " + server + ":" + porta);   

                     ObjectOutputStream oo = new ObjectOutputStream(s.getOutputStream());   

                     oo.writeObject("Soh!");   

                     s.close();   
           }   

      }catch(Exception e){   
           e.printStackTrace();   
      }   
 }   

}

e esse éo servidor:

import java.net.;
import java.io.
;

public class Servidor implements Runnable
{
ServerSocket ss;

    public Servidor(int porta) throws Exception{   
      ss = new ServerSocket(porta);   

      new Thread(this).start();   

      System.out.println("Servidor ouvindo na porta:" + porta);   

    }   

 public void run(){   
      try{   
           while(true){   
                new TrataCliente(ss.accept()).start();   
                System.out.println("Mais um cliente atendido!");   

           }   

      }catch(Exception e){   
           e.printStackTrace();   
           System.exit(1);   
      }   
 }   
 public static void main(String[] args){   
      try{   
           new Servidor(1000);   

      }catch(Exception e){   
           e.printStackTrace();   
           System.exit(1);   
      }   
 }   

}

class TrataCliente extends Thread
{
private Socket client;

 public TrataCliente(Socket s){   
      client = s;   
 }   

 public void run(){   
      try{   
           // aqui vai a sua comunicacao com o cliente   
           ObjectInputStream oi = new ObjectInputStream(client.getInputStream());   

           System.out.println("Chegou isso:" + oi.readObject());   

           client.close();}   

      catch(Exception e){   
           e.printStackTrace();   
           System.exit(1);   
      }   
 }   

}
se estiver certo me avise, se não me avise aonde posso conseguir o código pois realmente tenho bastante dificuldade com a lingaugem Java e realmente tenho vontade de aprender e aprender bem mesmo, se puderem me indicar algum material tb que me facilite a aprender essa lingaugem.

obrigado

Quando postar códigos, use a tag code como descrito aqui:
http://www.guj.com.br/posts/list/50115.java

mas é só na parte de socket e thread que não entendie fui mal só na primeira prova, mal em termos aceretei quase a metade da prova, se puderem me indicar, um lugar aonde posso achar esse código

Veja se isso te ajuda:

http://www.guj.com.br/java.tutorial.artigo.20.1.guj

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.
1 curtida

alguem pode me ajudar???
não estou conseguindo reenviar a todos os clientes…
criei um
List Lista = new ArrayList(); // onde guarda a porta dos clientes…
quero q toda a mensagem que chegue até ela seja reenviada a todos os clientes…

segue o codigo…

try {
String mensagem;

        outS = conexao.getOutputStream();
        inputS = conexao.getInputStream();
        outDS = new DataOutputStream(outS);
        inD = new DataInputStream(inputS);

        mensagem = inD.readUTF();
        servidor.telaLog.append("Data: " + getData() + "\n");
        servidor.telaLog.append("  Mensagem recebida de " + conexao.getPort() + "\n");
        servidor.telaLog.append(mensagem + "\n\n");
        outDS.writeUTF(mensagem);

    }

Comece fazendo o que eu já falei ali em cima, e leia o link:
http://www.guj.com.br/posts/list/50115.java

1 curtida

Estou revivendo esta thread, porque acho que o assunto aqui tem a ver com a minha dúvida.
Tenho uma aplicação que faz várias requisições via socket para uma outra máquina, sendo que, estas requisições são dividas em threads, por exemplo, cada thread pode enviar 200 requisições, mas se eu tenho 3 threads enviando 200 threads a minha aplicação “perde” desempenho. Porque quando eu faço as requisições com 1 thread enviando 200 requisições eu recebo do outro lado umas 100 por segundo, quando eu coloco mais threads esta média cai para umas 50 a 40 por segundo.
A minha dúvida é esta, eu tenho que rever o código? Ou tenho que configurar algo na jvm? Ou configurar algo na máquina de envio? Ou fazer as três opções?
O meu sistema operacional é Red Hat 4.1.2-14, eu uso a jvm6 e para cirar as threads eu uso a java.util.concurrent.*, e para enviar as requisições eu uso java.net.Socket.

A melhor forma de lidar com threads de pequena duração é através de um thread pool.

Um thread pool nada mais é do que um grupo de threads que nunca (ou quase nunca) morrem. Essas threads são preparadas para receber vários runnables, ou entrar em espera caso não tenham um runnable para processar. A grande vantagem é que entre um runnable e outro não há a destruição e nem a criação de threads, o que consome muito desempenho. Ele também tem a vantagem de permitir que você regule o número máximo de threads.

Um thread pool é criado da seguinte forma:

//Cria um pool de 50 threads para suas requisições ExecutorService requisitionPool = Executors.newFixedThreadPool(50);

O objeto requisitionPool terá um método para submeter um Runnable ou um Future a uma das suas threads. Esse método bloqueia se não houver threads disponíveis para atender a essa solicitação. A sua classe que controla esse pool pode então enfileirar as mensagens recebidas e se utilizar das 50 threads do pool para envia-las.

Ter threads demais no computador também é um problema, pois cada thread diminui a eficiência do sistema operacional como um todo. Ela exige que o SO faça trocas de contexto, o que pode ser prejudicial quando o número de threads é muito grande.

O pool de threads eu já faço deesta maneira.
Crio um pool e cada thread faz suas próprias requisições, o que eu queria saber mesmo era se tem como acelerar o envio das mensgens por socket.
Para criar o pool eu uso java.util.concurrent.* e para fazer as requisições socket eu uso java.net.Socket.
Estava dando uma pesquisada e via algo sobre java.nio.channels.SocketChannel, alguém já usou é mais rápido que a classe Socket?

Se a aplicação deve atender um número excessivo de requisições simultâneas e precisa usar Java NIO e você é um pouco masoquista, pode tentar usar o Apache Mina:
http://mina.apache.org/

Eu já usei. É sim mais rápido. Especialmente se você usar os Selectors.
Nesse caso, pode até poupar muitas das threads que manipulam o socket.

Agora, você pode ter problemas com socket por outras causas, como a aplicação que recebe os dados não estar sendo capaz de trata-los. Isso faz com que a janela de envio do socket fique cheia, e acabe também interrompendo o servidor.

Se a aplicação que recebe enfileira mensagens na memória, sem um limite, você pode cair num ciclo prejudicial na sua aplicação:

  1. Sua aplicação não é capaz de processar, o buffer de memória dela vai enchendo;
  2. O buffer fica cheio, a aplicação fica mais lenta, e menos capaz de processar;
  3. Estando menos capaz de processar o buffer enche mais e mais rápido…

É bom testar essa situação também.

Uma coisa…

Você já rodou um profiler na sua aplicação, tanto na que envia quanto na que recebe, e procurou por gargalos de software? Já mediu a taxa de transferência na sua rede com o wireshark?

Acho que antes de alterar sua arquitetura, e tentar otimizar o socket, é bom ter certeza de que esse é o gargalo de performance!

A minha aplicação funciona como cliente.
Eu envio dados via GET para um servidor em uma outra máquina.
A aplicação funciona da seguinte maneira, ela vai no banco de dados pega as informações necessárias, monta uma url http e envia para uma determinada máquina. Sendo que este envio podem ser simultâneamente para várias máquinas, porque o usuário pode configurar vários serviços, que para a aplicação são máquinas de destinos.
As máquinas que vão receber estas requisições são servidores apaches com php.
Eu poderia ter muitos problemas com o SocketChannel, neste ambiente?

Eu acho que não…

Mas antes de começar a otimizar, meça e tenha certeza… use o profiler.

Fiz mais algumas pesquisas e gostaria de saber se vocês já usaram HttpComponents? É um projeto do jakarta.

Já consegui um throughput de 6mB/s usando sockets.
Qual é o seu throughput?

Desculpa a minha ignorância…hehehe
O que é throughput?