Android上UDP组播无法接收数据的问题
最近,想做一个跨平台的局域网的文件传输软件,思路是组播设备信息,TCP连接传输文件。于是进行了一次简单的UDP组播测试,发现Android对于UDP组播接收数据的支持即极为有限。
部分代码如下
package com.hsocket.Udp; import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket; public class UdpReceiver {
protected DatagramSocket client=null;
private OnReceiveListener mOnReceiveListener=null;
private Thread thrRecv=null;
protected int port=0;
public UdpReceiver(int port){
this.port=port;
}
protected DatagramSocket Create() throws IOException{
return new DatagramSocket(this.port);
}
public void addOnReceiveListener(OnReceiveListener mOnReceiveListener){
this.mOnReceiveListener=mOnReceiveListener;
}
public void Stop(){
if(this.thrRecv!=null) this.thrRecv.interrupt();
this.Close();
}
public void Listen() throws IOException{
this.Close();
this.client=this.Create();
if(this.thrRecv!=null) this.thrRecv.interrupt();
this.thrRecv=new Thread(new Runnable() {
@Override
public void run() {
while(!Thread.interrupted()){
ReceiveEventArgs args=new ReceiveEventArgs();
try {
DatagramPacket packet=UdpReceiver.this.Receive();
args.Address=packet.getAddress();
args.Result=packet.getData();
args.Length=packet.getLength();
args.Error=false;
} catch (IOException e) {
e.printStackTrace();
args.Exception=e;
args.Error=true;
}
UdpReceiver.this.OnReceive(args);
if(UdpReceiver.this.mOnReceiveListener!=null)
UdpReceiver.this.mOnReceiveListener.OnReceive(UdpReceiver.this, args);
}
}
});
this.thrRecv.start();
}
protected DatagramPacket Receive() throws IOException{
byte[] recvBuf = new byte[4096];
DatagramPacket recvPacket= new DatagramPacket(recvBuf , recvBuf.length);
this.client.receive(recvPacket);
return recvPacket;
}
protected void Close(){
if(this.client!=null) this.client.close();
}
protected void OnReceive(ReceiveEventArgs args){ }
}
package com.hsocket.Udp; import java.io.IOException;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.MulticastSocket; public class UdpMultcastReceiver extends UdpReceiver { private InetAddress multicastAddr=null;
public UdpMultcastReceiver(InetAddress multicastAddr,int port) {
super(port);
this.multicastAddr=multicastAddr;
} @Override
protected DatagramSocket Create() throws IOException {
MulticastSocket socket=new MulticastSocket(this.port);
socket.joinGroup(this.multicastAddr);
socket.setLoopbackMode(false);
return socket;
}
}
发现UDP组播接收数据在部分机型存在问题,与系统有极大关系。小米、华为的手机的深度定制系统对UDP的封杀极为严重。
首先是组播锁,Android的Wifi,默认情况下是不接受组播的,详见:http://developer.android.com/reference/android/net/wifi/WifiManager.MulticastLock.html
要想打开组播功能,有以下几个步骤:
- 在Manifest文件中加入:android.permission.CHANGE_WIFI_MULTICAST_STATE,这个权限
- 获取到MulticastLock对象,这个对象不能直接实例化,要通过WifiManager间接得到,工厂模式
- 调用MulticastLock对象的acquire方法,获取到组播锁
- 相应的,用完组播,为了不浪费电力,要调用MulticastLock的release方法释放锁
WifiManager wifiManager=(WifiManager)getSystemService(Context.WIFI_SERVICE);
multicastLock=wifiManager.createMulticastLock("multicast.test");
multicastLock.acquire();
其次,即使获取到组播锁,但部分机型依旧无法接收到广播,因为部分Android手机有多网卡,默认是本地回环网卡,IP为127.0.0.1,无法加入组播,需用MulticastSocket::setNetworkInterface来设置组播网卡
mMulticastSocket.setNetworkInterface(NetworkInterface.getByName("wlan0"));
Android上UDP组播无法接收数据的问题的更多相关文章
- Android设备一对多录屏直播--(UDP组播连接,Tcp传输)
原文:https://blog.csdn.net/sunmmer123/article/details/82734245 近期需要学习流媒体知识,做一个Android设备相互投屏Demo,因此找到了这 ...
- ffmpeg笔记——UDP组播接收总结
ffmpeg在avformat_open_input里面已经实现了UDP的协议,所以只需要设置好参数,将url传递进去就可以了. 和打开文件的方式基本一样: 01 AVCodecContext *pV ...
- 多网卡情况下接收udp组播
多网卡下接收udp组播 往往会接收失败 因为用错了网卡 例如我想要接收2网段 其他电脑出的udp组播 我电脑有有线网和wifi在window下可以这样 route add 230.0.0.1 mas ...
- C# 使用UDP组播实现局域网桌面共享
最近需要在产品中加入桌面共享的功能,暂时不用实现远程控制:参考了园子里的一些文章,加入了一些自己的修改. 需求:将一台机器的桌面通过网络显示到多个客户端的屏幕上,显示内容可能为PPT,Word文档之类 ...
- 【网络开发】UDP组播接收端解析
UDP组播接收端解析 网络中的一台主机如果希望能够接收到来自网络中其它主机发往某一个组播组的数据报,那么这么主机必须先加入该组播组,然后就可以从组地址接收数据包.在广域网中,还涉及到路由器支持组播路由 ...
- (转)C# 使用UDP组播实现局域网桌面共享
转:http://www.cnblogs.com/mobwiz/p/3715743.html 最近需要在产品中加入桌面共享的功能,暂时不用实现远程控制:参考了园子里的一些文章,加入了一些自己的修改. ...
- Android开发:组播(多播)与广播
近期由于需要编写能够使同一局域网中的Android客户端与PC端进行自动匹配通信功能的程序,学习并试验了JAVA组播与广播的内容,记录一些理解如下: 一.组播(多播) 背景知识:组播使用UDP对一定范 ...
- Android MulticastSocket IP组播
MulticastSocket是对等的关系,也就是他们通过IP多点组播保留的地址来相互接收在这个组的Socket发送的消息 我写了一个例子,MultiSocketB是一个service,用于先接收再发 ...
- 桌面共享UDP组播实现
组播(Multicast)传输:在发送者和每一接收者之间实现点对多点网络连接.如果一台发送者同时给多个的接收者传输相同的数据,也只需复制一份的相同数据包.它提高了数据传送效率.减少了骨干网络出现拥塞的 ...
随机推荐
- 使用python的几个小经验(查看文档)
好久没有水博客了,未来再过20天不到的时间又得参加软考,今天终于得好好水一发帖子 关于Python,很多人包括我之前都不知道怎么找文档,现在有一个好办法,就是在命令行模式下调用pydoc –p xxx ...
- Aizu - 1379 Parallel Lines
平行直线 题意:给出一些点,这些点两两相连成一条直线,问最多能连成多少条直线. 思路:暴力出奇迹!!记得当时比赛做这道题的时候一直依赖于板子,结果却限制了自己的思路,这得改.dfs直接暴力,但是需要将 ...
- Huawei-R&S-网络工程师实验笔记20190609-VLAN划分综合(Access和Trunk端口)
>Huawei-R&S-网络工程师实验笔记20190609-VLAN划分综合(Access和Trunk端口) >>实验开始,先上拓扑图参考: >>>实验目标 ...
- vue 使用echarts
import echarts from 'echarts' <div id="kocGrow" style="width: 600px;height: 300p ...
- Django——8 关系表的数据操作 表关联对象的访问 多表查询
Django 关系表中的数据操作 表关联对象的访问 关联对象的add方法 create方法 remove方法 clear方法 多表查询 查询补充 聚合查询 分组查询 F查询 Q查询 关系表的数据操作 ...
- 申请SSL证书怎样验证域名所有权
申请域名型证书时,系统将提供以下三种方式验证域名的所有权,请根据自己的实际情况选择其中一种进行域名验证: 1.管理员邮箱验证 系统会向你选择的管理员邮箱 发送验证邮件,能够收到验证邮件,并点击邮件中验 ...
- C# WPF 窗体传递消息
对于存在窗体的WPF程序(或者说,起码在任务栏上有个图标,即ShowInTaskbar = true),互相传递消息是很容易的. 步骤: 1,寻找窗体的句柄 2,运用windows API: Send ...
- [cogs736][网络流24题#13]星际转移[网络流,网络判定]
将一个空间站分为天数个点,每次枚举天数,每增加一天就把对应天数的边连上,用网络流判定可行性,即-判断最大流是否不小于k,注意编号不要错位.通过此题,可见一些网络流题目需要用到网络判定方法,但虽然答案具 ...
- hdu_hpu第八次周赛_1001 To and Fro 201310270918
To and Fro Time Limit : 2000/1000ms (Java/Other) Memory Limit : 65536/32768K (Java/Other) Total Su ...
- SpringBoot多数据源改造(二)
在上一篇的内容中,主要介绍了spring boot项目的多数据源改造的涉及的基本配置及改动.在spring项目中,常用Mybatis做ORM操作数据库,并且分页操作是避免不了的. 因此,这一篇主要介绍 ...