我需要在Android上实现一个简单的telnet客户端。我尝试使用org.apache.commons.net.telnet.TelnetClient
类:
TelnetClient telnet = new TelnetClient();
telnet.connect( "localhost", PORT);
InputStream inStream = telnet.getInputStream();
PrintStream outStream = new PrintStream( telnet.getOutputStream());
outStream.println( COMMAND);
outStream.flush();
int ch = 0;
while( ( ch = inStream.read()) != -1) {
log("Respose:" + ch);
}
但inStream.read()
阻止。
与此同时,我可以使用Market的telent应用程序从服务器获取响应。
知道我做错了吗?
答案 0 :(得分:0)
一些字符后会阻塞吗?因为您要求它仅在达到inputStream的结尾时停止读取。
我不知道telnet protocole,但在我看来你应该从输入流中读取行,例如使用BufferedReader。一旦从服务器读取一行,就处理它。
答案 1 :(得分:0)
我认为不要使用“localhost”,而是使用该特定计算机的IP地址。
答案 2 :(得分:0)
我正在使用apache telnet客户端,我遇到了同样的问题。原因是telnet服务器是流式响应,没有END令牌。类似于行尾的东西..等等。
所以你将继续获取字节,如果没有传入的字节,那么它将在read()方法中阻塞。
所以我使用StringBuilder将所有传入的字节保持为字符,并跟踪特定的字符串(":/#"),它始终位于传输流的末尾(用于telnet连接)。即使在第一次连接中也是如此。
这是我使用的代码的一部分。
StringBuilder builder = new StringBuilder();
TelnetClient telnet = new TelnetClient();
telnet.connect("127.0.0.1", 23);
outstr = telnet.getOutputStream();
instr = telnet.getInputStream();
int cnt =0;
while(isConnected){
if(builder.toString().endsWith(":/ #")){
cnt++;
if(cnt==2){
Log.i("DATA : ", builder.toString());
builder.delete(0, builder.length());
cnt=1;
}
}
builder.append((char)instr.read());
}
如果您注意到,如果计数器" cnt"达到2.并且计数器设置为1。 " CNT"显示我选择定义流末尾的令牌数量(":/#")。
第一个连接将提供第一个令牌,但要获得结束,您需要计数器来确定它是否是结束令牌。这就是我使用反击的原因。
建议:在不同的线程上保持监听代码,并在另一个线程中命令发送代码。 (最终你会因为android而需要处理networkOnMainThread ..etc。)
不:上面的代码不是完整副本。但它是工作的简化部分。完整版使用分布式表单分离监听,命令发送和异常处理。