Onde estou errando nessa thread?

Galera,

Estou com o seguinte problema nas minhas Thrads.

Inicia a minha aplicação

  PonteEntreThread ponteEntreThread = new PonteEntreThread();

            ServidorDoGerenteDeEquipamento servidorDoGerenteDeEquipamento = new ServidorDoGerenteDeEquipamento(new Integer(mileSegundosGerenciaSocket), ponteEntreThread);
            Thread thread = new Thread(servidorDoGerenteDeEquipamento);
            thread.start();
            //Criar o servidor de socket aqui
            SViasLogger.logInfo(">> Subindo servidor socket");
            String porta = LerProperties.getValor("porta_servidor_gatway");
            SViasLogger.logInfo(">>Servidor socket ouvindo na porta: " + porta);
            ServerSocket serverSocket = new ServerSocket(new Integer(porta));
            SViasLogger.logInfo(">> Servidor aguardando conexão.");
            while (true) {
                Socket socket = serverSocket.accept();
                SViasLogger.logInfo(">> Mais um equipamento atendido.");
                try {
                    ServidorSocket servidorSocket = new ServidorSocket(ponteEntreThread, socket);
                    Thread thread2 = new Thread(servidorSocket);
                    thread2.start();
                } catch (Exception e) {
                    SViasLogger.logError("Principal-main", e);
                }
            }

Classe que gerencia os equipamentos conectados - essa que é o PROBLEMA, jaja vou explicar.

public class ServidorDoGerenteDeEquipamento implements Runnable {

    private PonteEntreThread ponteEntreThread;
    private long tempoDoSleep;

    public ServidorDoGerenteDeEquipamento(long tempo, PonteEntreThread ponte) {
        ponteEntreThread = ponte;
        tempoDoSleep = tempo;
    }

    private void gerenciarConexoesDosEquipamentos() {
        SViasLogger.logInfo(">> Aguardando Trabalho!");
        List<SocketSVias> listaSocketSVias = Collections.synchronizedList(new ArrayList<SocketSVias>(ponteEntreThread.pegarListaDeSocketSVias()));
        SViasLogger.logInfo(">> Pegando Lista de Conexoes. Tamanho da Lista: " + listaSocketSVias.size());
        synchronized (listaSocketSVias) {
            for (SocketSVias socketSVias : listaSocketSVias) {
                GerenciaSocket gerenciaSocket = new GerenciaSocket(socketSVias);
                Thread thread = new Thread(gerenciaSocket);
                thread.start();
            }
        }
    }

    public void run() {
        while (true) {
            try {
                gerenciarConexoesDosEquipamentos();
                Thread.sleep(tempoDoSleep);
            } catch (Exception e) {
                SViasLogger.logError("ServidorDoGerenteDeEquipamento-run", e);
            }
        }
    }
}

Classe que pega os meus equipamentos que conectaram e faz uma primeira validação dos equipamentos.


public class ServidorSocket implements Runnable {

    private PonteEntreThread ponteEntreThread;
    private Socket socket;

    public ServidorSocket(PonteEntreThread pet, Socket s) {
        ponteEntreThread = pet;
        socket = s;
    }

    private void servidorSocket() throws SViasException, InterruptedException, IOException {

        SViasLogger.logInfo(">>Equipamento Conectado, buscando os primeiros dados do equipamento.");
        String dadosRecebidosDoEquipamento = lerOsDadosDoEquipamentoConectado(socket);
        SViasLogger.logInfo(">>Dados do equipamento conectado:" + dadosRecebidosDoEquipamento);
        String imei = EquipamentoUtil.adquiriImeiEquipamentoConectado(dadosRecebidosDoEquipamento);
        if ("".equalsIgnoreCase(imei)) {
            return;
        }
        SViasLogger.logInfo(">>Equipamento de imei: " + imei + " conectado no servidor.");


        SocketSVias socketSVias = new SocketSVias(socket, "semcomando", imei);

        //buscar lista de equipamentos
        List<SocketSVias> lista = ponteEntreThread.pegarListaDeSocketSVias();
        if (lista.contains(socketSVias)) {
            SViasLogger.logInfo(">>Equipamento de imei: " + imei + " sendo validado, removido e inserido novamente na lista");
            int index = lista.indexOf(socketSVias);
            lista.remove(index);
            lista.add(socketSVias);

        } else {
            SViasLogger.logInfo(">>Equipamento de imei: " + imei + " sendo inserido na lista");
            lista.add(socketSVias);
        }

        SViasLogger.logInfo(">>Equipamento de imei: " + imei + " Validado na lista.");
    }

