Elyakim Levi
Elyakim Levi

Reputation: 370

Unable to catch SocketTimeoutException thrown from socket.connect(InetAddress, timeout)

I'm developing an app that connects to a server via socket connection to read and write data. I'm using runInBackground() method in AsyncTask to do this.

I use my PC as a server and connect my android device to the WiFi to connect to the PC.

I want to simulate a case where the server is unavailable so I disconnect my device from the WiFi and run the code.

I use the following code:

try 
{
    socket = new Socket();
    socket.connect(new InetSocketAddress("192.168.1.104", 4444), 10000);
    ...
    ...
}
catch (SocketTimeoutException e) 
{
    e.printStackTrace();
}
catch (ClassNotFoundException e) 
{
    e.printStackTrace();
}
catch (IOException e) 
{
    e.printStackTrace();
}
catch (Exception e) 
{
    e.printStackTrace();
}

A SocketTimeoutException is thrown after 10 seconds as expected but the problem is that none of the catch blocks actually catch the exception. How is that possible?

Here's the log:

11-09 17:57:15.286: W/System.err(12050): java.net.SocketTimeoutException: failed to connect to     /192.168.1.104 (port 4444) after 10000ms
11-09 17:57:15.301: W/System.err(12050):    at libcore.io.IoBridge.connectErrno(IoBridge.java:159)
11-09 17:57:15.301: W/System.err(12050):    at libcore.io.IoBridge.connect(IoBridge.java:112)
11-09 17:57:15.301: W/System.err(12050):    at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:192)
11-09 17:57:15.301: W/System.err(12050):    at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:459)
11-09 17:57:15.306: W/System.err(12050):    at java.net.Socket.connect(Socket.java:842)
11-09 17:57:15.306: W/System.err(12050):    at com.elyakimsportal.communication.ContactServer$RetrieveProfilesTask.doInBackground(ContactServer.java:183)
11-09 17:57:15.306: W/System.err(12050):    at com.elyakimsportal.communication.ContactServer$RetrieveProfilesTask.doInBackground(ContactServer.java:1)
11-09 17:57:15.311: W/System.err(12050):    at android.os.AsyncTask$2.call(AsyncTask.java:287)
11-09 17:57:15.311: W/System.err(12050):    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
11-09 17:57:15.311: W/System.err(12050):    at java.util.concurrent.FutureTask.run(FutureTask.java:137)
11-09 17:57:15.311: W/System.err(12050):    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
11-09 17:57:15.316: W/System.err(12050):    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
11-09 17:57:15.316: W/System.err(12050):    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
11-09 17:57:15.316: W/System.err(12050):    at java.lang.Thread.run(Thread.java:856)
11-09 17:57:15.316: I/System.out(12050): closed connection to server

Also, I looked at the documentation of the Socket.connect(InetSocketAddress, timeout) method and it doesn't say it ever throws SocketTimeoutException so that makes it even more confusing.

Parameters
remoteAddr  the address and port of the remote host to connect to. 
timeout  the timeout value in milliseconds or 0 for an infinite timeout. 

Throws
IllegalArgumentException  if the given SocketAddress is invalid or not supported or the timeout value is negative. 
IOException  if the socket is already connected or an error occurs while connecting.  

By the way, my app doesn't crash. Am I right to assume that that's because it's in a different thread?

Upvotes: 0

Views: 3859

Answers (2)

Vinod Kollipara
Vinod Kollipara

Reputation: 61

I faced this long back and solved it successfully. The reason you are not able to catch the exception is that the exception is being thrown from other thread from the calling thread.

If you debug it you can see the threads.

Upvotes: 0

James Taylor
James Taylor

Reputation: 6258

It looks to me that in the example code you provided the SocketTimeoutException is being caught. This would make sense since you said your app doesn't crash.

It might still 'look' like it's crashing or not catching the exception because you are printing the stack track to the terminal using e.printStackTrace().

If you don't want to fill the log with these exceptions, consider the rewrite:

try {
    socket = new Socket();
    socket.connect(new InetSocketAddress("192.168.1.104", 4444), 10000);
    ...
    ...

} catch (SocketTimeoutException e) {
    System.err.println("SocketTimeoutException: " + e.getMessage());

} catch (ClassNotFoundException e) {
    System.err.println("ClassNotFoundException: " + e.getMessage());

} catch (IOException e) {
    System.err.println("IOException: " + e.getMessage());

} catch (Exception e) {
    System.err.println("Exception: " + e.getMessage());

}

Upvotes: 1

Related Questions