Reputation: 4585
I'm not using any selectors or anything like that. I just have a simple ServerSocketChannel
listening and a SocketChannel
connecting to it in blocking mode. I want to impose a timeout on the connection, but SocketChannel.socket().setSoTimeout()
does not work.
I tried making a background thread sleep for 30 seconds and checking if a variable is still null
(since it will block waiting to read into that variable) but I couldn't synchronize the variable properly in that I could not access the local variable in my anonymous class.
Are there other ways to accomplish this?
Update: I've worded my question wrong. I also want to have a timeout on read operations as well as the connection itself.
Upvotes: 4
Views: 4095
Reputation: 310913
setSoTimeout()
sets a read timeout, not a connect timeout, and for some reason it doesn't work at all on SocketChannels
, even in blocking mode, and even with wrapped streams.
The method you are looking for is channel.socket().connect()
with two arguments.
Upvotes: 2
Reputation: 10020
As far as I know, this is not possible using synchronous operations in nio
. Socket timeouts set via Socket.setSoTimeout()
affect reads and writes but not establishing the connection.
Timeout for connecting is different from read/write timeouts even at system library level - see man 2 connect
, man 2 setsockopt
and man 7 socket
for the gory details. So if you want a real, application-controlled timeout when connecting, you need to use the asynchronous connection protocol and the appropriate Selector
, check SelectionKey.isConnectable()
and so on. This makes the code quite a bit longer, unfortunately.
I don't have the Java lib sources handy now, but it would be interesting to look into how Socket.connect(SocketAddress endpoint,int timeout)
is implemented internally - but I believe it's using select()
inside, too.
Upvotes: -1