2009-11-04 9 views
0

Serverapp Java Socket arrêter au hasard

public void run() { 

Socket serversocket = new ServerSocket(port); 
while(true) { 
    new Thread(new ServerThread(serverSocket.accept())).start(); 
} 
} 
//serverSocket.close(); etc 

de ServerThread

public void run() { 
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); 

String input; 

while(true) { 
    input = in.readLine(); 
    new Thread(new RequestThread(clientSocket, input)).start(); 
} 
} 
//close sockets etc in.close() clientSocket.close(); 

Demande de fil

public void run() { 
//input was passed from constructor 
String output = new SomeProtocol(input); 

if(output == null) 
    break; 
//true for auto flush 
PrintWriter out = new PrintWriter(socket.getOutputStream(), true); 
out.println(output); 
}//closing out seems to also close the socket, so opted to not to close it, maybe this is the one giving me trouble? 

Moniteur

public class ServerMonitor implements Runnable{ 
    private ServerThread server; 
    private LoggingClass log = LoggingClass .getInstance(); 
    private int heartbeat = 0; 

    public ServerMonitor(ServerThread server) { 
     this.server = server; 
    } 

    public boolean checkFile() { 
     File file = new File("cmd//in//shutdown.txt"); 
     return file.exists(); 
    } 

    public void run() { 

     log.logToFile("Server monitor running"); 

     while (true) { 
      incHeartbeat(); 
      if (checkFile()) { 
       log.logToFile("Shutting down server"); 
       break; 
      } 
      writeStatus(); 
      this.delay(5000); 
     } 

     log.logToFile("Server monitor stopped"); 
    } 

    public void delay(long delay) { 
     try { 
      wait(delay); 
     } catch (InterruptedException e) { 
      log.logToFile("Monitor sleep error"); 
      e.printStackTrace(); 
     } 
    } 

    public void writeStatus() { 
     try { 
      BufferedWriter out = new BufferedWriter(new FileWriter(
        "sys//status//status.txt")); 
      out.write("Start date:" + log.getStartDate()); 
      out.newLine(); 
      out.write("Current date:" + log.getTimestamp("yyyy-MMM-dd k:mm:ss")); 
      out.newLine(); 
      out.write("Heartbeat:" + getHeartbeat()); 
      out.newLine(); 
      out.write("Cimd in:" + log.getCimdIn()); 
      out.newLine(); 
      out.write("Cimd out:" + log.getCimdOut()); 
      out.newLine(); 
      out.write("Keep alive:" + log.getCimdKeepAlive()); 
      out.newLine(); 
      out.write("HTTP in:" + log.getNumHTTPIn()); 
      out.newLine(); 
      out.write("HTTP out:" + log.getNumHTTPOut()); 
      out.newLine(); 
      out.close(); 

     } catch (Exception e) { 
      log.logToFile("Write status error"); 
      e.printStackTrace(); 
     } 
    } 

    public int getHeartbeat() { 
     return heartbeat; 
    } 

    public synchronized void incHeartbeat() { 
     heartbeat++; 
    } 
} 

Ceci est le squelette rugueux de mon application. J'ai des problèmes car parfois ça s'arrête sans aucune erreur. Je soupçonne que c'est peut-être à cause des prises, mais je ne suis pas sûr que quelqu'un d'entre vous ait des idées? Merci.


Ajout de ma classe qui surveille les threads du serveur

>How do I know that it doesn't work 

Heartbeat n'incrémente pas plus

+0

Je n'ai aucune idée de ce qu'est le problème, mais je suggère que vous ajoutiez une connexion pour vous aider à voir ce que fait l'application quand elle s'arrête. –

+0

Combien de temps cela prend-il pour l'arrêt? – OscarRyz

+0

aléatoire, parfois il dure des jours, parfois il ne dure même pas une heure – lemon

Répondre

1

Vous pouvez exécuter de mémoire/fils

Est-ce que vous arrive d'avoir certaines exceptions de niveau élevé de gestion comme ceci:

