Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Peer to Peer discovery on LAN

So, as the title might have suggested I am having a bit of trouble in my Java project. What I want to do is this:

  • I have two Computers running application X
  • Also have another three Computers running application Y

What i need to do is to establish a connection between a X and an Y. For example, someone uses the computer running X, and after the discovrey process, they will be returned a list of computers running the Y app, and their IP, and the other way around.

I've done this using UDP broadcasting, but sometimes it fails. The computers are connected via WiFi, so basically through a router. On many occasions, any of the X computers can see the Y ones via my UDP discovery method, but sometimes not, unless I manually point the IP, sometimes not even then.

Here is a code for discovering servers listening on a specific port:

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;
}

And here is my "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());
        }
    }
}

Why sometimes they can't see each other, even if they are connected to the same router? EXTRA: Is there a special case, the X computers are connected via LAN, and the Y ones via WiFi?

like image 625
KiralyCraft Avatar asked Oct 19 '22 19:10

KiralyCraft


1 Answers

Why sometimes they can't see each other, even if they are connected to the same router?

Because Broadcasting is done using UDP services which are connectionless protocols. With UDP you just send packets of data (datagrams) to some IP address on the network. You have no guarantee that the data will arrive.

Is there a special case, the X computers are connected via LAN, and the Y ones via WiFi?

Even, the X cmputers are connected via LAN and the Y ones via WiFi, they all belong to the same network of router. Hence,network-discovery and network-services will be available. There won't be any problem with that. It's all fair and not different than the case which you're having!

like image 69
Am_I_Helpful Avatar answered Nov 03 '22 04:11

Am_I_Helpful