Java TelnetClient зависает при “нажмите любую клавишу, чтобы продолжить”

StackOverflow https://stackoverflow.com/questions/1278364

  •  16-09-2019
  •  | 
  •  

Вопрос

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

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

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

Забыл упомянуть, что очистка буфера - это первое, о чем я подумал.Я поместил команду 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();
    }
}

Отслеживание стека:Ява.нет.SocketTimeoutException:Время ожидания чтения истекло в java.net.SocketInputStream.socketRead0 (собственный метод) в 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:122) в 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.__читать (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

Нажмите любую клавишу, чтобы продолжить....

Это было полезно?

Решение

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

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

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

  3. Возможно, у вас возникла проблема из-за того, что приложение переводит терминал в "НЕОБРАБОТАННЫЙ режим".Но очистка вашего вывода должна исправить это :/

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top