2009-08-14 5 views
1

J'ai un programme Java qui s'exécute sur Linux et telnets dans un serveur distant en utilisant org.apache.commons.net.telnet.TelnetClient et exécute quelques commandes. Le problème est qu'il se bloque par intermittence quand il arrive à un affichage de sortie qui demande aux utilisateurs «d'appuyer sur n'importe quelle touche pour continuer ...» Le programme se bloque à peu près 1 fois sur 10 et sur les 7 serveurs que je le lance sur seulement 3 des serveurs ont des problèmes. Aussi, quand je cours le même programme sur une boîte de Windows il fonctionne tout le temps.Java TelnetClient se bloque à "appuyez sur n'importe quelle touche pour continuer"

Je me demandais si quelqu'un d'autre a rencontré un problème comme celui-ci?

Sur un serveur de test, je peux l'obtenir à chaque fois pour tester. J'ai essayé d'envoyer d'autres commandes qui ne le feront pas tomber mais pas de chance. J'ai essayé tout le retour de carrage, le saut de ligne, l'ajout d'un personnage et la mise en ligne. Rien ne semble faire que le client continue.

Oublié de mentionner que rinçage du tampon quelle était la première chose que je pensais. J'ai mis la commande flush partout où je pensais que ça pourrait aller.
Je mentionnerai également que lorsque je l'exécute et que je regarde la sortie de la ligne d'écriture, il trouve le "appuyez sur n'importe quelle touche" et continue mais bloque le terminal ne continue pas.

CODE OÙ JE FAIS APPEL:

 readUntil("X) Exit (no report)"); 
     write("C", false); 
     out.flush(); 

     readUntil("continue...."); 

     // write this for all servers. 
     write("", true); 
     out.flush(); 

     readUntil("X) Exit"); 
     write("X", false); 


/* 
* This method is used to read the command line until the pattern that was 
* passed in is found. 
*/ 
public String readUntil(String pattern) throws Exception { 
    try { 
     String tempString; 
     char lastChar = pattern.charAt(pattern.length() - 1); 
     StringBuffer sb = new StringBuffer(); 
     //boolean found = false; 
     char ch = (char) in.read(); 
     while (true) 
     { 
      // NOTE: Turn line below on to watch the program perform the telnet 
      System.out.print(ch); 

      sb.append(ch); 
      tempString = sb.toString(); 
      if (ch == lastChar) { 
       if (tempString.endsWith(pattern)) 
       { 
        // log to file 
        logFileWriter.write(tempString); 
        logFileWriter.flush(); 
        return tempString; 
       } 
      } 
      ch = (char) in.read(); 
     } 
    } 
    catch (Exception e) { 
     e.printStackTrace(); 
     throw e; 
    } 
} 

/* 
* writes the String passed in to the command line. 
* boolean userWriteln: true - use the return key after the command, false - just type the 
* command with NO enter key 
*/ 
public void write(String value, boolean useWriteln) 
{ 

    System.out.println("WRITTING '" + value + "'"); 

    try { 
     if (useWriteln) 
     { 
      out.println(value); 
     } 
     else 
     { 
      out.print(value); 
     } 
     out.flush(); 
     System.out.println(value); 
    } 
    catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 

StackTrace: java.net.SocketTimeoutException: Lire a expiré à java.net.SocketInputStream.socketRead0 (Native Method) à java.net.SocketInputStream. lire (SocketInputStream.java:129) à java.io.BufferedInputStream.fill (BufferedInputStream.java:218) à java.io.BufferedInputStream.read (BufferedInputStream.java:237) à java.io.FilterInputStream.read (FilterInputStream.java:66) at java.io.PushbackInputStream.read (PushbackInputStream.java:12 2) à org.apache.commons.net.io.FromNetASCIIInputStream .__ lecture (FromNetASCIIInputStream.java:77) à org.apache.commons.net.io.FromNetASCIIInputStream.read (FromNetASCIIInputStream.java:175) à java. io.BufferedInputStream.fill (BufferedInputStream.java:218) à java.io.BufferedInputStream.read (BufferedInputStream.java:237) à org.apache.commons.net.telnet.TelnetInputStream .__ read (TelnetInputStream.java:122) à org.apache.commons.net.telnet.TelnetInputStream.run (TelnetInputStream.java:564) à java.lang.Thread.run (Thread.java:619)

OÙ il se bloque: anglais 1 6000 4462 26% 13826 11056 20%

Calls answered since Thu Jun 4, 2009 3:11 am: 41245 

Appuyez sur une touche pour continuer ....

+0

Utilisez-vous des flux tamponnés? Peut-être que certains ont besoin d'appeler .flush pour s'assurer que vos personnages sont effectivement transmis immédiatement? – jsight

+0

Pouvez-vous publier un fragment de votre code source sur lequel vous envoyez les commandes provoquant le blocage du serveur? – ChssPly76

+0

Lorsque votre application se bloque, avez-vous essayé d'obtenir une trace de pile (par exemple en lui envoyant un signal kill -QUIT)? – Adamski

Répondre

4

Il pourrait y avoir plusieurs raisons:

  1. Vous n'êtes pas rinçage de votre sortie (l'entrée de la commande à distance), de sorte la "n'importe quelle clé" n'est jamais envoyée.

  2. Le programme essaie de vous envoyer des données et vous ne lisez jamais votre entrée (la sortie de la commande à distance). Notez que vous devez le faire dans un deuxième thread car l'E/S se produit généralement "en même temps" et un côté bloquera si vous ne manipulez pas l'autre côté assez rapidement.

  3. Peut-être que vous rencontrez un problème car l'application transforme le terminal en "mode RAW". Mais vider votre sortie devrait corriger cela:/

+0

J'ai regardé les deux et je suis en train de rincer mon tampon. (plusieurs fois et dans de nombreux endroits). J'ai aussi cherché du texte supplémentaire mais je n'en ai vu aucun. – Ben

Questions connexes