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)传输:在发送者和每一接收者之间实现点对多点网络连接.如果一台发送者同时给多个的接收者传输相同的数据,也只需复制一份的相同数据包.它提高了数据传送效率.减少了骨干网络出现拥塞的 ...
随机推荐
- Django REST framework 自定义(认证、权限、访问频率)组件
本篇随笔在 "Django REST framework 初识" 基础上扩展 一.认证组件 # models.py class Account(models.Model): &qu ...
- C#学习笔记_11_方法的隐藏和重写
11_方法的隐藏和重写 方法的隐藏 需要使用到关键字:new 方法的重写 虚函数: 使用关键字virtual修饰的函数 虚函数可以被子类隐藏,也可以被子类重写 非虚函数只能被子类隐藏 关键字:over ...
- Linux - nginx基础及常用操作
目录 Linux - nginx基础及常用操作 Tengine淘宝nginx安装流程 nginx的主配置文件nginx.conf 基于域名的多虚拟主机实战 nginx的访问日志功能 网站的404页面优 ...
- 微信小程序·前端-锦囊
========================== flex[盒子] display: flex; flex-direction: column; [从上到下排列]↓ justify-conte ...
- Redis Expire TTL命令
Redis can be told that a key should only exist for a certain length of time. This is accomplished wi ...
- bug的分类和等级
一.bug的定义 软件的bug,狭义指软件程序的漏洞或缺陷,广义指测试工程师或用户提出的软件可改进的细节.或与需求文档存在差异的功能实现等 对应三个测试目的:(3个为了) 1.为了发现程序的代码或业务 ...
- SpringMVC demo 小例子,实现简单的登录和注册
1.创建一个动态的web工程 2.导入springMvc所需要的jar包(这里可以去网上找,资源有很多) 前两部就不详细描述了,后面才是正经代码~ 首先有一个web.xml文件,这个属于大配置文件,由 ...
- scrapy——8 scrapyd使用
scrapy——8 scrapyd使用 什么是scrapyd 怎么安装scrapyd 如何使用scrapyd--运行scrapyd 如何使用scrapyd--配置scrapy.cfg 如何使用s ...
- GlobalSign 增强型(EV) SSL 证书
GlobalSign 增强型(EV) SSL 证书,属于最高验证级别的EV SSL,验证域名所有权,进行严格的企业真实身份验证,证书标识企业组织机构名称,强化信任度,浏览器地址栏变绿色.提供40位/5 ...
- FORTIFY_SOURCE
In recent years Linux distributions started treating security more seriously. Out of many security f ...