    public void run() {
        try {
            servidorSocket();
        } catch (Exception ex) {
            SViasLogger.logError("ServidorSocket-run", ex);
        }
    }

    private String lerOsDadosDoEquipamentoConectado(Socket cliente) throws SViasException, IOException {
        InputStream in = null;

        in = cliente.getInputStream();
        byte[] buffer = new byte[1024];
        int i = in.read(buffer);
        String retorno = new String(buffer);
        return retorno;

    }
}

por fim tenho uma classe que denominei PonteEntreThread, essa classe possui uma lista dos equipamentos que estao conectados na minha aplicação.

public class PonteEntreThread {

    private List<SocketSVias> lista = new ArrayList<SocketSVias>();

    public synchronized List<SocketSVias> pegarListaDeSocketSVias() {
        return lista;
    }

    public synchronized void setarEquipamentosConectados(SocketSVias socketSVias) {
        lista.add(socketSVias);
    }
}

Entao galera, a classe ServidorDoGerenteDeEquipamento do nada para de funcionar, as outras thread’s continuam funcionando normalmente, ja esse cara que eu citei para de funcionar, não da erro, nada, simplesmente para.
O meu aplicativo esta em testes no cliente, fica no maximo 2 dias sem ser preciso reiniciar, passa um periodo maior ocorre o erro acima.

Onde estou errando nessas logicas minha?

Att


    public class ServidorDoGerenteDeEquipamento implements Runnable {  
      
        private PonteEntreThread ponteEntreThread;  
        private long tempoDoSleep;  
      
        public ServidorDoGerenteDeEquipamento(long tempo, PonteEntreThread ponte) {  
            ponteEntreThread = ponte;  
            tempoDoSleep = tempo;  
        }  
      
        private void gerenciarConexoesDosEquipamentos() {  
            SViasLogger.logInfo(">> Aguardando Trabalho!");  
            List<SocketSVias> listaSocketSVias = Collections.synchronizedList(new ArrayList<SocketSVias>(ponteEntreThread.pegarListaDeSocketSVias()));  
            SViasLogger.logInfo(">> Pegando Lista de Conexoes. Tamanho da Lista: " + listaSocketSVias.size());  
            synchronized (listaSocketSVias) {  
                for (SocketSVias socketSVias : listaSocketSVias) {  
                    GerenciaSocket gerenciaSocket = new GerenciaSocket(socketSVias);  
                    Thread thread = new Thread(gerenciaSocket);  
                    thread.start();  
                }  
            }  
        }  
      
        public void run() {  
            while (true) {  
                try {  
                    gerenciarConexoesDosEquipamentos();  
                    Thread.sleep(tempoDoSleep);  
                } catch (Exception e) {  
                    SViasLogger.logError("ServidorDoGerenteDeEquipamento-run", e);  
                }  
            }  
        }  
    }  

na linha 27 vc esta chamando o metodo gerenciarConexoesDosEquipamentos(), a pergunta é vc não esta criando varias threads desnecessárias ?? porque a lógica seria uma thread para gerenciar cada socket. Aquele "for " da linha 16 parece que a cada passada por ele cria uma thread.

sds

j.silvestre

Pode ser que aconteça algo de errado na conexão e que termine a sua socket.

Já pensou eu fazer um código que detecte que sua socket está fechada, e reacbra ela novamente? Pode ajudar com o problema

