【问题标题】:Application crashes after I closed the socket waiting for reading in a thread关闭套接字等待读取线程后应用程序崩溃
【发布时间】:2017-04-05 09:05:14
【问题描述】:

我有一个在后台运行的服务,其中包含多个通过 TCP 套接字读取和写入的线程。在我关闭套接字并停止服务后,我的应用程序崩溃了。在崩溃发生之前,我的代码抛出并捕获了一个 SocketException。我不知道为什么 SocketExeption 在它已经被捕获时会导致我的应用程序崩溃。但是这个问题只发生在我的一部在 android 4.2 上运行的手机上。到目前为止,android 5 或 andoird 6 上没有发生崩溃。

以下是部分代码:

public void logout() throws IOException {
this.userName = "";
listenerService.p_status=false;
listenerService.p_Thread.interrupt();
listenerService.c_status=false;
listenerService.c_Thread.interrupt();
listenerService.closeSocket();
unbindService(mConnection);
listenerService.stopService();

}

这里是调试信息:

04-05 17:36:49.635 28101-28691/com.androidapp.ptt I/System.out: SOCKET CLOSED!
04-05 17:36:49.635 28101-28691/com.androidapp.ptt W/System.err: java.net.SocketException: Socket closed
04-05 17:36:49.635 28101-28691/com.androidapp.ptt W/System.err:     at libcore.io.Posix.recvfromBytes(Native Method)
04-05 17:36:49.635 28101-28691/com.androidapp.ptt W/System.err:     at libcore.io.Posix.recvfrom(Posix.java:142)
04-05 17:36:49.640 28101-28699/com.androidapp.ptt I/System.out: 404:kukukukukukuku
04-05 17:36:49.640 28101-28691/com.androidapp.ptt W/System.err:     at libcore.io.BlockGuardOs.recvfrom(BlockGuardOs.java:164)
04-05 17:36:49.640 28101-28691/com.androidapp.ptt W/System.err:     at libcore.io.IoBridge.recvfrom(IoBridge.java:499)
04-05 17:36:49.640 28101-28691/com.androidapp.ptt W/System.err:     at java.net.PlainSocketImpl.read(PlainSocketImpl.java:488)
04-05 17:36:49.640 28101-28691/com.androidapp.ptt W/System.err:     at java.net.PlainSocketImpl.access$000(PlainSocketImpl.java:46)
04-05 17:36:49.645 28101-28691/com.androidapp.ptt W/System.err:     at java.net.PlainSocketImpl$PlainSocketInputStream.read(PlainSocketImpl.java:240)
04-05 17:36:49.645 28101-28691/com.androidapp.ptt W/System.err:     at java.io.InputStream.read(InputStream.java:162)
04-05 17:36:49.645 28101-28691/com.androidapp.ptt W/System.err:     at com.androidapp.ptt.ListenerService$2.run(ListenerService.java:439)
04-05 17:36:49.645 28101-28691/com.androidapp.ptt W/System.err:     at java.lang.Thread.run(Thread.java:841)
04-05 17:36:49.685 28101-28101/com.androidapp.ptt I/System.out: Service done!

非常感谢任何帮助!

【问题讨论】:

  • 显示堆栈跟踪(有多种获取 SocketException 的选项)并显示更多代码。可能你没有关闭输入/输出流之类的
  • 现在我将调试信息添加到问题中。我只是关闭了套接字,没有明确关闭输入流和输出流。但我认为socket关闭后输入输出流应该自动关闭。崩溃只发生在android 4.2,android 5.0或6.0没有问题。
  • 尝试在 close() 之前检查套接字是否已经关闭。
  • 我确定套接字在 close() 之前是打开的。在调用 logout() 方法之前,我可以通过套接字发送和接收消息。我想可能是我应该保持套接字打开并通过套接字发送一条消息来告诉服务器客户端已经退出。然后我可以在以后需要时重用这个套接字。
  • 感谢您的帮助。我关于套接字的代码太乱了,无法发布。但你是对的,它写得不正确。关闭套接字后,我没有成功停止线程中的循环。我有一个与多线程有关的问题。由于多个线程的意外执行顺序,我捕获的其中一个 Excetpion.printStackTrace() 可能在包含这些线程的服务被另一个线程终止后调用,然后导致应用程序崩溃。

标签: android multithreading sockets socketexception


【解决方案1】:

read() 中被阻塞的线程 抛出了一个IOException。这正是应该预期的行为。您关闭了套接字:它已关闭。您无法继续阅读。

如果您想要一种终止该线程的好方法,请在套接字上调用shutdownInput() 而不是关闭它。这将导致读取线程解除阻塞,感知流结束,如果写入正确,则停止读取并关闭套接字。

【讨论】:

  • 谢谢,您的解释很有帮助。通过 shutdownInput() 解除对 read() 的阻塞比抛出异常要好。而且我的代码没有正确停止线程并关闭套接字。我还发现了一件有趣的事情:调用 Exception.printStackTrace() 可能会导致未捕获的异常,这可能是由于多个线程的意外执行顺序。 Excetpion.printStackTrace() 可以在包含这些线程的服务被另一个线程终止后调用,然后导致应用程序崩溃。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多