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.
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 forSSLSocket
.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 ofSocketChannel
, 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
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.