Thread + Socket - Essa eu quero ver vocês resolverem!

3 respostas
Z
Galera, eh o seguinte: Eu criei um aplicativo do tipo servidor, onde eu instancio um objeto do tipo ServerSocket, e fico escutando em uma porta, e quando ele recebe uma conexão, inicia uma nova Thread. Portanto, posso ter vários client´s abertos com meu servidor. Os clientes solicitam determinadas informações, que o servidor processa e devolve a resposta. Muito bem. O problema é o seguinte. E se eu quiser, através do servidor, fechar as minhas conexões?????? Não consigo de jeito nenhum... Meu código eh assim:
package br;

import java.awt.event.*;
import java.io.*;
import java.net.*;
import java.util.*;

public class Server extends Thread implements ActionListener {

    public static void main(String[] args) {
        Server i = new Server();
        i.carregar();
    }

    public void carregar(){
        w = new Window();
        w.setVisible(true);
        
        w.getJMenuItemConectar().addActionListener(this);
        w.getJMenuItemDesconectar().addActionListener(this);
        w.getJMenuItemLimpar().addActionListener(this);
        w.getJMenuItemSair().addActionListener(this);
        
    }
    
    public void actionPerformed(ActionEvent event) { 
        // pegando a fonte do evento 
        Object source = event.getSource(); 

        if(source == w.getJMenuItemSair()) { 
            System.exit(0); 
        } else if(source == w.getJMenuItemDesconectar()) { 
            // defina aqui o quê acontece
            w.statusMenu("desconectado");
        } else if(source == w.getJMenuItemConectar()) { 
            try
            {
                worker = new SwingWorker(){
                    public Object construct(){
                        conectar();
                        return "a";
                    }
                };
                worker.start();
                w.statusMenu("conectado");
    		} catch (Exception e) {
    			w.print("Exception: " + e);
    		}                
        } else if(source == w.getJMenuItemLimpar()) {
            w.limparEventos();
        }
    }
	
    public void conectar() {

        // instancia o vetor de clientes conectados
        clientes = new Vector();
        
		try 
		{
		    s = new ServerSocket(2222);
			
			while(true){
				Socket conexao = s.accept();
				
				w.usuarioConectou(conexao.getRemoteSocketAddress().toString().substring(1));
				
			    w.print(conexao.getRemoteSocketAddress().toString().substring(1) + " - Conectou");
			    
				Thread t = new JsndServer(conexao);
				t.start();
			}
		} catch (IOException e) {
			w.print("IOException: " + e);
		}    
	}

    public Server(){
	}
	
    // construtor que recebe o socket deste cliente	
    public Server(Socket s)
	{
	    conexao = s;
	}

    // execução da thread
    public void run()
    {
        try
        {
            // objetos que permitem controlar fluxo de comunicação
            BufferedReader entrada = new BufferedReader(new InputStreamReader(conexao.getInputStream()));
            PrintStream saida = new PrintStream(conexao.getOutputStream());

            clientes.add(saida);
            
            boolean validar = true;
            
            while(validar)
            {
                usuario = conexao.getRemoteSocketAddress().toString().substring(1);
                
                send(saida, "Digite o terminal:");
                
	            // primeiramente, espera-se pelo numero do terminal
	            linha = entrada.readLine();
                
	            //	agora, verifica se string recebida é valida, pois
	            // sem a conexão foi interrompida, a string é null.
	            // Se isso ocorrer, deve-se terminar a execução.
	            if (linha == null)
	            {
	                w.print(usuario + " - Encerrou");
	                break;
	            }
	            
	            if (linha.length() == 0)
	            {
	                w.print(usuario + " - Encerrou");
	                break;
	            }
	            
	            try 
	            {
	                send(saida, linha);
	                terminal = Long.parseLong(linha);
	                
		            //Nesse ponto se valida o terminal informado. Aqui se solicita ao Servidor as informações do terminal. 
	                if (linha.length() == 15) {
	                    
	                    w.print(usuario + " - Solicitou um terminal");
	                    send(saida, "Teste solicitado. Aguarde...");
	                    
	                    Solicitar mensagem = new Solicitar();
	                    try{
	                        
	                        mensagem.enviar(terminal, usuario, w);
	                        
	                    }
	                    catch (NAWRException exc){
	                        if (exc.getMessage().indexOf("timeout") != -1) {
	                            w.print(usuario + " - Timeout!");
	                            w.acaoUsuario(usuario, "Timeout ao solicitar um terminal!\n\r");
	                            send(saida, "Timeout ao solicitar um terminal!");
	                        }
	                        else {
	                            w.print(usuario + " - Erro - " + exc.getDescripcion().toString());
	                            send(saida, "Ocorreu uma falha no servidor!");
	                        }
	                    }
	                    catch(Exception e){
	                        w.print(usuario + " - Erro - " + e.getMessage());
	                        send(saida, "Ocorreu uma falha no servidor!");
	                    }
		                
		            }
		            else{
		                send(saida, "O numero do terminal deve conter 15 digitos!");
		            }
		            
	            }
	            catch (NumberFormatException erro)
	            {
	                send(saida, "Entre com valores numericos!");
	            } 
	            
            }
            clientes.remove(saida);
            conexao.close();
            w.usuarioDesconectou(usuario);   
        }
        catch (IOException e)
        {
            // Caso ocorra alguma excessão de E/S, mostre qual foi.
            w.print("IOException: " + e);
        }
    }//final do void run

