我正在使用 Apache Commons TelnetClient 为某些交换机创建自动 telnet 界面。如果我直接从机器远程登录到交换机,连接似乎永远不会超时。随机地,在Java程序中,连接似乎与InputStream一起立即关闭。我试图建立一个检查来查看连接失败并尝试再次建立连接,但如果第一次失败,它总是会失败。
import org.apache.commons.net.telnet.TelnetClient;
public String connect()
{
String errorMessage = null;
tcConnectionHandle = new TelnetClient();
tcConnectionHandle.setDefaultTimeout(iTimeOutMilliseconds);
try
{
tcConnectionHandle.connect(strConnectionIP, intConnectionPort);
osOutput = tcConnectionHandle.getOutputStream();
isInput = tcConnectionHandle.getInputStream();
int availableBytes = isInput.available();
while(availableBytes <= 0)
{
tcConnectionHandle = null;
isInput = null;
osOutput = null;
Thread.sleep(500);
tcConnectionHandle = new TelnetClient();
Thread.sleep(500);
tcConnectionHandle.setDefaultTimeout(iTimeOutMilliseconds);
Thread.sleep(500);
tcConnectionHandle.connect(strConnectionIP, intConnectionPort);
Thread.sleep(500);
osOutput = tcConnectionHandle.getOutputStream();
Thread.sleep(500);
isInput = tcConnectionHandle.getInputStream();
Thread.sleep(500);
availableBytes = isInput.available();
System.out.println("reopened: " + availableBytes);
}
}
catch(InterruptedException iX)
{
errorMessage = "Could not establish connection. " + iX.getLocalizedMessage();
}
catch(SocketException sX)
{
errorMessage = sX.getMessage();
}
catch(IOException ioX)
{
errorMessage = ioX.getMessage();
}
return errorMessage;
}
如果我遗漏了Thread.sleep(500)
,它将永远不会有任何可用字节。暂停后,结果为 20,但是,如果我尝试使用 isInput.read() ,它将返回 -1,这意味着 InputStream 已关闭。
我正在寻找一种方法来捕获连接失败并再次尝试连接。这种情况发生得太频繁,不能再试一次。
最佳答案
我认为附加到 TelnetClient 的 InputStream 随机处于关闭状态。即使我创建了新的 TelnetClient 对象并稍后重新连接到同一 Telnet 服务器,在该状态下尝试读取它也会导致通信失败。这没有意义,但我决定尝试一种新方法,而不是弄清楚 TelnetClient 类中发生了什么。
我通过为此类使用实现 TelnetInputListener
解决了该问题。当调用 telnetInputAvailable()
时,InputStream 有时为 null,但我现在可以通过不对函数的特定调用执行任何操作来从中恢复。
public String connect()
{
String errorMessage = null;
tcConnectionHandle = new TelnetClient();
tcConnectionHandle.setDefaultTimeout(iTimeOutMilliseconds);
tcConnectionHandle.registerInputListener(this);
try
{
tcConnectionHandle.connect(strConnectionIP, intConnectionPort);
osOutput = tcConnectionHandle.getOutputStream();
isInput = tcConnectionHandle.getInputStream();
}
catch(SocketException sX)
{
errorMessage = sX.getMessage();
}
catch(IOException ioX)
{
errorMessage = ioX.getMessage();
}
return errorMessage;
}
public Matcher waitForRegularExpression(String regularExpression)
{
Matcher matcher;
Pattern pattern = Pattern.compile("(?s)" + regularExpression);
StringBuilder warningLog = new StringBuilder();
synchronized(sbInputBuffer)
{
matcher = pattern.matcher(sbInputBuffer.toString());
while(!matcher.find())
{
try
{
int inputBufferSize = sbInputBuffer.length();
sbInputBuffer.wait(iTimeOutMilliseconds);
if(inputBufferSize == sbInputBuffer.length())
{
warningLog.append("Did not find pattern and no new input.");
logWarning(warningLog.toString());
return null;
}
}
catch(InterruptedException intX)
{
warningLog.append("Interrupted waiting on input. ").append(intX.getLocalizedMessage());
}
matcher = pattern.matcher(sbInputBuffer.toString());
}
sbInputBuffer.delete(0, matcher.end()-1);
}
if(!warningLog.toString().isEmpty())
{
logWarning(warningLog.toString());
}
return matcher;
}
@Override
public void telnetInputAvailable()
{
synchronized(sbInputBuffer)
{
StringBuilder warningLog = new StringBuilder();
int readBytes = -2;
if(isInput != null)
{
try
{
readBytes = isInput.read();
if(readBytes > 0)
{
sbInputBuffer.append((char)readBytes);
}
sbInputBuffer.notify();
}
catch(IOException ioX)
{
warningLog.append("Failed for IO: ").append(ioX.getLocalizedMessage()).append(" - input so far: ")
.append(sbInputBuffer.toString()).append("\nRead bytes: ").append(readBytes).append("\n");
logWarning(warningLog.toString());
}
}
}
}
关于Java TelnetClient 输入流打开后关闭,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12148771/