SSDP协议下STA模式和softAP模式间切换时遇到的数据收发问题
2016-01-07 10:22
253 查看
在实现SSDP协议的时候,STA模式下,服务设备和手机之间的消息收发是正常的。后来boss加入了可切换的softAP模式,即服务设备可在STA模式和softAP模式间来回切换以满足不同的需求。当时就凌乱了…按理说切换到softAP模式后,就拿手机说吧,作为一个热点,手机内APP的网络数据包是不再走原来的wifi网卡的而是应该走通信模块(可能说的业余了),热点接收的数据包也理应往3G/4G通信模块转发,也就是说APP原来和wifi网卡在STA模式下建立的通路应该是断开的。是否如此呢?一测试果然:在切换到softAP模式后,经抓包分析wlan0网卡不再接收到设备内服务端应用发出的NOTIFY数据;同时,接收到的手机端的M-SEARCH消息也不再往服务端应用发送。
那么,消息到底发哪儿去了呢?如之前所猜想中的发送到了通信模块吗?但此时设备并未插入SIM卡,如何跟踪?一时还真没什么办法,瞎试。这时,boss将问题定位在了监听线程中 MulticastSocket 加入组播组时的 NSD(No such device)异常,后来经断点跟踪,MulticastSocket的send()也抛出了相同的异常,因此,APP并未建立与热点网卡的连接,数据也未能发送出去。因此,可能需要手动做相关的配置或者设置。
根据异常提示,可能原因是切换到热点模式后,网卡的信息未注册到系统或者云云,需要手动设置NetworkInterface。注意到 MulticastSocket::setNetworkInterface() 可进行相关设置:
参考http://stackoverflow.com/questions/6550618/multicast-support-on-android-in-hotspot-tethering-mode/27699370
于是在原来的代码的send (此时joinGroup 未做修改)语句添加try/catch,在捕获到SocketException的时候便设置NetworkInterface,测试,切换到热点模式,发送成功!
但是接下来还是犯了几个很low的错误:
.a 将相应的try/catch以及setNetworkInterface添加到joinGroup相关代码中时,从STA模式切换成热点模式,各项指标正常,但当从softAP模式切回STA模式时,设备无法接收M-SEARCH消息,但是能发送NOTIFY,而且,虽然用的同一块网卡(MAC相同),结果算出的UUID(依赖于网卡MAC)还不一致!真是醉了。其实,所谓的UUID不一致的真相是:同事的机子…
.b 还是有疑问,M-SEARCH收不到什么原因?应该是当前的版本没有重启服务吧(能发送是因为send的调用对象都是临时生成临时绑定的网卡),毕竟监听socket是服务启动时就创建了,于是添加重启代码。!!!丫的还是不行。但是点击Activity界面上的服务重启按键,是可以的!!!真是见鬼。按键重启和代码重启能有什么区别!(其实是后来才发现的时间差)好吧开蛊,一个字:创建监听socket是需要联网的!当代码重启时,我只是检查了wifi的enabled状态,然而,此时wifi还未连接路由,于是加入组播组时又是熟悉的NSD异常;然后,所谓的按键重启,此时wifi已经处于连接状态..
那么,消息到底发哪儿去了呢?如之前所猜想中的发送到了通信模块吗?但此时设备并未插入SIM卡,如何跟踪?一时还真没什么办法,瞎试。这时,boss将问题定位在了监听线程中 MulticastSocket 加入组播组时的 NSD(No such device)异常,后来经断点跟踪,MulticastSocket的send()也抛出了相同的异常,因此,APP并未建立与热点网卡的连接,数据也未能发送出去。因此,可能需要手动做相关的配置或者设置。
根据异常提示,可能原因是切换到热点模式后,网卡的信息未注册到系统或者云云,需要手动设置NetworkInterface。注意到 MulticastSocket::setNetworkInterface() 可进行相关设置:
public static NetworkInterface getNetworkInterface() { Enumeration<NetworkInterface> enumeration = null; try { enumeration = NetworkInterface.getNetworkInterfaces(); } catch (SocketException e) { e.printStackTrace(); } NetworkInterface wlan0 = null; StringBuilder sb = new StringBuilder(); while (enumeration.hasMoreElements()) { wlan0 = enumeration.nextElement(); sb.append(wlan0.getName() + " "); if (wlan0.getName().equals("wlan0")) { //there is probably a better way to find ethernet interface Log.i(TAG, "wlan0 found"); return wlan0; } } return null; }
参考http://stackoverflow.com/questions/6550618/multicast-support-on-android-in-hotspot-tethering-mode/27699370
于是在原来的代码的send (此时joinGroup 未做修改)语句添加try/catch,在捕获到SocketException的时候便设置NetworkInterface,测试,切换到热点模式,发送成功!
但是接下来还是犯了几个很low的错误:
.a 将相应的try/catch以及setNetworkInterface添加到joinGroup相关代码中时,从STA模式切换成热点模式,各项指标正常,但当从softAP模式切回STA模式时,设备无法接收M-SEARCH消息,但是能发送NOTIFY,而且,虽然用的同一块网卡(MAC相同),结果算出的UUID(依赖于网卡MAC)还不一致!真是醉了。其实,所谓的UUID不一致的真相是:同事的机子…
.b 还是有疑问,M-SEARCH收不到什么原因?应该是当前的版本没有重启服务吧(能发送是因为send的调用对象都是临时生成临时绑定的网卡),毕竟监听socket是服务启动时就创建了,于是添加重启代码。!!!丫的还是不行。但是点击Activity界面上的服务重启按键,是可以的!!!真是见鬼。按键重启和代码重启能有什么区别!(其实是后来才发现的时间差)好吧开蛊,一个字:创建监听socket是需要联网的!当代码重启时,我只是检查了wifi的enabled状态,然而,此时wifi还未连接路由,于是加入组播组时又是熟悉的NSD异常;然后,所谓的按键重启,此时wifi已经处于连接状态..
相关文章推荐
- 我是运营,我没有假期
- DB2数据库的安装
- C#实现把指定数据写入串口
- “传奇”图象数据存储方式
- 修复mysql数据库
- 浅析SQL数据操作语句
- SQLServer 数据导入导出的几种方法小结
- MySQL数据备份之mysqldump的使用详解
- C#实现窗体间传递数据实例
- 给你的数据库文件减肥
- Oracle数据更改后出错的解决方法
- Oracle数据库数据丢失恢复的几种方法总结
- C#将Sql数据保存到Excel文件中的方法
- MFC实现在文件尾追加数据的方法
- 把excel表格里的数据导入sql数据库的两种方法
- 用文本作数据处理
- 桌面中心(一)创建数据库
- 桌面中心(四)数据显示
- PHP+JS实现大规模数据提交的方法
- C#数据绑定(DataBinding)简单实现方法