2009-08-14 39 views
1

我有一个Java程序在Linux和Telnet上运行到使用org.apache.commons.net.telnet.TelnetClient的远程服务器并执行一些命令。问题在于,当它到达一个输出显示,并要求用户“按任意键继续...”时,它会间歇性地挂起。程序在每运行10次,每运行10次,运行它的7台服务器中就有1次挂起只有3台服务器有问题。另外,当我在Windows盒子上运行相同的程序时,它一直都在运行。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(); 
    } 
} 

堆栈跟踪:java.net.SocketTimeoutException:阅读java.net.SocketInputStream.socketRead0(本机方法) 超时 在java.net.SocketInputStream。在java.io.BufferedInputStream.fill(BufferedInputStream.java:218) 处读取(SocketInputStream.java:129) at java.io.BufferedInputStream.read(BufferedInputStream.java:237) at java.io.FilterInputStream.read( FilterInputStream.java:66) at java.io.PushbackInputStream.read(PushbackInputStream.java:12 2) at org.apache.commons.net.io.FromNetASCIIInputStream .__ read(FromNetASCIIInputStream.java:77) at org.apache.commons.net.io.FromNetASCIIInputStream.read(FromNetASCIIInputStream.java:175) at java。 (BufferedInputStream.java:218) at java.io.BufferedInputStream.read 在org.apache.commons.net.telnet.TelnetInputStream.run(TelnetInputStream.java:564) 在java.lang.Thread.run(Thread.java:619)

WHERE它挂起: 英语1 6000 4462 26%13826 11056 20%

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

按任意键继续....

+0

你使用缓冲流吗?也许有些人需要调用.flush来确保你的角色实际上是立即传输的? – jsight 2009-08-14 15:10:25

+0

你可以发布你的源代码的一个片段,你发布导致服务器挂起的命令吗? – ChssPly76 2009-08-14 15:24:08

+0

当您的应用程序挂起时,您是否尝试获取堆栈跟踪(例如,通过发送一个kill -QUIT信号)? – Adamski 2009-08-14 15:26:06

回答

4

可能有几个原因:

  1. 你不冲水的输出(远程命令的输入),所以“任何密钥”都不会被发送。

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

  3. 也许你遇到问题,因为应用程序将终端转换为“RAW模式”。但冲洗你的输出应该可以解决这个问题:/

+0

我已经看过这两个,我正在冲洗我的缓冲区。 (很多次,在许多地方)。我也寻找额外的文字,但没有看到任何。 – Ben 2009-09-11 17:37:06

相关问题