Java“Telnet”代码中的Socket Streams问题?

时间:2012-03-22 13:55:13

标签: java sockets telnet

我无法从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>";
}   

有许多事情要清理,我将试验是否需要以这种方式进行,但这是“解决方案”的要点。最大的杀手就是结束。应该再次提到,这是丑陋的非生产代码,但任何其他输入仍然会受到赞赏。

1 个答案:

答案 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()来查询是否发生了任何错误。”

希望我漫长的漫无边际的回应能帮助你。