'How to tell if Java SSLSocket has data available?
When I was using regular Sockets, I could call getInputStream() and use available() to see how many bytes were available. I switched to SSLSocket, but now available() always returns 0 for some reason. When I read instead, I can still get data. How can I tell if there is data available in an SSLSocket so that I can service it without blocking if there is no data?
Notes:
- I cannot call read() on the InputStream or the thread will block. I would like non-blocking in my implementation.
- available() returns 0 even though there is data for SSLSocket's InputStream.
Solution 1:[1]
There is no way to do this. Your streams cannot tell you the length of the data without first decrypting it. available()
will always return 0 for SSLSocket
.
As mentioned in this chat, the reason you wanted to check for data is to prevent read()
from blocking when called, so you can handle multiple connections on a single thread, instead of a Thread per Client system.
Instead, use a non-blocking alternative. java.nio
currently doesn't have it's own SSL implementation of SocketChannel
, but you can find one online (like here) or create your own.
With this system, you can register a Selector
to every channel, and manage them all using the "selector thread". I wrote an example of how to use a selector here (scroll down to Using a Selector).
With non-blocking IO, you to handle multiple clients per thread, allowing you to scale up. This method of managing channels was brought up due to the C10k Problem
Solution 2:[2]
I assume you fixed your problem, but for those like me, I found a much easier solution. If you perform a read, then the available() method fills up for what was decrypted. How to use and abuse this? Read a single byte with a very low SoTimeout on your socket, if you catch a SocketTimeoutException, then the connection is empty, if not, prepend that byte you read to your future interpretation of the message. Until in.available() == 0 again, just roll with it.
Solution 3:[3]
You can use available() with inputStream of underlying Socket. This works in my case.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Community |
Solution 2 | JavaProphet |
Solution 3 | Anupam |