Android Dev
Android Dev

Reputation: 31

Catch timeout exception when connecting TCP socket to hostname

I need to catch a timeout exception for a TCP connection to a host name and port, which includes making a DNS lookup of the host name. If I connect to a numeric IP address and port I can set a short timeout and catch an exception quickly, but if I use a domain name the DNS lookup can take take 5 minutes to throw an exception.

How can I make this operation timeout more quickly?

Socket socketconnectionObjet = new Socket();
socketconnectionObjet.connect(new InetSocketAddress(url, port),
                              3  * 1000);          

Upvotes: 2

Views: 1218

Answers (2)

Malt
Malt

Reputation: 30335

First, it's important to understand that you actually need to timeout two separate processes - the DNS lookup, and the connection itself. If both have to fit within a certain timeout, then the solution has to look something like this:

long startTime = System.currentTimeMillis();
InetAddress destination = doDnsLookupWithTimeout(MAX_TIMEOUT);
long remaniningTime = MAX_TIMEOUT - (System.currentTimeMillis() - startTime);
if (remainingTime > 0){ //we still have time to connect
    connectWithTimeout(remainingTime);
}

The good news is that it's easy to timeout the socket connection, you've already done that. The bad news however is that enforcing a timeout on the DNS lookup is harder. Unfortunately, Java's InetAddress.getByName() doesn't accept a timeout parameter, so the call can block for a quite a while (I recently had an issue with some reverse DNS calls on windows blocking for 4.5 seconds).

One solution is to simply to avoid Java's native DNS lookup utilities, and use an external library that supports timeout for instance, DnsJava's SimpleResolver which has a setTimeout() method.

Another solution that comes to mind is to perform the DNS lookups in a separate thread, and wait for that thread to finish its business using Thread.join() or Future.get() with a timeout value. If the second thread finishes in time, use the remaining time to connect. If it doesn't, and you timeout on the Thread.join or Future.get, then you've timeout out.

Upvotes: 1

user4596305
user4596305

Reputation:

Take a look: Socket#connect. You requested the function to fail after 5 minutes (3 * 1000). Read the provided documentation for further info.

Upvotes: -1

Related Questions