3

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.

ldam
  • 4,412
  • 6
  • 45
  • 76
  • possible duplicate of [Specify connection timeout in java.nio](http://stackoverflow.com/questions/2563934/specify-connection-timeout-in-java-nio) – ollo Feb 28 '13 at 00:27
  • 1
    No, that's for non blocking mode nio. I'm talking about blocking mode. – ldam Feb 28 '13 at 05:29

2 Answers2

2

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.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • Thanks, but I would like to have a timeout on read operations too. I've updated my question to reflect this too. I asked the question when I was tired last night and forgot to mention it. – ldam Feb 28 '13 at 05:34
  • Then I suggest you use `java.net.Socket`, which does have read timeouts. – user207421 Apr 22 '15 at 07:19
  • The top answer in regard to `setSoTimeout()` not working on `SocketChannel` is [here](http://stackoverflow.com/questions/2866557/timeout-for-socketchannel-doesnt-work) with a workaround. Tried and it worked for me. – Sarthak Singhal Apr 29 '17 at 22:25
-1

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.

Michał Kosmulski
  • 9,855
  • 1
  • 32
  • 51
  • You are mistaken. You can use NIO in blocking mode, and you can obtain both a read timeout and a connect timeout. OP does not have to switch to non-blocking mode. -1 – user207421 Feb 27 '13 at 21:27
  • @EJP I don't quite think so. The code for [SocketChannelImpl.connect()](http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/sun/nio/ch/SocketChannelImpl.java#498) uses `Net.connect()` which is not passed any timeout value. If you use `SocketChannel.socket()`, you get an instance of `SocketAdaptor` whose [connect() method](http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/sun/nio/ch/SocketAdaptor.java#SocketAdaptor.connect%28java.net.SocketAddress%2Cint%29) uses async I/O internally. So SO_TIMEOUT seems to not affect SocketChannel.connect(). – Michał Kosmulski Feb 27 '13 at 22:12
  • Call channel.socket.connect(address, timeout) and you get a connection timeout, like it says on the tin. I didn't say anything about SO_TIMEOUT. – user207421 Feb 27 '13 at 22:33
  • If you call `SocketChannel.socket().connect(address,timeout)`, you are actually using the plain old `Socket` API - so I wouldn't call this an example of connecting using `nio` which I understand the OP needs. – Michał Kosmulski Feb 27 '13 at 22:46
  • 3
    What he needs is a way to get a connection timeout starting from the NIO API, and that is the way. He doesn't 'need' any kind of 'NIO API purity', and he doesn't 'need' to implement a timed connect himself with non-blocking mode and a selector when there is already a one-liner that already does exactly that under the hood. – user207421 Feb 27 '13 at 22:58