V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
doublemark
V2EX  ›  Android

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

  •  
  •   doublemark · 2018-11-13 17:06:40 +08:00 · 10861 次点击
    这是一个创建于 2234 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

    5 条回复    2018-11-14 08:35:56 +08:00
    BBCCBB
        1
    BBCCBB  
       2018-11-13 17:10:12 +08:00
    另开一个线程调用 socket.close() ??

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

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

    你后面的逻辑是啥就继续写代码处理就对了啊.
    doublemark
        5
    doublemark  
    OP
       2018-11-14 08:35:56 +08:00
    @BBCCBB 感谢,在停止服务的时候加上了个结束 socket 的线程,然后在 accept 里捕获异常后处理好了。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5737 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 06:31 · PVG 14:31 · LAX 22:31 · JFK 01:31
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.