2009-08-14 4 views
1

У меня есть Java-программа, которая работает на Linux и telnets на удаленном сервере с использованием org.apache.commons.net.telnet.TelnetClient и выполняет несколько команд. Проблема в том, что он периодически переминается, когда приходит на выходной дисплей, который просит пользователей «нажимать любую клавишу, чтобы продолжить ...». Программа зависает на этом примерно 1 из каждых 10 тем, которые она запускает, и из 7 серверов, на которых я запускаю ее на только 3 из серверов есть проблемы. Кроме того, когда я запускаю ту же программу в окне окна, она работает все время.Java TelnetClient зависает при нажатии любой клавиши для продолжения.

Мне было интересно, если кто-нибудь еще столкнулся с такой проблемой?

На тестовом сервере я могу заставить его повесить каждый раз, чтобы проверить. Я попытался отправить другие команды, которые не заставят его висеть, но не повезло. Я пробовал все возвраты карьеры, фид, добавление персонажа и добавление строки. Похоже, что клиент не продолжает работать.

Забыл упомянуть, что сброс буфера, что первое, что я думал. Я поставил команду flush где-нибудь, я подумал, что это может быть проблематично.
Я также упомянул, что когда я запускаю его и смотрю вывод из строки записи, он находит «нажимать любую клавишу» и продолжает двигаться, но висит, что терминал не продолжается.

КОД ГДЕ СДЕЛАТЬ ВЫЗОВ:

 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: Read таймаут на java.net.SocketInputStream.socketRead0 (Native Method) в java.net.SocketInputStream. read (SocketInputStream.java:129) на java.io.BufferedInputStream.fill (BufferedInputStream.java:218) на java.io.BufferedInputStream.read (BufferedInputStream.java:237) на java.io.FilterInputStream.read (FilterInputStream.java:66) в java.io.PushbackInputStream.read (PushbackInputStream.java:12 2) на org.apache.commons.net.io.FromNetASCIIInputStream .__ читать (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)

ГДЕ вешает: английский 1 6000 4462 26% 13826 11056 20%

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

Нажмите любую клавишу для продолжения ....

+0

Вы используете буферизированные потоки? Возможно, кому-то нужно вызвать .flush, чтобы гарантировать, что ваши персонажи фактически переданы немедленно? – jsight

+0

Можете ли вы опубликовать фрагмент исходного кода, в котором вы выдаете команды, вызывающие зависание сервера? – ChssPly76

+0

Когда ваше приложение зависает, вы пытались получить трассировку стека (например, отправив ему сигнал kill -QUIT)? – Adamski

ответ

4

Там может быть несколько причин:

  1. Вы не промоете выход (вход удаленной команды), так «любой ключ» никогда не отправляется.

  2. Программа пытается отправить вам некоторые данные, и вы никогда не читаете свой ввод (вывод удаленной команды). Обратите внимание, что вы должны сделать это во втором потоке, так как ввод-вывод обычно происходит «одновременно», и одна сторона блокируется, если вы не справитесь с другой стороной достаточно своевременно.

  3. Возможно, у вас возникли проблемы, потому что приложение превращает терминал в режим «RAW». Но промывка вашего выхода должна исправить это:/

+0

Я посмотрел на оба эти, и я смываю свой буфер. (много раз и во многих местах). Я также искал дополнительный текст, но не видел. – Ben