[英]Issue with Socket Streams in Java “Telnet” Code?
我在从“ Telnet”接口的C / C ++过渡到Java时遇到一些麻烦。 我希望能够与网卡建立连接,该网卡在启动命令行界面后等待连接并向客户端提供提示(“确定>”)。 这对于我编写的C和C#客户端都可以正常工作,但是Java给了我一些问题。 我已经附上了我从一些在线示例中获取的代码,但是到目前为止,我只能确定正在创建套接字。
码:
private boolean CreateTelnetSession()
{
try
{
_socket = new Socket();
_socket.connect(new InetSocketAddress(_ipAddr, _ipPort));
_socket.setSoTimeout(10000);
_socket.setKeepAlive(true);
_out = new PrintWriter(_socket.getOutputStream(), true);
_in = new BufferedReader(new InputStreamReader(_socket.getInputStream()));
_out.println("\r\n");
System.out.println(_in.readLine());
return true;
}
catch(Exception e)
{
System.out.println("Exception!");
}
return false;
}
套接字SEEMS可以正确创建,并且在程序关闭时,我可以看到会话正在我想要交谈的卡上关闭,但是我没有看到回车符/换行符符合我的期望,或者通过InputStream返回提示。 这可能是字符编码问题吗? 我在流中做错了什么(穿过它们!!!)? 有什么见解吗? 当我克服了这个最初的学习曲线时,我想承认Java使这些套接字读写变得如此容易,但是直到那时...
我读了这篇文章: 使用套接字的Java简单telnet客户端
似乎与我所面临的挑战相似,但事实并非如此。 如果有人在这里看到可以解决我问题的内容,我愿意代表销售,因此请直截了当地告诉我我错过了什么。
编辑:
private boolean CreateTelnetSession()
{
try
{
_socket = new Socket();
_socket.connect(new InetSocketAddress(_ipAddr, _ipPort));
_socket.setSoTimeout(10000);
_socket.setKeepAlive(true);
_out = new DataOutputStream(_socket.getOutputStream());
_in = new DataInputStream(_socket.getInputStream());
_outBuffer = ByteBuffer.allocate(2048);
_outBuffer.order(ByteOrder.LITTLE_ENDIAN);
_inBuffer = ByteBuffer.allocate(2048);
_inBuffer.order(ByteOrder.LITTLE_ENDIAN);
System.out.println("Connection Response: " + _in.read(_inBuffer.array()));
System.out.println("Response: " + WriteCommand("DRS\r\n"));
return true;
}
catch(Exception e)
{
System.out.println("Exception!");
}
return false;
}
private String WriteCommand(String command)
{
try
{
_outBuffer = encoder.encode(CharBuffer.wrap(command));
_out.write(_outBuffer.array());
_out.flush();
_in.read(_inBuffer.array());
String retString = decoder.decode(_inBuffer).toString();
return retString.substring(0, retString.indexOf('>') + 1);
}
catch(Exception e)
{
System.out.println("Exception!");
}
return "E1>";
}
有很多事情需要清理,我将尝试是否需要以这种方式进行清理,但这是“解决方案”的要旨。 最大的杀手是字节序。 应当再次提及,这是丑陋且非生产性的代码,但是任何其他输入仍将受到赞赏。
我有几件可以尝试的东西。 您正在使用PrintWriter作为输出,这是一个相当高级的Writer(即,它封装了您的很多东西)。 我担心的是,PrintWriter中的println()方法在结尾处自动添加了一个行终止字符(适用于您的操作系统)。 因此,您真正发送的是“ / r / n(行终止符)”,因此在Unix框上您将发送“ / r / n / n”。
我建议切换到DataOutputStream,它使您对发送的原始字节有更多控制: http : //docs.oracle.com/javase/6/docs/api/java/io/DataOutputStream.html
请记住,如果切换到DataOutputStream,则需要在输出流上调用flush。
我的另一个想法是这可能是一种流行病。 Java严格是Big Endian(网络字节顺序)。 您的“卡片”是否有可能以小端顺序读取内容? 如果您需要通过网络以低位优先顺序写(如果您的卡是坏网民!),则需要使用ByteBuffer,将其顺序设置为低位顺序。 向其写入字节,然后将字节缓冲区中的字节写入DataOutputStream。
我可能也会为您的输入流切换到DataInputStream。 readline()仅在看到换行符后才返回。 您的卡是否在响应中返回换行符?
我的最后一个想法是您的println方法可能有一个错误,并且您不知道该错误,因为PrintWriter不会引发异常。 PrintWriter JavaDocs说:
“此类中的方法永远不会抛出I / O异常,尽管它的某些构造函数可能会发生。客户端可以通过调用checkError()来查询是否发生了任何错误。”
希望我漫不经心的回应中的某些内容对您有所帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.