---------------------------!! 转载请注明出处 !!-----------------------
 

一个项目,利用wifi组播在局域网内发现设备。却发现在有的路由器上能正常工作,有的路由器上完全监听不到组播消息。检查路由配置没有任何问题。

组播实现很简单:拿住WifiLock,拿住MulticastLock,创建MulticastSocket端口1900,ttl设为3或者5,然后joinGroup加入239.255.255.250组,然后设置socket的timeout,调用receive开始监听。还要记得manifest中加上几个相关的permission。

网上可以搜到很多示例,基本都是这样的处理流程,没什么复杂的。

一开始测试时工作正常,由于用的是UPnP通用的组播ip (239.255.255.250:1900),所以可以收到局域网里很多组播消息,包括MediaRenderer,InternetGateway等等,我们只要从中筛出自己的消息就行了。

但小批量投放后,发现了问题。我们的产品在某些路由器上无法监听到组播消息。监听端口上一片静默,不仅我们自己的消息收不到,网络中其他设备发的组播消息也收不到。

带回3台有问题的路由,分别是 1) linksys,2) 华为,3) ARRIS

而国内的三台路由上工作却是正常的,这三台分别是  4)小米,5) 华硕, 6)Cisco

找了另外三台android手机安装同一个app做测试,三台手机:htc (android4.4.2),Sony (andorid4.1.2),华为(android5.0.2)

问题来了,htc和sony在6台路由上均能监听到组播,华为荣耀7跟我们的设备一样,完全监听不到。

*以上路由和手机就不标具体型号了^_^

----------------------------------------------------问题描述完毕,开始解决------------------------------------

WinPCap工具抓包发现,

两台测试机htc和sony,在加入组播组(joinGroup)时,会发送
IGMP V2 Membership Report / Join group 239.255.255.250
离开组播组(leaveGroup)
IGMP V2 Leave Group 239.255.255.250
 
有些支持IGMP V3的路由上抓包如下:
IGMP V3 Membership Report / Join group 239.255.255.250 for any sources
IGMP V3 Membership Report / Leave group 239.255.255.250

而出问题的手机(华为手机和我们自己的设备),根本没发IGMP包。

也就是表示,它们在加入组播组时,尽管在app总调用joinGroup成功,但实际上并未向路由器发出IGMP请求,即根本没加入组播组,自然就监听不到消息。

那么为什么这两台机器在小米,华硕,cisco路由上能正常监听呢? 猜测这三台路由恐怕并没有严格按照的UPnP协议来实现,猜测它可能给连在路由上的任何设备发送组播(类似广播一样处理),设备收到组播后,根据本地的配置情况决定是否发给app。由于没有路由器实现的代码,只是根据现象猜测。

至此,我们要解决的问题就是 让它们发出IGMP包。

对华为手机,没办法了,不是我做的。。。

我们自己的设备是有全部源码的,调查发现linux kernel的config中 CONFIG_IP_MULTICAST 这项没定义。

添加CONFIG_IP_MULTICAST=y, 重编kernel img后,再次抓包能抓到设备发出的IGMP包了,实测问题解决。
 
这个问题调查过程中 发现在国内的站点上很少能搜到真正有帮助的信息,所以发这个帖子,也许你的问题与我不一样,但至少提供一个思路吧。
 
---------------------------转载请注明出处-----------------------
 

Android App用MulticastSocket监听组播,为什么连接到不同路由、在不同手机上跑,有的能收到有的收不到的更多相关文章

  1. Android对ScrollView滚动监听,实现美团、大众点评的购买悬浮效果

    转帖请注明本文出自xiaanming的博客(http://blog.csdn.net/xiaanming/article/details/17761431),请尊重他人的辛勤劳动成果,谢谢! 我之前写 ...

  2. Android EditText截获与监听输入事件

      Android EditText截获与监听输入事件共有2种方法: 1.第一种方法:使用setOnKeyListener(),不过这种方式只能监听硬键盘事件. edittext.setOnKeyLi ...

  3. Android Back Home键监听

    Android Back Home键监听 Back键的监听 对于Back键的监听比较容易,可以在多个系统回调处拦截,比如在activity的下列方法中都可以收到Back键按下的事件: @Overrid ...

  4. Android addTextChangedListener(文本监听)参数解释及实现EditText字数监听

    由于最近做项目要检测EditText中输入的字数长度,从而接触到了Android中EditText的监听接口,TextWatcher.它有三个成员方法,第一个after很简单,这个方法就是在EditT ...

  5. android事件处理之基于监听

    Android提供了了两种事件处理方式:基于回调和基于监听. 基于监听: 监听涉及事件源,事件,事件监听器.用注册监听器的方法将某个监听器注册到事件源上,就可以对发生在事件源上的时间进行监听. 最简单 ...

  6. Android 对电话进行监听和挂断

    1.添加权限 <!--拨打电话的权限--><uses-permission android:name="android.permission.PROCESS_OUTGOIN ...

  7. android应用锁之监听应用前后台切换方式

    今天在做技术总结,顺便就把知识共享,个人崇尚分享. 通过以下方式来监听是不是发生了应用的前后台切换: 1. android api 10 – 15 通过ActivityManager register ...

  8. Android——按钮的事件监听

    关于Button按钮的四种事件监听方法总结 首先我们在activity_main.xml里面先定义一个Button空间 <RelativeLayout xmlns:android="h ...

  9. Android EditText的输入监听,输入字符的动态获取

    http://itindex.net/detail/38974-android-edittext-%E7%9B%91%E5%90%AC 有时候我们可能会用到时时的监听EditText输入字符的时时监听 ...

随机推荐

  1. C#中的ODBC、OLEDB连接

      using System;using System.Collections.Generic;using System.Text;using System.Data.Odbc;using Syste ...

  2. ArrayList Iterator remove java.lang.UnsupportedOperationException

    在使用Arrays.asList()后调用add,remove这些method时出现 java.lang.UnsupportedOperationException异常.这是由于Arrays.asLi ...

  3. Rabin-Miller算法

    首先附上matrix67大神的讲解: --------------------------------------------------------------------------------- ...

  4. [NYOJ 43] 24 Point game

    24 Point game 时间限制:3000 ms  |  内存限制:65535 KB 难度:5   描述 There is a game which is called 24 Point game ...

  5. HTTP2.0那些事

    1. HTTP2.0的前世 http2.0的前世是http1.0和http1.1这两兄弟.虽然之前仅仅只有两个版本,但这两个版本所包含的协议规范之庞大,足以让任何一个有经验的工程师为之头疼.http1 ...

  6. C#中OpenFileDialog的使用

    string resultFile = ""; OpenFileDialog openFileDialog1 = new OpenFileDialog();            ...

  7. PV,UV,IP

    参加了DTCC归来之后,各大电商技术大牛都会自豪的分享一下自己公司网站的PV,流量等等.当时也是一知半解,回来之后赶紧查了查,也算是扫扫盲. 以下摘自网络中,自己稍稍做了整理,对于PV,流量和带宽的理 ...

  8. 读取编码为utf-16le的文件并打印

    import codecs data = open('test.txt').read()if data[:2] == codecs.BOM_UTF16_LE:    data = data[2:]  ...

  9. FFT矩阵

    举个例子: \[{F_4}=\left[{\begin{array}{*{20}{c}}1&1&1&1\\1&i&{-1}&{-i}\\1&{- ...

  10. 【CSS3】Advanced9:Transformation

    1.transform:rotate(-10deg) skew(20deg,10deg) scaling(2/1,2) translate/移动(100px,200px) 2.transform:ma ...