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)传输:在发送者和每一接收者之间实现点对多点网络连接.如果一台发送者同时给多个的接收者传输相同的数据,也只需复制一份的相同数据包.它提高了数据传送效率.减少了骨干网络出现拥塞的 ...
随机推荐
- 熟悉RHEL7登录界面使用
Linux操作系统提供了图像界面和字符界面两种操作环境. 图像界面: 1.开启RHEL7后进入到该界面,图中用户是我们创建的本地用户,如果我们要以管理员身份登录则点击Not listed(未列出). ...
- file.seek()/tell()-笔记
---------------------------------------------------------------------------------------------------- ...
- tp5 微信支付开发流程
1.用户在选择商品后,向APi提交包含它所选择商品的相关信息. 2.APi在接收到信息后,需要检查订单相关商品的库存量. 3.有库存,把订单数据存入数据库中= 下单成功了,返回客户端消息,告诉客户端可 ...
- [TyvjP1515] 子串统计 [luoguP2408] 不同子串个数(后缀数组)
Tyvj传送门 luogu传送门 经典题 统计一个字符串中不同子串的个数 一个字符串中的所有子串就是所有后缀的前缀 先求出后缀数组,求出后缀数组中相邻两后缀的 lcp 那么按照后缀数组中的顺序遍历求解 ...
- java 垃圾收集
1.为什么使用垃圾收集 a.把用户从释放占用内存的重担中解救出来 b.帮助程序保持完整性 2.垃圾收集算法 检测出垃圾对象,必须回收垃圾对象所使用的堆空间并还给程序 垃圾检测:通过建立一个根对象集合并 ...
- F2BPM中关于工作流引擎驳回设计
1.1 关于驳回 驳回,在有的应用中叫“回退”.驳回是中国特色的一种方式,驳回在流程图上也没有迁移线的表达经常也是隐性的,比如申请经费可能由于资料不足被驳回来补充资料,像这样的例子有非常多,也很常见. ...
- Maven 的dependency 的 classifier的作用
直接看一个例子,maven中要引入json包,于是使用了 <dependency> <groupId>net.sf.json-lib</groupId> <a ...
- 查看编译器的默认include 路径
echo | gcc -v -x c++ -E - echo | g++ -v -x c++ -E - `gcc -print-prog-name=cc1plus` -v `g++ -print-pr ...
- MFC 小知识总结四
1 PlaySound 播放WAV格式的音乐 This function plays a sound specified by a file name, resource, or system ev ...
- iOS 代码方式设置按钮标题、图片的偏移
button.imageEdgeInsets = UIEdgeInsetsMake(0,1 , 2, 3); button.titleEdgeInsets = UIEdgeInsetsMake(0,1 ...