[quote=j.silvestre]


    public class ServidorDoGerenteDeEquipamento implements Runnable {  
      
        private PonteEntreThread ponteEntreThread;  
        private long tempoDoSleep;  
      
        public ServidorDoGerenteDeEquipamento(long tempo, PonteEntreThread ponte) {  
            ponteEntreThread = ponte;  
            tempoDoSleep = tempo;  
        }  
      
        private void gerenciarConexoesDosEquipamentos() {  
            SViasLogger.logInfo(">> Aguardando Trabalho!");  
            List<SocketSVias> listaSocketSVias = Collections.synchronizedList(new ArrayList<SocketSVias>(ponteEntreThread.pegarListaDeSocketSVias()));  
            SViasLogger.logInfo(">> Pegando Lista de Conexoes. Tamanho da Lista: " + listaSocketSVias.size());  
            synchronized (listaSocketSVias) {  
                for (SocketSVias socketSVias : listaSocketSVias) {  
                    GerenciaSocket gerenciaSocket = new GerenciaSocket(socketSVias);  
                    Thread thread = new Thread(gerenciaSocket);  
                    thread.start();  
                }  
            }  
        }  
      
        public void run() {  
            while (true) {  
                try {  
                    gerenciarConexoesDosEquipamentos();  
                    Thread.sleep(tempoDoSleep);  
                } catch (Exception e) {  
                    SViasLogger.logError("ServidorDoGerenteDeEquipamento-run", e);  
                }  
            }  
        }  
    }  

na linha 27 vc esta chamando o metodo gerenciarConexoesDosEquipamentos(), a pergunta é vc não esta criando varias threads desnecessárias ?? porque a lógica seria uma thread para gerenciar cada socket. Aquele "for " da linha 16 parece que a cada passada por ele cria uma thread.

sds

j.silvestre[/quote]

Respondendo as duas perguntas.

Eu fiz esse for justamente por causa da perda da conexão, abro threads dentro do for, para que caso ocorra algum problema em alguma thread, esse erro fique isolado dessa determinada thread e nao mate o resto do meu programa.

Pq seria muito mais facil eu pegar a conexao fazer o que eu tenho que fazer e desconectar, mas o meu chefe quer que eu pegue todas as conexoes e armazena em uma lista e fique lendo essas conexoes de tempo em tempo.

Entenderam?

O seguinte vc tem que ficar monitorando as conexões, se estiverem ok, então tudo bem, mas se ela tiver caido(exception) vc tem que dar um close nela antes de abrir de novo.


conexão.close();

tem que fechar também o InputStream in


in.close()

depois abrir tudo de volta.

vc esta fazendo isso ??

eu fiz um servidor estes tempos dá uma olhada no código ve se te ajuda.



import java.util.ArrayList;
import java.io.*;
import java.net.*;
import serialjava.*;
class ClientWorker extends SocketThrdServer implements Runnable { // a classe implementa runnable
  private Socket client;
  private String clienteS="";
  private String guiche;


    public ClientWorker() {
    }
 // private JTextArea textArea;
  
  ClientWorker(Socket client) {
   this.client = client;
   clienteS = getClientS();

  }
   public String getClientS(){
   String S;
   S = client.getInetAddress().getHostAddress();
   return S;

   }

  public void run(){ //  segmento a ser executado
    String line;
    BufferedReader in = null;
    PrintWriter out = null;
    try{
      in = new BufferedReader(new InputStreamReader(client.getInputStream()));
      out = new PrintWriter(client.getOutputStream(), true);
    } catch (IOException e) {
      System.out.println("in or out failed");
      System.exit(-1);
    }

    while(true){
         
      try{
        line = in.readLine();
//Send data back to client
        int num = 0;
       // System.out.println(line); // debug
        try{
        String SA = line.substring(0,6);
        }catch(NullPointerException e){} // não faz nada só para não ocorrer
                                         // exception

         //System.out.println(" o numero do guiche é :  " + SA); dbg
        if(line.substring(0,6).equals("GUICHE")){
         num = 1;
        guiche = line.substring(6,9);
       // System.out.println(" o numero do guiche é :  " + guiche); dbg
       lerEscreverBuffer(guiche); // herança da classe SocketThrdServer //
        out.println("TRANSMISSAO OK");
        }

        if(line.equals("HANDSHAKE")){
        num = 1;
        out.println("HANDSHAKEOK");
       // System.out.println("HANDSHAKEOK");
       

        }
        if(line.equals("cliente1")){
         num = 1;
         out.println("****" + line + " " + client.getInetAddress());
         System.out.println("****" + line + " " + client.getInetAddress());
        }
         if(line.equals("cliente2")){
          num = 1;
         out.println("#####" + line + " " + client.getInetAddress());
        
        }
       if(num == 0){
       
        System.out.println("DADOS INVALIDOS");
       out.println("Dados invalidos" + client.getInetAddress());
       }
      
        
       } catch (IOException e) {
         System.out.println("Read failed");
         try{
        System.out.println("Fechando a conexão com : " +  clienteS);
         in.close();
         out.close();
         client.close();

         }catch(IOException EE)
         {break;}
          break; // sai da e finaliza a Thread
       }
    }
  }// fim do metodo run
} //fim da classe ClienteWorker


