【发布时间】:2015-07-31 14:57:20
【问题描述】:
我正在尝试在 Android 设备和 Windows 计算机之间建立对等发现解决方案。我只是一种“广播等待响应”的方法。我的问题是广播消息的应用程序也等待响应同时。
是这样的:
线程 A: 等待消息,我们称之为“X”。当它收到一个 UDP 数据包时,如果消息是“X”,它会发送一个 UDP 数据包BACK TO THE SENDER(不再广播),我们应该称之为“Y”。
THERAD B:在整个网络中广播“X”。然后收集所有回复“Y”的发件人的地址。
线程 A 和 B 在同一时间运行并且不能互相停止或暂停。
当线程 B 广播 X 时,线程 A(在同一设备/计算机上)接收到消息,因此与 .. 自身建立连接。
这是我当前的代码:
public static void launchDiscovery () throws Exception
{
DatagramSocket socket = new DatagramSocket(2005, InetAddress.getByName("0.0.0.0"));
socket.setBroadcast(true);
while (true) {
byte[] recvBuf = new byte[15000];
DatagramPacket packet = new DatagramPacket(recvBuf, recvBuf.length);
socket.receive(packet);
String message = new String(packet.getData()).trim();
// if (message.equals("SMARTSHARE_REQUEST"))
// if (message.equals("SMARTSHARE_REQUEST")&&!isTheSamePC(packet.getAddress())) //TODO fix here
if (message.equals("SS_REQ") && !isTheSamePC(packet.getAddress())) //TODO fix here
{
byte[] sendData = "SS_RESP".getBytes();
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, packet.getAddress(), packet.getPort());
socket.send(sendPacket);
}
}
}
private static boolean isTheSamePC(InetAddress address)
{
// Broadcast the message over all the network interfaces
try
{
Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
while (interfaces.hasMoreElements())
{
NetworkInterface networkInterface = (NetworkInterface) interfaces.nextElement();
if (networkInterface.isLoopback() || !networkInterface.isUp()) {
continue; // Don't want to broadcast to the loopback interface
}
for (InterfaceAddress interfaceAddress : networkInterface.getInterfaceAddresses())
{
if (address.getHostAddress().equals(interfaceAddress.getAddress().getHostAddress()))
{
return true;
}
}
}
}
catch(Exception e)
{
e.printStackTrace();
}
return false;
}
如何避免在没有任何第三方 API 的情况下发送给自己?这个方法有效,但是有点慢,我也想要更快的方法。
【问题讨论】:
-
显然,您只需要忽略来自您自己的任何东西,无论是基于其源地址还是基于其中编码的身份信息。
-
这就是重点。 “源地址”方法有点慢,应用程序必须遍历所有网络接口并获取计算机的所有 IP,因为对所有网络接口进行广播。这在某些计算机上可能会很慢。身份信息呢?既然两个线程是分开的,怎么可能做到这一点?
-
这可能不是您的问题,但万一获取接口需要时间,如果您在 之前缓存地址列表和接口列表,您可以有效地立即完成开始发送或检查收到的数据包。很可能时间花在了其他地方。在身份信息方面,你只需要一个唯一的(足够的)令牌。单独的线程并不意味着您不能共享数据 - 在它们启动之前建立数据尤其容易。
-
如果我在应用程序启动之前捕获了地址列表,但用户已断开 WiFi 连接,或者切换了网络,该怎么办?我想我会选择令牌,我相信这是实现这一目标的最佳方式
标签: java android multithreading sockets networking