Android send udp broadcast silently fails(Android静默发送udp广播失败)
问题描述
我想通过使用网络的广播地址来实现服务发现.我正在使用 WireShark 嗅探数据包,以确认我的 UDP 数据包没有被发送.网络代码未在 UI 线程上运行.DatagramSocket.send 调用返回,没有抛出异常,但是包括 WireShark 在内的其他程序看不到任何异常.我已经验证了getWifiBroadcastAddress返回的地址实际上是我网络的广播地址.
I want to implement service discovery by using the network's broadcast address. I am sniffing packets with WireShark to confirm that my UDP packets are not being sent. The network code is not being run on the UI thread. The DatagramSocket.send call returns with no exception thrown, but nothing is seen by other programs including WireShark. I have verified that the address returned by getWifiBroadcastAddress actually is the broadcast address of my network.
我已经通过编写 C# 程序验证网络支持广播,在另一台机器上运行,并且 WireShark正在检测来自该程序的广播数据包.
I have verified that the network supports broadcast by writing a C# program, run on another machine, and WireShark is detecting broadcast packets from this program.
这是我的 Android Java 代码:
Here is my Android Java code:
try {
DatagramSocket socket = new DatagramSocket(Protocol.INQUIRY_PORT);
socket.setBroadcast(true);
InetAddress broadcastAddr = getWifiBroadcastAddress();
byte[] data = new byte[10];
for(int i = 0; i < data.length; i++) {
data[i] = (byte) i;
}
DatagramPacket packet = new DatagramPacket(data, data.length,
broadcastAddr, Protocol.INQUIRY_PORT);
while(true) {
// Loops indefinitely, no errors/exceptions
socket.send(packet);
try {
Thread.sleep(5000);
} catch(InterruptedException ie) {
break;
}
}
} catch(IOException ioe) {
// Not logged
Log.d("Broadcast", "Error sending inquiry.");
}
getWifiBroadcastAddress() 方法如下所示:https://lab.dyne.org/AndroidUDPBroadcast
The getWifiBroadcastAddress() method is as seen here: https://lab.dyne.org/AndroidUDPBroadcast
有谁知道为什么这会默默地失败?就像我说的,我在另一个机器上运行的 C# 程序运行良好,做同样的事情,每 5 秒发送一次相同的数据,WireShark 看到这些数据包,但 Android 手机没有.
Does anyone know why this would fail silently? Like I said my C# program running on another box is working just fine, doing the same thing, sending the same data every 5s, and WireShark sees those packets, but nothing from the Android phone.
推荐答案
以下对我有用,我可以将特定的字符串值广播到另一端的指定端口(在你的情况下为 Protocol.INQUIRY_PORT),并且本地子网上所有在该端口上监视 UDP 的设备都可以识别该字符串值,并相应地做出响应.我从主线程广播,但在异步任务中监听响应.
The following works for me, where I can broadcast a particular string value to a specified port (in your case Protocol.INQUIRY_PORT) on the other end(s), and all of the devices on the local subnet that are monitoring UDP on that port can recognize that string value, and accordingly can respond. I am broadcasting from the main thread, but listening for responses in an async task.
public void sendBroadcast(String messageStr) {
// Hack Prevent crash (sending should be done using an async task)
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
byte[] sendData = messageStr.getBytes();
try {
sendSocket = new DatagramSocket(null);
sendSocket.setReuseAddress(true);
//sendSocket.bind(new InetSocketAddress(Protocol.INQUIRY_PORT));
sendSocket.setBroadcast(true);
//Broadcast to all IP addresses on subnet
try {
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, InetAddress.getByName("255.255.255.255"), Protocol.INQUIRY_PORT);
sendSocket.send(sendPacket);
System.out.println(getClass().getName() + ">>> Request packet sent to: 255.255.255.255 (DEFAULT)");
} catch (Exception e) {
}
} catch (IOException e) {
Log.e(TAG, "IOException: " + e.getMessage());
}
}
以下是异步任务类中对应的 UDP 响应侦听器代码:
Following is the corresponding UDP response listener code inside an async task class:
protected String doInBackground(String... params) {
serverIP = "";
try {
//Keep a socket open to listen to all the UDP trafic that is destined for this port
InetAddress myHostAddr = InetAddress.getByName("0.0.0.0");
rcvSocket = new DatagramSocket(null);
rcvSocket.setReuseAddress(true);
rcvSocket.bind(new InetSocketAddress("0.0.0.0",Protocol.INQUIRY_PORT));
rcvSocket.setBroadcast(true);
while (true) {
Log.i("VIS","Ready to receive broadcast packets!");
//Receive a packet
byte[] recvBuf = new byte[15000];
DatagramPacket packet = new DatagramPacket(recvBuf, recvBuf.length);
rcvSocket.receive(packet);
//Packet received
serverIP = packet.getAddress().getHostAddress();
Log.i("VIS", "Packet received from: " + serverIP);
String data = new String(packet.getData()).trim();
Log.i("VIS", "Packet received; data: " + data);
if (!data.equals("") && !data.equals(myInquiryString)) {
//break while loop and return IP address of server
break;
}
}
} catch (IOException ex) {
Log.i("VIS", "ServerDiscovery" + ex.getMessage());
}
return serverIP;
}
这篇关于Android静默发送udp广播失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:Android静默发送udp广播失败
基础教程推荐
- 当从同一个组件调用时,两个 IBAction 触发的顺序是什么? 2022-01-01
- 如何让对象对 Cocos2D 中的触摸做出反应? 2022-01-01
- UIWebView 委托方法 shouldStartLoadWithRequest:在 WKWebView 中等效? 2022-01-01
- android 应用程序已发布,但在 google play 中找不到 2022-01-01
- 如何在没有IB的情况下将2个按钮添加到右侧的UINavigationbar? 2022-01-01
- Android:对话框关闭而不调用关闭 2022-01-01
- 在 gmail 中为 ios 应用程序检索朋友的朋友 2022-01-01
- 如何在 UIImageView 中异步加载图像? 2022-01-01
- 如何在 iPhone 上显示来自 API 的 HTML 文本? 2022-01-01
- Kivy Buildozer 无法构建 apk,命令失败:./distribute.sh -m “kivy"d 2022-01-01