局域网上的对等发现

5
所以,正如标题所暗示的那样,我的Java项目遇到了一些问题。我想做的是:
  • 我有两台运行应用程序X的计算机
  • 还有另外三台运行应用程序Y的计算机
我需要做的是在X和Y之间建立连接。例如,有人使用运行X的计算机,在发现过程后,他们将返回一个运行Y应用程序的计算机列表、它们的IP地址,反之亦然。
我已经使用UDP广播完成了这个任务,但有时会失败。这些计算机通过WiFi连接,基本上是通过路由器连接。在许多情况下,任何一个运行X的计算机都可以通过我的UDP发现方法看到Y计算机,但有时不行,除非我手动指定IP,有时甚至连手动指定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;
}

这是我的“服务器”:

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台电脑通过局域网连接,而Y台电脑通过WiFi连接,会有特殊情况吗?

1个回答

3
为什么有时候即使他们连接到同一个路由器,他们也看不到彼此?
这是因为广播使用UDP服务,它是一种无连接协议。使用UDP只需将数据包(数据报)发送到网络上的某个IP地址。您无法保证数据是否到达。
如果X台计算机通过LAN连接,而Y台计算机通过WiFi连接,是否有特殊情况?
即使X台计算机通过LAN连接,而Y台计算机通过WiFi连接,它们都属于同一个路由器的网络。因此,网络发现和网络服务都将可用。这不会有任何问题。这与您所遇到的情况没有任何区别!

谢谢清晰的信息,但是如果我发送数据包5-6次会怎样呢?我已经修改了代码,每次发送数据包大约5次,并且在每次发送后等待答复。但是如果这种方法不可靠,有没有其他更有效的方法可以使用呢?或者有没有更高成功率的方法呢?还有一个问题,如果我将IP地址从255.255.255.255和0.0.0.0改为广播IP地址会怎样呢?比如192.168.1.255(这个地址将事先计算好)。 - KiralyCraft
多播使用C类地址,并使用UDP服务进行。每次只能轮询/发送数据包,除此之外你无法做任何事情。另外,由于问题比较广泛,无法在评论中回答你的问题。请提出一个新的问题,寻求有关使用192.168.1.255进行广播的帮助! - Am_I_Helpful
非常感谢,我很快会提出一个关于C类广播的新问题 :D - KiralyCraft
抱歉,我打错了字母,应该是d而不是c。多播使用D类地址实现。再次对打错字感到抱歉。 - Am_I_Helpful

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接