ldam
ldam

Reputation: 4585

How does one implement a timeout in blocking mode NIO?

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

Answers (2)

user207421
user207421

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

Michał Kosmulski
Michał Kosmulski

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

Related Questions