簡體   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