    // enviar uma mensagem para todos, menos para o próprio
    public void send(PrintStream saida, String resposta) throws IOException
    {
        Enumeration e = clientes.elements();

        while (e.hasMoreElements())
        {

            // obtém o fluxo de saída de um dos clientes
            PrintStream chat = (PrintStream) e.nextElement();

            // envia para todos, menos para o próprio usuário
            if (chat == saida)
            {
                chat.println(resposta);
            }
        }
    }

    // Parte que controla as conexões por meio de threads.
    // Note que a instanciação está no main.
    private static Vector clientes;
    
    // socket cliente
    private Socket conexao;
    
    // socket servidor
    private ServerSocket s;

    // recebe o valor digitado
    private String linha;
    
    // para validação do número
    private long terminal;
    
    // objeto gráfico
    private static Window w; 

    private SwingWorker worker;
    
    private String usuario = null;
}

Ai no meio tem umas chamadas de outras classes minhas, mas isso não vem ao caso. O que preciso eh de um jeito de fechar todas as conexões abertas.... seja fechar os Socket´s com os clientes, ou seja fechar o ServerSocket.
Quem resolver essa merece um prêmio!!!!!
8O

3 Respostas

O

cara faz isso…qndo o server tiver esperando conexao ou seja…
ServerSocket seilah = new ServerSocket(porta);
Socket seilah2 = seilah.accept(); /*vai ta esperando alguem se conectar neh…ai qndo se conectar tu pega e cria um thread…eu nem li teu codigo nao…to com preguissa da porra…mas vai ficar assim mais ou menos
*/
threadx t = new threadx(seilah2); //threadx eh o nome do construtor do thread, como paramentro tu passa o socket do cara q se conectou…!
agora tu faz o seguinte…cria um array de thread…tpw

threadx [] usuarios = new threadx[capacidade]
ou melhor…tu deve dxar esse array criado criado antes do servidor :wink:

poiseh…continuando…dps q tu cria o threadx “t” tu faz o seguinte

for (int i = 0; i < usuarios.length; i++) {

if (usuarios[i] == null)

usuarios[i] = t;

}

t.start;

//pronto ,ateh ae eh pra tu criar e tal…

ai qndo tu quiser fechar todos tu faz

for (int x  = 0; i < usuarios.length; i++) {

if (usuarios[i] != null)

usuarios[i].seilah2.close();

}

tae…hehe :stuck_out_tongue_winking_eye:

Z

Pois eh cara, solução interessante, mas não funcionou!

Ocorreu o seguinte erro;
“conexao cannot be resolved or is not a field”

quando eu digito:
usuarios[i]
e chamo os metodos desse objeto, so aparecem os metodos da thread (stop, start, etc…) e não aparece o objeto conexao (o objeto socket).

e agora?

O

seguinte vo t dah um exemplo simples entao

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

public class server {

ServerSocket ss;

Socket cliente;

publid static final int porta = 1024;

int capacidade = 10;

int id = 0;

tserver t [] = new tserver[capacidade];

public static void main(String args[]) {

try {

ss = new ServerSocket(porta);

while(true) {

System.out.println(esperando conexao…”);

cliente = ss.accept();

System.out.println(cliente+" conectou-se");

while (t[id] != null) id++;

tserver ts = new tserver(cliente, id);

t[id] = ts;

ts.start();

}

} catch(IOEXception e) { //msg de erro }

}

}

class tserver extends Thread {

Socket cliente;

int id;

tserver ( Socket cliente, int id ) {

this.cliente = cliente;

this.id = id;

}

public void run() {

 //teus comandos…

}

}

}

num testei nao…axo q vai compilar…se tu quiser fechar todos os cliente do vai na classe server e…

for (int i = 0; i < capacidade; i++)

if(t[i] != null)

t[i].cliente.close;

cara eh isso ai… nesse caso num vai retornar soh start, close, … vai retornar o Socket cliente e o inteiro q eu colokei lah de identificador…tudo q tu instanciar lah vai ser retornado…poiseh vou nessa ae…flw

Criado 1 de dezembro de 2004
Ultima resposta 2 de dez. de 2004
Respostas 3
Participantes 2