繁体   English   中英

Java“ Telnet”代码中的套接字流有问题吗?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM