2014-10-12 44 views
1

當我使用常規套接字時,我可以調用getInputStream()並使用available()來查看有多少字節可用。我切換到SSLSocket,但現在可用()總是返回0出於某種原因。當我讀取時,我仍然可以獲取數據。如何判斷SSLSocket中是否有可用的數據,以便在沒有數據的情況下可以在不阻塞的情況下爲其提供服務?如何判斷Java SSLSocket是否有可用的數據?

注:

  • 我不能調用read()上的InputStream或線程將阻塞。我希望在我的實現中不阻塞。
  • available()返回0,即使有SSLSocket的InputStream的數據。
+0

[Java中InputStream.available()的作用是什麼?](http://stackoverflow.com/questions/3695372/what-does-inputstream-available-do-in-java)(請查看[第二個答案](http://stackoverflow.com/a/3695378/2398375)) – 2014-10-12 00:41:39

+0

這很有趣。但是,在我的情況下,有數據可用,因此read()不應該被阻止,並且可用不應該返回0. – Aura 2014-10-12 00:48:20

+0

請檢查該答案的第一條評論 - 「*還要注意available()始終返回零爲SSL套接字*「。這將有助於瞭解爲什麼阻塞是您的情況中的問題。請記住,您正在使用阻止IO – 2014-10-12 00:53:25

回答

1

有沒有辦法做到這一點。沒有先解密數據,您的數據流無法告訴您數據的長度。 available()總是返回0爲SSLSocket

正如this chat提到的,你要檢查數據的原因是防止read()從調用時阻塞,這樣你就可以在單個線程處理,而不是每個客戶端系統線程多個連接。

相反,使用非阻塞替代。 java.nio目前沒有的SocketChannel它自己的SSL實現,但你可以找到一個網絡(如here),或者創建自己的。

有了這個系統,你可以註冊一個Selector每一個通道,管理所有使用「選擇線程」。我寫了一個如何使用選擇器的示例here(向下滾動到使用選擇器)。

與非阻塞IO,您可以處理多個客戶端的每個線程,允許你擴大。被帶到管理頻道的這個方法了,由於C10k Problem

4

我相信你能解決問題,但對於那些喜歡我,我發現了一個更容易的解決方案。如果您執行讀取操作,則available()方法會填充解密的內容。如何使用和濫用這個?如果發現SocketTimeoutException,那麼讀取一個SoTimeout值非常低的單個字節,如果沒有,則連接爲空,則將該字節添加到將來對消息的解釋中。直到in.available()== 0再次,只需滾動它。

+0

感謝@JavaProphet,這個簡單的解決方法對於我正在做的概念驗證派上用場。 – 2016-06-17 23:28:18

+0

簡單但有用,謝謝! – 2017-02-18 22:16:31

相關問題