Thread + Socket (Client/Servidor) (RESOLVIDO)

boa tarde pessoal
estou com uma outra duvida aqui em relacao ao thread usando socket
eu fiz um prog que qndo cliente manda msg o servidor responde com quantos characters o cliente enviou
funcionou normal
mais agora preciso colocar varios clientes utilizando o thread e do jeito que eu estou fazendo nao esta funcionando de jeito nenhum
se alguem puder por favor me da 1 luz =)

Cliente:

[code] import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.net.UnknownHostException;

public class Cliente extends Thread {
String sentence;
String modifiedSentence;
Socket Client = null;
public static void main (String[] args)
{
Cliente teste1 = new Cliente();

      Thread Conserv = new Thread(teste1);	
      
      Thread Conserv2 = new Thread(teste1);
      
      Thread Conserv3 = new Thread(teste1); 
    	      
      Conserv.start();
    	   
      Conserv2.start();
	   
      Conserv3.start();
      
  }
  public void run()
  {
    	 MandarConectar();
        	 
  }
  public void MandarConectar(){
	 
	  try{
		  if(Client == null){
			// Cria um Socket cliente passando como parâmetro o ip e a porta do servidor   
	           Client = new Socket("localhost", 40000);}
		 
           // Cria um buffer que armazenará as informações de entrada do teclado
           BufferedReader inFromUSer = new BufferedReader(new InputStreamReader(System.in));
           
           // Cria um stream de saída 
           DataOutputStream outToServer = new DataOutputStream(Client.getOutputStream());
  
           // Cria um buffer que armazenará as informações retornadas pelo servidor
           BufferedReader inFromServer = new BufferedReader(new InputStreamReader(Client.getInputStream()));
   
           // Atribui as informações armazenadas no buffer do teclado à variável "sentence"
           sentence = inFromUSer.readLine();
   
           // Disponibiliza as informações contidas em "sentence" para a stream de saída do cliente
           outToServer.writeBytes(sentence + "\n");
   
           // Atribui as informações modificadas pelo servidor na variável "modifiedSentence"
           modifiedSentence = inFromServer.readLine();
   
           // Imprime no console do cliente a informação retornada pelo servidor
           System.out.println("do servidor: " + modifiedSentence);
   
           // Fecha o Socket
         Client.close();   
      } catch (UnknownHostException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
      } catch (IOException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
      }
  }

}[/code]

Servidor:

[code]import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;

public class Servidor {

public static void main(String[] args) {

   String clientSentence;
   String capitalized;
   ServerSocket socket = null;
   Socket connectionSocket = null;
   try {

       // Cria um SocketServer (Socket característico de um servidor)
       socket = new ServerSocket(40000);
       while(true) {    

           /* Cria um objeto Socket, mas passando informações características de um servidor,
            *no qual somente abre uma porta e aguarda a conexão de um cliente 
            */
           connectionSocket = socket.accept();
           
           // Cria uma buffer que irá armazenar as informações enviadas pelo cliente
           BufferedReader inFromClient = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));

           // Cria uma stream de sáida para retorno das informações ao cliente
           DataOutputStream outToClient = new DataOutputStream(connectionSocket.getOutputStream());

           // Faz a leitura das informações enviadas pelo cliente as amazenam na variável "clientSentence"
           clientSentence = inFromClient.readLine();

           /* Faz uma modificação na String enviada pelo cliente, simulando um processamento em "back-end"
            * antes de retorná-la ao cliente
            */
           capitalized = clientSentence.toLowerCase();

           // Imprime a a String modificada no console do servidor
           System.out.println("Voce digitou: "+capitalized.length()+" letras");

           // Retorna as informações modificadas, ao cliente
           outToClient.write(capitalized.length()); 
       } 
   } catch (IOException e) {
       // TODO Auto-generated catch block
       e.printStackTrace();
   }finally{
       try {
    	   connectionSocket.close();
		socket.close();
	} catch (IOException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
   }
}

}[/code]

Obriigado atE+

Você precisa criar um cliente para cada Thread:

[code]public static void main (String[] args) {
Thread Conserv = new Thread(new Cliente());
Thread Conserv2 = new Thread(new Cliente());
Thread Conserv3 = new Thread(new Cliente());

Conserv.start();
Conserv2.start();
Conserv3.start();

}[/code]

No lado do servidor, também será necessário criar uma classe que trabalhe com um Socket. E criar uma thread para cada “accept()” que o servidor receber.

esse thread para cada accept

seria o thread que enviaria a mensagem ao cliente?

tipo socket.acept for verdadeiro
ai mando a msg?
e isso?

Para cada cliente conectado, o accept() do ServerSocket cria um Socket, que representa aquele cliente. Então, você deve disparar uma thread para lidar com o cliente recebido.

O while do servidor vai ficar mais ou menos assim:

while (true) {
   ClienteHandler handler = new ClientHandler(socket.accept());
   Thread t = new Thread(handler);
   t.start();
}

A classe ClientHandler é quem vai efetivamente conversar com o cliente.

Portanto, todo esse código deve ser movido para o método run ClientHandler:

                // Cria um buffer que armazenará as informações de entrada do teclado  
                BufferedReader inFromUSer = new BufferedReader(new InputStreamReader(System.in));  
                  
                // Cria um stream de saída   
                DataOutputStream outToServer = new DataOutputStream(Client.getOutputStream());  
         
                // Cria um buffer que armazenará as informações retornadas pelo servidor  
                BufferedReader inFromServer = new BufferedReader(new InputStreamReader(Client.getInputStream()));  
          
                // Atribui as informações armazenadas no buffer do teclado à variável "sentence"  
                sentence = inFromUSer.readLine();  
          
                // Disponibiliza as informações contidas em "sentence" para a stream de saída do cliente  
                outToServer.writeBytes(sentence + "\n");  
          
                // Atribui as informações modificadas pelo servidor na variável "modifiedSentence"  
                modifiedSentence = inFromServer.readLine();  
          
                // Imprime no console do cliente a informação retornada pelo servidor  
                System.out.println("do servidor: " + modifiedSentence);  
          
                // Fecha o Socket  
              Client.close(); 

Seu código atual até funciona, pois sua comunicação com o cliente é curta, e ele deve retornar muito rapidamente ao accept. Mas sem a thread, ele não funcionará, pois o cliente manteria o servidor ocupado, e o código poderia demorar demais a voltar para o accept.

Com a thread vc permite várias comunicações simultâneas do lado do servidor.

1 curtida

Cada requisição feita para o servidor deve ser tratada em uma thread separada para não ocupar a porta que estiver atendendo as requisições, senão vc vai ter problemas.
Cada Socket recebido pelo accept vai para uma das threads.

Quando cliquei para responder não vi a resposta do ViniGodoy… mas ele está explicando melhor que eu… rs

hmm clareou bastante aqui
obrigado
ViniGodoy e ViniMunhoz

tipo o socket eu continuo criando na classe do servidor?
ai eu mando o socket aceito para a classe handle?
e a classe handle q vai retornar a mensagem pro cliente
e isso?

Isso.

Galera fiz do seguinte modo
da uma olhada para ver oq acham
Servidor:

[code] import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;

public class Servidor extends Thread{

public static void main(String args[]){
	ServerSocket s = null;
	try{//tentando criar uma conexao
		s = new ServerSocket(40000);//Cria um SocketServer com porta 40000
		while(true){
           /* Cria um objeto Socket, mas passando informações características de um servidor,
            *no qual somente abre uma porta e aguarda a conexão de um cliente 
            */
			Socket conexao = s.accept();
			
			//cria uma thread que envia a conexao
			Thread t = new Servidor(conexao);
			
			//inicia a thread t
			t.start();
		}
	}catch(IOException e){
		System.out.println("IOException "+e);
	}
}
private Socket conexao;
public Servidor(Socket s){//recebe o valor do socket enviado na thread
	conexao = s;
}
public void run(){
	try{
		
		// Cria uma buffer que irá armazenar as informações enviadas pelo cliente
		BufferedReader inFromClient = new BufferedReader(new InputStreamReader(conexao.getInputStream()));
	    
        // Cria uma stream de sáida para retorno das informações ao cliente
        DataOutputStream outToClient = new DataOutputStream(conexao.getOutputStream());

        // Faz a leitura das informações enviadas pelo cliente as amazenam na variável "EscritaCliente"
        String EscritaCliente = inFromClient.readLine();

        // Imprime a String modificada no console do servidor
        System.out.println("Voce Digitou: "+EscritaCliente.length()+" Digitos");
        
        // Imprime a String modificada no console do cliente
        outToClient.writeBytes("Voce Digitou: "+EscritaCliente.length()+" Digitos");
	}catch(IOException e){
		System.out.println("IOException "+e);
	}
}

}

[/code]

Cliente

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


public class Cliente extends Thread {
	public static void main(String args[]){
		try{
			// Cria um Socket conexao passando como parâmetro o ip e a porta do servidor 
			Socket conexao = new Socket("localhost",40000);
			
			//cria uma thread que envia a conexao
			Thread t = new Cliente(conexao);
			
			//inicia o thread
			t.start();
			
		}catch(IOException e){
			System.out.println("IOException"+e);
		}
	}
	private Socket conexao;
	public Cliente(Socket s){//recebe o valor do socket enviado na thread
		conexao = s;
	}
	public void run(){
		try{//cria uma printstream para pegar as informacoes enviadas do servidor
			PrintStream saida = new PrintStream(conexao.getOutputStream());
			
			//cria um bufferedreader para receber informacoes digitadas
			BufferedReader teclado = new BufferedReader (new InputStreamReader(System.in));
			
			//escreve uma mensagem ao usuario
			System.out.println("entre com algum digito");
			
			//digito recebe o valor digitado pelo usuario
			String digito = teclado.readLine();
			
			//imprime o valor de digito
			saida.println(digito);
			
			
			BufferedReader entrada = new BufferedReader(new InputStreamReader(conexao.getInputStream()));
			entrada.readLine();				
		}catch(IOException e){
			System.out.println("IOException"+e);
		}finally{
			try {
				conexao.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}

alguem pode me dar alguma dica ou opniao

É assim mesmo. Agora só falta você melhorar o protocolo de comunicação e colocar mensagens que façam mais sentido para a autenticação, troca de dados e desconexão.

certo… obrigado vini por ter me ajudado
atE+

Pessoal, estou fazendo uma aplicação parecida, onde tenho apenas um cliente que faz várias requisições ao servidor. Pergunta: No servidor devo abrir uma thread para a conexão do cliente, mas na classe cliente, devo abrir uma thread para cada requisição feita ao servidor? :?: