我无法从C / C ++过渡到Java,因为我的“Telnet”界面转到我们在这里工作的一些模块。我希望能够与卡建立连接,在启动它的命令行界面后,等待连接并向客户端提供提示(“OK>”)。这对我编写的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 simple telnet client using sockets
它似乎与我遇到的相似,但它不一样。如果有人在这里看到解决我问题的事情,我愿意接受代表,所以请直接告诉我,直截了当地说,我错过了什么。
修改
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>";
}
有许多事情要清理,我将试验是否需要以这种方式进行,但这是“解决方案”的要点。最大的杀手就是结束。应该再次提到,这是丑陋的非生产代码,但任何其他输入仍然会受到赞赏。
答案 0 :(得分:1)
我有几件事你可以试试。您正在使用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,将其顺序设置为little-endian。将字节写入其中,然后将字节从ByteBuffer写入DataOutputStream。
我可能也会切换到输入流的DataInputStream。 readline()只有在看到换行符后才会返回。您的卡片是否在其响应中返回换行符?
我的最后一个想法是你的println方法可能有错误,你不知道它,因为PrintWriter不会抛出异常。 PrintWriter JavaDocs说:
“此类中的方法永远不会抛出I / O异常,尽管它的一些构造函数可能。客户端可以通过调用checkError()来查询是否发生了任何错误。”
希望我漫长的漫无边际的回应能帮助你。