Sockets + Thread... ajuda!

1 resposta
J

Pessoal, to com uma dúvida que me ocupou o dia todo… mesmo procurando nos milhares de tópicos sobre o assunto não encontrei uma solução.

Bom vamos lá… fiz uma simplória aplicação com sockets (cliente / server) onde ao se conectar com o server eu mantenho o socket aberto até que alguma das pontas se desconecte.
A troca de informação entre eles está perfeita… ambos recebendo e enviando normalmente.

Tanto o server quanto o cliente possuem cada um uma thread que ficam escutando os streams enviados um pelo outro, quando aciono o botão do CLIENTE para fechar a conexão (que ainda só implementei no lado do cliente), ele envia uma simples string que o server irá identificar como um encerramento, após isso o CLIENTE tem que:

1 - Encerrar a thread que fica escutando o server.
2 - Encerrar a conexão.

Segue meu problema:

THREAD QUE FICA LENDO AS ENTRADAS VINDAS DO SERVER.

@Override
    public void run() 
    {
        try 
        {
            //pega o streams do server
             retorno = new InputStreamReader(clientSocket.getInputStream());
             bufferedReader = new BufferedReader(retorno);
        } 
        catch (IOException ex) 
        {
            System.out.println(ex);
        }
        
            //escuta os streams ate que a thread seja interropmpida
            while(!Thread.currentThread().isInterrupted())
            {
                try
                {   
                    //simplesmente adiciona o que vier do lado do server num JTextArea
                    //#### ESSA LINHA LANCA A EXCECAO:
                    // java.net.SocketException: socket closed
                    textArea.setText(textArea.getText().concat(bufferedReader.readLine()+"\n"));
                }
                catch(IOException e)
                {
                    System.out.println(e);
                }
            }
            
        System.out.println("(ENCERRANDO A THREAD)");
    }

METODO DE OUTRA CLASSE QUE ENCERRA A THREAD (ACIONADA ATRAVÉS DO BUTTON)

public void desconecta()
    {
        try 
        {
            
            thread.interrupt();
           
            while(!thread.isAlive())
                System.out.println("AGUARDANDO THREAD MORRER...");
            
            socket.close();
        } 
        catch (IOException ex) 
        {
            Logger.getLogger(MyClientForm.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

Ela encerra a conexao e a thread, mas antes disso ela lanca a execessao

java.net.SocketException: socket closed

antes de encerrar a conexão.

como eu faço para que a thread seja encerrada antes de encerrar a conexao do socket ?
ou qual seria a maneira correta de fazer o encerramento da thread e socket ?

Ja tentei de varias maneiras matar essa thread, mas todas dão no mesmo resultado !

1 Resposta

J

Bom pessoal depois de de passar o dia todo tentanto resolver... eu acabei encontrando...

O problema não eram as thread e sockets em si, mas sim o BufferedReader que ultiliza o readLine()... qu é um metodo blocante... ele estava segurando a execucao da thread. o problema foi resolvido alterando as seguintes linhas:
while(!Thread.currentThread().isInterrupted())
            {
                try
                {   
                    
                    //simplesmente verificando se há algum stream vindo do server, isso irá carregar o buff e permitir
                    //ulitilizar para a manipulacao das strings, caso contrario ele apenas continua verificando
                    if(bufferedReader.ready())
                    {
                        textString=bufferedReader.readLine();

                        if(textString.startsWith("SERVER"))
                        {
                            textString = textString.replace("SERVER", "CLIENTE:\n");
                            textArea.setText(textArea.getText().concat(textString+"\n"));
                        }
                        else
                            textArea.setText(textArea.getText().concat("SERVER:\n"+textString+"\n"));
                        }
                }
                catch(IOException e)
                {
                    System.out.println(e);
                }
            }

apesar de ninguem ter ajudado :( fica ai para quem um dia precisar !
Abraços

Criado 21 de fevereiro de 2013
Ultima resposta 22 de fev. de 2013
Respostas 1
Participantes 1