public static void main(String ... args) { 
    try { 
     // lots of code ... 
    } catch(Exception e) {} 
} 

Si oui, vous devez au moins enregistrer les erreurs que vous ignorez.

C'est ce qui me vient à l'esprit car je n'ai pas votre code source sous la main.

+0

Yup, j'ai cela. Mais ça ne montre rien, la chose s'arrête. – lemon

+0

:-) Si vous le faites, retirez-le juste pour l'instant, et voyez ce qui se passe. Ou au moins faites-le 'catch (Exception e) {e.printStackTrace(); } 'Attraper toutes les exceptions n'est pas une bonne idée. Vous devriez attraper ce que vous attendez. Ou au moins connectez-vous ce qui se passe. – OscarRyz

+0

Il ne montre rien parce que vous ignorez les exceptions. – OscarRyz

0

Pourriez-vous mieux définir «arrête de travailler»? Est-ce que ça cesse d'accepter la connexion? Est-ce que ça plante? Est-ce qu'il arrête de faire quelque chose en cours de traitement? etc? Un peu de spéculation est que je ne suis pas certain de ce qui se passera dans le lecteur quand une prise est fermée. Ce que je m'attendrais à ce que j'essaie de faire est d'essayer d'appeler une ligne de lecture avec un socket fermé, ce qui provoquerait une exception, qui stopperait ce thread, et/ou tuerait l'application entière. Ce qui générerait une trace de pile, et d'autres problèmes. Fondamentalement, en plus de ce qu'Oscar a dit à propos de la journalisation des exceptions dans main; vous voudriez vous connecter à n'importe quelle méthode run(). Un try/catch dans main n'accepterait que les exceptions lancées par le thread principal; pas ceux qui sont jetés dans d'autres fils.

+0

okay, j'ai ajouté comment je sais pourquoi il arrête de travailler sur mon poste. – lemon

0

Il est difficile de dire à partir du pseudo-code que vous avez posté, mais si l'application est suspendue (et ne plante pas complètement) ma meilleure estimation est que in.readLine() dans ServerThread bloque. Si l'application s'arrête juste, je regarderais les fermetures de socket et peut-être vérifier isReady() dans votre BufferedReader.

Un commentaire général: vous générez peut-être plus de threads que nécessaire ici. Cela ressemble à la lecture de la socket client et l'écriture s'y fait en série. Si c'est le cas, le ServerThread Runnable (je suppose que c'est un Runnable puisque vous le passez au constructeur d'un Thread) n'a pas nécessairement besoin de générer un RequestThread.

public class ServerRunnable implements Runnable { 
    ... 

    public void run() { 
     BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); 

     String input; 

     while(true) 
     { 
      input = in.readLine(); 
      if(input == null) 
      { 
       //this means the underlying socket closed 
       //log something here or return or whatever 
      } 

      String output = new SomeProtocol(input); 

      if(output == null) 
      break; 
      //true for auto flush 
      PrintWriter out = new PrintWriter(socket.getOutputStream(), true); 
      out.println(output); 
     } 
    } 
    ... 
} 
+0

C'est ce que j'ai fait sur la version précédente, ça s'arrêtait toujours. – lemon

+0

Oh et pense au serveur en tant que répartiteur, chaque chaîne fait sa propre chose, c'est pourquoi j'ai fait un nouveau thread pour chaque demande. Devrais-je revenir à sa version précédente? – lemon

+0

Addendum: Je doute qu'il soit bloqué dans in.readLine() puisque le rythme cardiaque du thread du moniteur s'arrête avec lui (cela ne devrait pas arriver puisque c'est un thread différent). Fermeture de socket: Je ferme correctement J'ai même mon enregistrement de journal lorsque le thread s'arrête mais quand il se bloque, je ne vois pas en train de consigner tout ce qu'il s'arrête. (Pensez-y comme quelqu'un a tué votre programme en cours d'exécution) – lemon