局域网上的点对点发现
Peer to Peer discovery on LAN
因此,正如标题所暗示的那样,我在 Java 项目中遇到了一些麻烦。我想做的是:
- 我有两台电脑运行 应用程序 X
- 还有另外三台电脑运行申请Y
我需要做的是在X和Y之间建立连接。例如,某人使用计算机运行 X,发现过程后,将返回一个计算机列表运行 Y 应用及其 IP,反之亦然。
我已经使用 UDP 广播完成了此操作,但有时会失败。计算机通过 WiFi 连接,所以基本上是通过路由器。在很多情况下,任何 X 计算机都可以通过我的 UDP 发现方法看到 Y 计算机,但有时不能,除非我手动指向 IP,有时甚至不能。
下面是一段用于发现侦听特定端口的服务器的代码:
public static ArrayList<InetAddress> searchComputer() {
ArrayList<InetAddress> targets = new ArrayList<InetAddress>();
try {
c = new DatagramSocket();
c.setBroadcast(true);
byte[] sendData = "DISCOVER_PC_SERVER_REQUEST".getBytes();
try {
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, InetAddress.getByName("255.255.255.255"), 2005);
c.send(sendPacket);
} catch (Exception e) {}
Enumeration interfaces = NetworkInterface.getNetworkInterfaces();
while (interfaces.hasMoreElements()) {
NetworkInterface networkInterface = (NetworkInterface) interfaces.nextElement();
if (networkInterface.isLoopback() || !networkInterface.isUp()) {
continue;
}
for (InterfaceAddress interfaceAddress : networkInterface.getInterfaceAddresses()) {
InetAddress broadcast = interfaceAddress.getBroadcast();
if (broadcast == null) {
continue;
}
try {
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, broadcast, 8888);
c.send(sendPacket);
} catch (Exception e) { }
}
}
byte[] recvBuf = new byte[15000];
DatagramPacket receivePacket = new DatagramPacket(recvBuf, recvBuf.length);
if (useInstant) {
c.setSoTimeout(500);
}
else {
c.setSoTimeout(4000); //EXECUTE THE WHILE FOR 4 SECONDS, THEN RETURN WHATEVER THE RESULTS ARE.
}
while (true) {
c.receive(receivePacket);
String message = new String(receivePacket.getData()).trim();
if (message.equals("DISCOVER_PC_SERVER_RESPONSE")) {
// return receivePacket.getAddress();
targets.add(receivePacket.getAddress());
}
}
// c.close();
} catch (IOException ex){}
return targets;
}
这是我的 "server":
private void start_Discovery() throws Exception {
//Keep a socket open to listen to all the UDP trafic that is destined for this port
socket = new DatagramSocket(2005, InetAddress.getByName("0.0.0.0"));
socket.setBroadcast(true);
while (true) {
// System.out.println(getClass().getName() + ">>>Ready to receive broadcast packets!");
//Receive a packet
byte[] recvBuf = new byte[15000];
DatagramPacket packet = new DatagramPacket(recvBuf, recvBuf.length);
socket.receive(packet);
//Packet received
// System.out.println(getClass().getName() + ">>>Discovery packet received from: " + packet.getAddress().getHostAddress());
// System.out.println(getClass().getName() + ">>>Packet received; data: " + new String(packet.getData()));
//See if the packet holds the right command (message)
String message = new String(packet.getData()).trim();
if (message.equals("DISCOVER_ANDROID_SERVER_REQUEST")) {
byte[] sendData = "DISCOVER_ANDROID_SERVER_RESPONSE".getBytes();
//Send a response
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, packet.getAddress(), packet.getPort());
socket.send(sendPacket);
// System.out.println(getClass().getName() + ">>>Sent packet to: " + sendPacket.getAddress().getHostAddress());
}
}
}
为什么有时他们看不到对方,即使他们连接到同一个路由器?
EXTRA: 有没有特殊情况,X台电脑通过LAN连接,Y台电脑通过WiFi连接?
Why sometimes they can't see each other, even if they are connected to
the same router?
因为广播是使用无连接协议的 UDP 服务完成的。使用 UDP,您只需将数据包(数据报)发送到网络上的某个 IP 地址。您无法保证数据一定会到达。
Is there a special case, the X computers are connected via LAN, and
the Y ones via WiFi?
甚至,X台计算机通过LAN连接,Y台计算机通过WiFi连接,它们都属于同一个路由器网络。因此,网络发现和网络服务将可用。不会有任何问题的。这一切都很公平,与您遇到的情况没有什么不同!
因此,正如标题所暗示的那样,我在 Java 项目中遇到了一些麻烦。我想做的是:
- 我有两台电脑运行 应用程序 X
- 还有另外三台电脑运行申请Y
我需要做的是在X和Y之间建立连接。例如,某人使用计算机运行 X,发现过程后,将返回一个计算机列表运行 Y 应用及其 IP,反之亦然。
我已经使用 UDP 广播完成了此操作,但有时会失败。计算机通过 WiFi 连接,所以基本上是通过路由器。在很多情况下,任何 X 计算机都可以通过我的 UDP 发现方法看到 Y 计算机,但有时不能,除非我手动指向 IP,有时甚至不能。
下面是一段用于发现侦听特定端口的服务器的代码:
public static ArrayList<InetAddress> searchComputer() {
ArrayList<InetAddress> targets = new ArrayList<InetAddress>();
try {
c = new DatagramSocket();
c.setBroadcast(true);
byte[] sendData = "DISCOVER_PC_SERVER_REQUEST".getBytes();
try {
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, InetAddress.getByName("255.255.255.255"), 2005);
c.send(sendPacket);
} catch (Exception e) {}
Enumeration interfaces = NetworkInterface.getNetworkInterfaces();
while (interfaces.hasMoreElements()) {
NetworkInterface networkInterface = (NetworkInterface) interfaces.nextElement();
if (networkInterface.isLoopback() || !networkInterface.isUp()) {
continue;
}
for (InterfaceAddress interfaceAddress : networkInterface.getInterfaceAddresses()) {
InetAddress broadcast = interfaceAddress.getBroadcast();
if (broadcast == null) {
continue;
}
try {
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, broadcast, 8888);
c.send(sendPacket);
} catch (Exception e) { }
}
}
byte[] recvBuf = new byte[15000];
DatagramPacket receivePacket = new DatagramPacket(recvBuf, recvBuf.length);
if (useInstant) {
c.setSoTimeout(500);
}
else {
c.setSoTimeout(4000); //EXECUTE THE WHILE FOR 4 SECONDS, THEN RETURN WHATEVER THE RESULTS ARE.
}
while (true) {
c.receive(receivePacket);
String message = new String(receivePacket.getData()).trim();
if (message.equals("DISCOVER_PC_SERVER_RESPONSE")) {
// return receivePacket.getAddress();
targets.add(receivePacket.getAddress());
}
}
// c.close();
} catch (IOException ex){}
return targets;
}
这是我的 "server":
private void start_Discovery() throws Exception {
//Keep a socket open to listen to all the UDP trafic that is destined for this port
socket = new DatagramSocket(2005, InetAddress.getByName("0.0.0.0"));
socket.setBroadcast(true);
while (true) {
// System.out.println(getClass().getName() + ">>>Ready to receive broadcast packets!");
//Receive a packet
byte[] recvBuf = new byte[15000];
DatagramPacket packet = new DatagramPacket(recvBuf, recvBuf.length);
socket.receive(packet);
//Packet received
// System.out.println(getClass().getName() + ">>>Discovery packet received from: " + packet.getAddress().getHostAddress());
// System.out.println(getClass().getName() + ">>>Packet received; data: " + new String(packet.getData()));
//See if the packet holds the right command (message)
String message = new String(packet.getData()).trim();
if (message.equals("DISCOVER_ANDROID_SERVER_REQUEST")) {
byte[] sendData = "DISCOVER_ANDROID_SERVER_RESPONSE".getBytes();
//Send a response
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, packet.getAddress(), packet.getPort());
socket.send(sendPacket);
// System.out.println(getClass().getName() + ">>>Sent packet to: " + sendPacket.getAddress().getHostAddress());
}
}
}
为什么有时他们看不到对方,即使他们连接到同一个路由器? EXTRA: 有没有特殊情况,X台电脑通过LAN连接,Y台电脑通过WiFi连接?
Why sometimes they can't see each other, even if they are connected to the same router?
因为广播是使用无连接协议的 UDP 服务完成的。使用 UDP,您只需将数据包(数据报)发送到网络上的某个 IP 地址。您无法保证数据一定会到达。
Is there a special case, the X computers are connected via LAN, and the Y ones via WiFi?
甚至,X台计算机通过LAN连接,Y台计算机通过WiFi连接,它们都属于同一个路由器网络。因此,网络发现和网络服务将可用。不会有任何问题的。这一切都很公平,与您遇到的情况没有什么不同!