【问题标题】:Java TelnetClient hangs at “press any key to continue”Java TelnetClient 在“按任意键继续”时挂起
【发布时间】:2009-08-14 14:57:05
【问题描述】:

我有一个在 Linux 上运行的 Java 程序,并使用 org.apache.commons.net.telnet.TelnetClient 远程登录到远程服务器并执行一些命令。问题是,当它到达一个要求用户“按任意键继续……”的输出显示时,它会间歇性挂起只有 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();
    }
}

StackTrace:java.net.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.__read(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

按任意键继续....

【问题讨论】:

  • 你在使用缓冲流吗?也许有些人需要调用 .flush 来确保您的字符实际上是立即传输的?
  • 您可以在您发出导致服务器挂起的命令的地方发布您的源代码片段吗?
  • 当您的应用挂起时,您是否尝试过获取堆栈跟踪(例如,通过向其发送 kill -QUIT 信号)?

标签: java apache-commons expect


【解决方案1】:

可能有几个原因:

  1. 您没有刷新输出(远程命令的输入),因此永远不会发送“任意键”。

  2. 程序试图向您发送一些数据,但您从未读取过您的输入(远程命令的输出)。请注意,您必须在第二个线程中执行此操作,因为 I/O 通常“同时”发生,如果您没有足够及时地处理另一端,则一侧会阻塞。

  3. 您可能会遇到问题,因为应用程序将终端设置为“RAW 模式”。但是刷新你的输出应该可以解决这个问题:/

【讨论】:

  • 我已经看了这两个,我正在刷新我的缓冲区。 (很多次和很多地方)。我还查找了其他文本,但没有看到任何内容。
猜你喜欢
  • 2013-11-10
  • 2015-01-23
  • 2020-08-10
  • 1970-01-01
  • 1970-01-01
  • 2011-12-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多