我有一个实现Telnet服务器的设备,我正在编写java代码来与之通信。当前的实施"工作"并且我的意思是它会暂时挂起,有时立即挂起,有时一小时后或其他任何地方挂起。我不排除它是设备本身的可能性,但是,使用putty的长时间运行似乎没有问题,因此我假设它是我的java代码。
我首先列出我的代码,然后更详细地描述问题:
该连接由一个对象EthernetTelnetConnection()
处理,该对象使用了Apache Commons TelnetClient()
。
public EthernetTelnetConnection(String host, int port) throws IOException {
mTelnet = new TelnetClient();
mTelnet.connect(host, port);
mOut = mTelnet.getOutputStream();
mIn = mTelnet.getInputStream();
}
这些流通过以下方式转换为缓冲流:
mReadStream = new BufferedInputStream(mConnection.getInputStream());
mWriteStream = new BufferedOutputStream(mConnection.getOutputStream());
可以通过以下方式获得:
public BufferedInputStream getInputStream() {
return mReadStream;
}
public BufferedOutputStream getOutputStream() {
return mWriteStream;
}
因此,在创建连接后,我开始尝试解析流。这发生在专用线程中,他们生活中唯一的目的是执行这一方法:
public void detectMessages() throws IOException {
final BufferedInputStream in = mTekdaqc.getInputStream();
StringBuilder builder = new StringBuilder();
int data;
final Scanner scan = new Scanner(in, "UTF-8").useDelimiter(Character.toString((char) AASCIIMessage.RECORD_SEPARATOR_CHAR));
while (scan.hasNext()) {
onMessageDetected(scan.next());
}
/*while ((data = in.read()) != -1) {
if (data == AASCIIMessage.RECORD_SEPARATOR_CHAR) {
onMessageDetected(builder.toString());
builder = new StringBuilder();
} else {
builder.append((char) data);
}
}*/
}
AASCIIMessage.RECORD_SEPARATOR_CHAR
定义为:
public static final int RECORD_SEPARATOR_CHAR = 0x1E;
底部的评论部分还有一些额外的变量,这是我之前的尝试。 显示相同问题的两种方法:onMessageDetected()
最终会被成千上万的空字符串调用。通常,如果我让事情运行,最终事情会像往常一样持续一段时间,然后这个问题又开始了。因此,我试图弄清楚是什么导致扫描仪和简单的while循环/读取周期来检测消息分隔符。当捕获设备和putty之间的wireshark流量时,我可以确认它没有发送这些分隔符,尽管它正在发送keep alive包。
更新
有人向我建议,这可能是一个问题,其中Apache TelnetClient将一个字节序列解释为Putty不是的终端命令。我不确定设备实现了什么终端实现,因为我没有创建该代码并且没有记录。我看了一下putty,它没有在Telnet配置窗口中指出终端类型。
更新2
我将System.out
连接到TelnetClient
实例的间谍流,并在十六进制编辑器中检查输出,发现该流实际上看到重复RS (0x1E)
个字符。使用Putty Telnet连接嗅探流量我没有看到这个,那么TelnetClient
类和我的设备是否存在某种不正确的配置?
答案 0 :(得分:0)
事实证明我可以在设备上责怪这一个。当我嗅到putty的流量并执行与Java应用程序完全相同的命令序列时,我能够重现这个问题。这是我需要在固件中追踪的错误。感谢@Adam和@MrunalGosar的输入。