/***********************************************************************************/
/*                                                                                 */
/***********************************************************************************/
class SocketThrdServer { // classe interna
   static  ArrayList<String> bufferGuicheWR = new ArrayList<String>();
//   ClientWorker cliente = new ClientWorker();

   ServerSocket server = null;
   static int a = 0;
   SocketThrdServer(){ //Begin Constructor
   super();
  

   } //End Constructor

  public void listenSocket(){

   ReadBuffer z;
   z = new ReadBuffer();
    Thread read = new Thread(z);
       read.start();
         a = Thread.activeCount(); //dbg
        System.out.println("Threads ativas " + a);//dbg
    try{
      server = new ServerSocket(4444,10); // no maximo 10 conexões
    } catch (IOException e) {
      System.out.println("Could not listen on port 4444");
      System.exit(-1);
    }
    while(true){
      ClientWorker w;
      //ReadBuffer z;
      try{
        w = new ClientWorker(server.accept()); // a cada solicitação de sockts
       // z = new ReadBuffer();
       System.out.println(w. getClientS()); // imprime o endereço ip conectado ao srver
        Thread t = new Thread(w);                        // cria uma nova instancia de Client Worker
        t.start();
        
        //Thread read = new Thread(z);
        //read.start();
        a = Thread.activeCount();
        System.out.println("Threads ativas " + a);
      } catch (IOException e) {
        System.out.println("Accept failed: 4444");
        System.exit(-1);
      }
    }
  }

    @Override
  protected void finalize(){
//Objects created in run method are finalized when 
//program terminates and thread exits
     try{
        server.close();
    } catch (IOException e) {
        System.out.println("Could not close socket");
        System.exit(-1);
    }
  }

  public synchronized  String lerEscreverBuffer(String S){


if( S.equals("LER"))
{
  
  if(!bufferGuicheWR.isEmpty()){
 // System.out.println("lendo buffer") ;// dbg
   String retorno = bufferGuicheWR.get(0);
 //  System.out.println(" buffer = " + retorno);
 // for(String l : bufferGuicheWR) //dbg
 // System.out.println("IMPRIMINDO BUFFER :" + bufferGuicheWR );//dbg

  bufferGuicheWR.remove(0);
  return retorno;
  }
}
if( !S.equals("LER")){
// System.out.println("tem buffer") ;// dbg
  bufferGuicheWR.add(S);
 // System.out.println("Salvando buffer");
return null;
}
return null;
}

}

class ReadBuffer  extends SocketThrdServer  implements Runnable{
//instanciar classe SerialConnection pattern singleton
SerialConnection con =  SerialConnection.getInstance(SerialParameters.getInstance2());

public void run(){


 
while(true){
 try{
 Thread.sleep(1000);
 }catch(InterruptedException ex ){ ex.printStackTrace();}
 //System.out.println("Thread");

 String B = lerEscreverBuffer("LER"); // herança classe SocketThrdServer//
 //System.out.println(" o buffer** :" + B); //dbg
 if( B != null){
 System.out.println("imprimindo na serial : " + B);
 con.enviarMensagem(B); // envia string para a serial
 }
}


}

}

sds

j.silvestre

Endendi.

Vou ver aqui na minha aplicação.

att