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)传输:在发送者和每一接收者之间实现点对多点网络连接.如果一台发送者同时给多个的接收者传输相同的数据,也只需复制一份的相同数据包.它提高了数据传送效率.减少了骨干网络出现拥塞的 ...
随机推荐
- Linux系统学习之 一:新手必须掌握的Linux命令1
2018-10-03 16:04:12 一.常用系统工作命令 1.wget 命令 作用:用于在终端中下载网络文件. 格式:wget [参数] 下载地址 参数及作用: -b : 后台下载模式 -d:显示 ...
- Git 基础教程 之 别名
配置别名, 例如: git config --global alias.st status git config ...
- time库
简介 返回系统当前时间戳(正常的生活时间) 返回格林威治时间戳对应的struct_time对象 本地时间的struct_time对象 当前时间戳对应的易读格式字符串时间(周几,月份,号数,时,分,秒, ...
- 【郑轻邀请赛 H】 维克兹的进制转换
[题目链接]:https://acm.zzuli.edu.cn/zzuliacm/problem.php?id=2134 [题意] [题解] 设f[i]表示数字i分解为二进制数的方案数; 则 如果i为 ...
- BZOJ——T 4563: [Haoi2016]放棋子
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 387 Solved: 247[Submit][Status][Discuss] Descriptio ...
- [转]WCF的几种寄宿方式
转自:WCF开发框架形成之旅---WCF的几种寄宿方式 WCF寄宿方式是一种非常灵活的操作,可以在IIS服务.Windows服务.Winform程序.控制台程序中进行寄宿,从而实现WCF服务的运行,为 ...
- javac compiling error ( mising package)
javac 编译java源文件时,提示 package does not exist 的错误 Test.java import java.security.MessageDigest; import ...
- ubuntu 14.04升级PHP5.5.9 到5.6
升级的步骤:参考https://www.digitalocean.com/community/questions/how-to-upgrade-from-php-v-5-5-9-to-v-5-6 su ...
- springmvc mybatis 分页插件 pagehelper
springmvc mybatis 分页插件 pagehelper 下载地址:pagehelper 4.2.1 , jsqlparser 0.9.5 https://github.com/pagehe ...
- 多工程联编的Pods如何设置
多工程联编的Pods如何设置 (2014-07-17 13:57:10) 转载▼ 标签: 联编 多工程 分类: iOS开发 如今,CocoaPods使用越来越多,几乎每个项目都会使用到.有时候我们的项 ...