簡體   English   中英

讀取SSL套接字Java的奇怪行為

[英]Odd behavior reading SSL socket Java

我正在嘗試使用SSL編寫一個簡單的echo服務器。 轉到服務器的第一行完全回應。 當我發送第二行時,只回顯第一個字符。 客戶端使用stdin的緩沖讀取器讀取線。 如果我再次點擊CR,則會顯示其余信息。 服務器似乎正在發送所有數據。 這是客戶端和服務器的輸出:

客戶:

在端口9999上發送到服務器192.168.0.161

4 seasoNS
回聲:4 seasoNS

非常好
回聲:一

回聲:真的很好

SERVER:服務器監聽9999
有cr / lf
4 seasoNS

發送大小:10
有cr / lf
非常好

發送大小:16
退出...

這是客戶端循環:

        try {
        BufferedReader consoleBufferedReader = getConsoleReader();
        sslsocket = getSecSocket(strAddress, port);
        BufferedWriter sslBufferedWriter = getSslBufferedWriter(sslsocket);
        InputStream srvrStream = sslsocket.getInputStream();

        String outMsg;
        while ((outMsg = consoleBufferedReader.readLine()) != null) {
            byte[] srvrData = new byte[1024];
            sslBufferedWriter.write(outMsg);
            sslBufferedWriter.newLine();
            sslBufferedWriter.flush();
            int sz = srvrStream.read(srvrData);
            String echoStr = new String(srvrData, 0, sz);
            System.out.println("echo:" + echoStr);
        }
    } catch (Exception exception) {
        exception.printStackTrace();
    }

這個問題看起來很奇怪,我希望有一些明顯的東西讓我失蹤。

你所看到的是完全正常的。

假設您要一次性讀取整個緩沖區是錯誤的:

int sz = srvrStream.read(srvrData);

相反,你需要保持循環,直到你得到你選擇的分隔符(在你的情況下可能是一個新的行)。

這通常適用於普通TCP連接以及SSL / TLS連接。 這就是為什么應用程序協議必須具有分隔符或內容長度的原因(例如,HTTP有一個雙重新行來結束其標題,並使用Content-Length或chunked transfer encoding在實體結束時告訴另一方)。

在實踐中,您可能看不到何時您的假設不適用於這么小的例子。

但是,JSSE會將它發送的記錄拆分為1 / n-1, 以減輕BEAST攻擊 (OpenSSL將發送0 / n。)因此,在這種情況下,問題更加明顯。

同樣,這不是SSL / TLS或Java問題,修復此問題的方法是將您讀取的輸入視為流,而不是假設您在一端讀取的緩沖區大小將與用於的緩沖區大小相匹配從另一端發送數據。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM