ssdp 在android上的一些问题 01.07 更新 01.08再次更新
来源:互联网 发布:儿童教育软件哪种好 编辑:程序博客网 时间:2024/06/03 17:34
只用MulticastLock是不够的。
先看ubuntu miniDLNA/android BubleUPnP 的抓包例子:
# 192.168.2.103:33940 --> 239.255.255.250:1900
M-SEARCH * HTTP/1.1
Man: "ssdp:discover"
Mx: 3
Host: 239.255.255.250:1900
St: ssdp:all
# 192.168.2.109:1900 --> 192.168.2.103:33940
HTTP/1.1 200 OK
CACHE-CONTROL: max-age=1810
DATE: Mon, 05 Jan 2015 15:27:27 GMT
ST: uuid:4d696e69-444c-164e-9d41-206a8a7025d1
USN: uuid:4d696e69-444c-164e-9d41-206a8a7025d1
EXT:
SERVER: 3.13.0-43-generic DLNADOC/1.50 UPnP/1.0 MiniDLNA/1.1.4
LOCATION: http://192.168.2.109:8200/rootDesc.xml
Content-Length: 0
miniDLNA是开源的C代码,而我只关心android上怎么实现dlna client, 无赖BubleDLNA是闭源的。网上搜了一个例子UpnpDemo[1],核心部分是cling[2]。
而我关心的是里面的AndroidRouter。
# AndroidRouter
super.lock();
setWiFiMulticastLock(true);
setWifiLock(true);
# RouterImpl.enable()
## lock(writeLock)
ReentrantReadWriteLock routerLock = new ReentrantReadWriteLock(true);
Lock readLock = routerLock.readLock();
Lock writeLock = routerLock.writeLock();
lock.tryLock(timeoutMilliseconds, TimeUnit.MILLISECONDS);
lock.unlock();
## createNetworkAddressFactory
import java.net.NetworkInterface;
System.setProperty("java.net.preferIPv4Stack", "true");
NetworkInterface iface \in NetworkInterface.getNetworkInterfaces();
iface.getName() \in System.getProperty(SYSTEM_PROPERTY_NET_IFACES);
iface.getDisplayName(); //wlan0
InetAddress addr = iface.getInetAddresses();
addr.getHostAddress() \in System.getProperty(SYSTEM_PROPERTY_NET_ADDRESSES);
addr instanceof Inet4Address
addr.isLoopbackAddress()
addr.getHostAddress();
InterfaceAddress faddr \in iface.getInterfaceAddresses();
faddr.getBroadcast();
faddr.getAddress() instanceof InetAddress
faddr.getNetworkPrefixLength();
## MulticastReceiver multicastReceiver = createMulticastReceiver()
### init
InetSocketAddress addr = new InetSocketAddress(, port);
MulticastSocket socket = new MulticastSocket(port);
socket.setReuseAddress(true);
socket.setReceiveBufferSize(32768);
socket.joinGroup(multicastAddress, faddr);
### run
byte[] buf = new byte[640];
DatagramPacket datagram = new DatagramPacket(buf, buf.length);
socket.receive(datagram);
### stop
socket.isClosed();
socket.leaveGroup(multicastAddress, faddr);
socket.close();
测试发现上面的receiive已经可以收到udp了。下面的不必要,只是为了完整起见放在这里。
## createStreamServer
### init
localAddress = new InetSocketAddress(addr, 0);
socket = new MulticastSocket(localAddress);
socket.setTimeToLive(4);
socket.setReceiveBufferSize(262144);
### run
byte[] buf = new byte[640];
DatagramPacket datagram = new DatagramPacket(buf, buf.length);
socket.receive(datagram);
datagram.getAddress().getHostAddress();
datagram.getPort();
## createStreamClient
### createRequest http GET/POST
杂项
# isWifi
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo(); //.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
networkInfo.isAvailable();
networkInfo.isConnected();
NetworkInfo networkInfo.getType():
ConnectivityManager.TYPE_WIFI
ConnectivityManager.TYPE_MOBILE
9 //Ethernet since api 13
代码
talk is cheap, show me the code -- 根据AndroidRouter写一个最简版的demo:
https://github.com/DeYangLiu/AndroidPlayer/commit/cb3dd172df8838dd40952342ef0133be1f39d357
测试时不需ndk, 只需把AndroidManifest.xml里面的intent filter注释打开即可。
小结: Android组播需要注意的地方
* InetAddress.getLocalHost() 返回的是 "127.0.0.1"。
* WifiManager.MulticastLock 应该放在joinGroup后面。
# 01.08
感觉说了上面两条没底气,今天来验证了下:
Log.v("gw", "==Inet=" + NetworkInterface.getByInetAddress(InetAddress.getLocalHost()).getDisplayName()); 打印的是lo,当然收不到别人的组播啦。
WifiManager.MulticastLock 放在joinGroup前面也可以的。
更正结论:
* 要选择正确的网络接口,通常是wlan0,才能接收组播数据。
* 组播和广播接收发送为了省电默认是关闭的, 需要用WifiManager.MulticastLock.acquire()打开;由于它耗电,acquire/release圈起来的代码要求尽可能的少。
Ref
[1] http://blog.csdn.net/ljx19900116/article/details/42272095
[2] https://github.com/4thline/cling
- ssdp 在android上的一些问题 01.07 更新 01.08再次更新
- Android Studio离线更新的一些问题
- 关于应用程序从AppStore上更新的一些问题处理
- 关于数据表映射在更新时候出现的一些问题
- iOS项目更新之升级Xcode7 & iOS9 包括Xcode7在iOS9上测试时出现的一些问题
- Android开发jni遇到的一些问题,持续更新
- 在google play上更新android版本
- Android应用在更新版本时的出现的问题
- Android SDK在eclipse中更新的URL问题
- 更新android SDK的问题
- 更新android出现的问题
- Android的SDK更新问题
- 使用Vista的一些问题[持续更新]
- mybatis批量新增,更新的一些问题
- mybatis批量更新的一些问题
- OleDbCommand更新数据的一些问题
- Handler 更新UI的一些细节问题
- 更新Xcode8遇到的一些问题总结
- java计算程序(算法)执行时间
- 利用Android手机抓取蓝牙日志包
- Jackson学习一之对象与JSON互相转化
- Android Studio初体验之启动AVD模拟器异常:cannot set up guest memory 'pc.ram'
- java中字节流和字符流的总结
- ssdp 在android上的一些问题 01.07 更新 01.08再次更新
- linux如何安装eclipse
- 随便写写
- IPAddress,IPEndPoint,IPHostEntry介绍
- [leetcode]Word Break
- CodeForces 472D Design Tutorial: Inverse the Problem (最小生成树)
- Windows8.1企业版 安装Sql Server 2008 r2
- 线性结构(二) - 栈的原理与实现
- Pip 命令使用详解