【问题标题】:Unable to catch SocketTimeoutException thrown from socket.connect(InetAddress, timeout)无法捕获从 socket.connect 抛出的 SocketTimeoutException(InetAddress,超时)
【发布时间】:2014-11-09 16:30:44
【问题描述】:

我正在开发一个应用程序,该应用程序通过套接字连接连接到服务器以读取和写入数据。 我在 AsyncTask 中使用 runInBackground() 方法来执行此操作。

我将我的 PC 用作服务器并将我的 android 设备连接到 WiFi 以连接到 PC。

我想模拟服务器不可用的情况,因此我断开设备与 WiFi 的连接并运行代码。

我使用以下代码:

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();
}

在 10 秒后按预期抛出 SocketTimeoutException,但问题是没有一个 catch 块实际上捕获异常。这怎么可能?

这是日志:

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

另外,我查看了 Socket.connect(InetSocketAddress, timeout) 方法的文档,并没有说它曾经抛出过 SocketTimeoutException 异常,因此更加混乱。

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.  

顺便说一句,我的应用程序没有崩溃。我是否可以假设这是因为它在不同的线程中?

【问题讨论】:

  • 你正在捕捉它,然后打印堆栈跟踪......
  • 是的,我没有意识到,谢谢。对了,你能解释一下为什么当文档没有提到抛出那种异常的可能性时它会抛出 SocketTimeoutException 吗?
  • 并非所有异常都需要明确抛出。例如 RuntimeException
  • 或者,更好的是,SocketTimeoutException 属于 IOException,我很确定您的班级至少会抛出这个(包括 STE)

标签: java android sockets


【解决方案1】:

在我看来,在您提供的示例代码中,SocketTimeoutException 被捕获了。这是有道理的,因为您说您的应用不会崩溃。

它可能仍然“看起来”像崩溃或未捕获异常,因为您正在使用 e.printStackTrace() 将堆栈跟踪打印到终端。

如果您不想用这些异常填充日志,请考虑重写:

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());

}

【讨论】:

  • 好吧,现在我觉得自己很愚蠢:/感谢您为我清理它,James :)
【解决方案2】:

我面对这个漫长的背影并成功地解决了它。 您无法捕获异常的原因是该异常是从调用线程的其他线程抛出的。

如果你调试它,你可以看到线程。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-11-09
    • 2015-08-14
    • 1970-01-01
    • 1970-01-01
    • 2014-08-26
    • 2011-04-05
    • 2015-09-23
    相关资源
    最近更新 更多