Android:SSDP 卡在 MulticastSocket.receive()
Posted
技术标签:
【中文标题】Android:SSDP 卡在 MulticastSocket.receive()【英文标题】:Android: SSDP stuck on MulticastSocket.receive() 【发布时间】:2014-04-07 18:38:37 【问题描述】:TL;DR: SSDP library 没有收到数据报。 Wireshark 显示预期的(?)流量。
我正在使用 android-dlna library 在 Android 应用中支持 SSDP。目标是发现支持 SSDP 的自定义设备,获取其 IP 地址,然后对其进行 RESTful API 调用。这在 ios 上运行良好,但我在 Android 上接收数据报时遇到了一些问题。
使用 Wireshark,我可以确定 SSDP 搜索结束,设备返回 OK 状态,但此循环永远不会超过 receive()
方法:
SSDPSearchMsg search = new SSDPSearchMsg(SSDP.ST_ContentDirectory);
Log.e("SSDP", search.toString());
SSDPSocket sock = null;
try
sock = new SSDPSocket();
sock.send(search.toString());
while (true)
Log.e("SSDP", "Receive...");//only called once (stuck here)
DatagramPacket dp = sock.receive();
Log.e("SSDP", "Datagram Received with data " + new String(dp.getData()));
catch (IOException e)
e.printStackTrace();
finally
Log.e("SSDP", "Closing Socket");
if (sock != null)
sock.close();
这一切都在AsyncTask
中完成。我看到以下打印到 logcat:
SSDP M-SEARCH * HTTP/1.1
SSDP Host:239.255.255.250:1900
SSDP Man:"ssdp:discover"
SSDP ST:urn:schemas-upnp-org:service:ContentDirectory:1
SSDP MX:3
SSDP
SSDP Receive...
Wireshark 报告以下相关数据报:
Source Destination Protocol Length Info
---------------------------------------------------------------------------
192.168.1.7 239.255.255.250 SSDP 175 M-SEARCH * HTTP/1.1
192.168.1.1 192.168.1.7 SSDP 356 HTTP/1.1 200 OK
最后,我拥有以下清单权限:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
我忽略了什么?为什么我没有收到响应数据报?
【问题讨论】:
我的代码和你的代码之间唯一的区别是我使用字节数组作为缓冲区而不是DatagramPacket dp = sock.receive();
,并使用DatagramPacket dp = new DatagramPacket(buf, buf.length);
。字节数组就是byte[] buf = new byte[1024];
。然后我打电话给mSSDPSocket.receive(dp);
,其中mSSDPSocket
是我的MulticastSocket
。
【参考方案1】:
我知道这是一个老问题,但它也让我感到困惑,所以也许这会帮助其他偶然发现这个问题的人。如果您没有获取到MulticastLock
,Android 会过滤掉多播数据包,因此更新代码以获取MulticastLock
并在完成后释放它。
final WifiManager wifi = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
WifiManager.MulticastLock lock = wifi.createMulticastLock("ssdp");
try
lock.acquire();
sock = new SSDPSocket();
sock.send(search.toString());
while (true)
Log.e("SSDP", "Receive...");//only called once (stuck here)
DatagramPacket dp = sock.receive();
Log.e("SSDP", "Datagram Received with data " + new String(dp.getData()));
catch (IOException e)
e.printStackTrace();
finally
Log.e("SSDP", "Closing Socket");
if (sock != null)
sock.close();
if(lock.isHeld())
lock.release();
需要以下权限(已经在 OP 的清单文件中)--
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE"/>
【讨论】:
以上是关于Android:SSDP 卡在 MulticastSocket.receive()的主要内容,如果未能解决你的问题,请参考以下文章