Android: ServerSocket 如何关闭正在阻塞的 accept()方法

2018-11-13 17:06:40 +08:00
 doublemark

首先说明一下,本人目前是一名硬件工程师,手头有个项目需要写一个简单的 Android 测试软件,和单片机控制的 WiFi 模块通讯,软件上为 Server 端,监听某一端口,单片机为 Client,通过 TCP/IP 协议通讯,目前 app 端我用 Service 实现了把 Socket 封装起来,这样各个 activity 里都可以发送接收,后台 service 保持 socket 的连接。 界面上一个 startservice 的按钮,一个 stopservice 的按钮。 有个小问题,假如用户在打开了 startservice 按钮,又想关闭了,程序里 serversocket 在 accept 的时候已经阻塞了,该怎么关闭呢? 看过几个回答,csdn 也好,google 的也好,都没能实现。前来 V2EX 寻求高人指点。多谢各位。

10738 次点击
所在节点    Android
5 条回复
BBCCBB
2018-11-13 17:10:12 +08:00
另开一个线程调用 socket.close() ??

这样 accept 的地方就会出现一个异常, catch 这个异常处理就 ok 了吧
doublemark
2018-11-13 17:14:25 +08:00
@BBCCBB 感谢回复。

试过在另一个线程里 close,也在 accept 里 catch 到这个异常了,到这里的话怎么办? catch 到了之后怎么处理呢?
nicevar
2018-11-13 17:34:37 +08:00
正确的办法应该是用线程管理,如果 service 没有必要停止就一直开启, 自己做一个管理器进行通信管理
就是说 accept 阻塞了就让它在那个线程一直跑着,别管它就行了,应用层就这么处理
所以有时候应用层也很无奈,以前 mtk 的底层播放器 stop 函数会经常卡住,理论上正确的逻辑 stop 应该在 UI 线程调用,应该要立即返回的,一旦卡住就会导致程序 ANR 了,这时候你用线程异步去 stop 虽然能避开这个坑,但是逻辑上是有问题的,比如一些芯片不能实例化多个多播放器,直接导致播放器状态出错
BBCCBB
2018-11-13 17:39:12 +08:00
@doublemark catch 到异常后说明 socket 关闭了, 你想关闭的愿望也就实现了

你后面的逻辑是啥就继续写代码处理就对了啊.
doublemark
2018-11-14 08:35:56 +08:00
@BBCCBB 感谢,在停止服务的时候加上了个结束 socket 的线程,然后在 accept 里捕获异常后处理好了。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/507475

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX