IP Autodiscovery

2020-06-06 06:36发布

问题:

I have to network devices: 1. Server (variable IP) that needs to receive a String for further stuff (e.g. Socket 9999). This server has also another socket (e.g. 8888) where it sends it's device name on pairing. 2. Client (variable IP) that does NOT know the IP of the server but wants to send him the string.

On a IP C-network I could iterate through the last octet (0..255) and check if Socket 8888 transmits something. But on A and B networks I have no chance. Is there any other solution for this? (I could iterate through all four octets but that wouldn't be an elegant solution).

Thank you!

回答1:

The most appropriate way to do it, if they are in the same LAN is:

  • Client sends a UDP broadcast to a specific port and matching the network class (A,B,C)
  • Server is listening on this port, receives the broadcast packet and connect or send his IP to the client.

With just two network packets you know the IP address.

--EDITED--

To broadcast:

InetAddress broadcastAddr = SharedFunctions.getNetworkLocalBroadcastAddressdAsInetAddress();

    DatagramSocket socket = null;
    try {
        socket = new DatagramSocket();
        socket.setBroadcast(true);
        System.arraycopy(BROADCAST_SIGNATURE, 0, buffSend, 0, BROADCAST_SIGNATURE.length);
        DatagramPacket packet = new DatagramPacket(buffSend, buffSend.length, broadcastAddr, BROADCAST_PORT);
        socket.send(packet);
    } catch (Exception e) {
        e.printStackTrace();
        if(socket != null) try {socket.close();} catch (Exception e1) {}
    }


public static InetAddress getNetworkLocalBroadcastAddressdAsInetAddress() throws IOException {
    for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
        NetworkInterface intf = en.nextElement();
        if(VERSION.SDK_INT < 9) { 
            if(!intf.getInetAddresses().nextElement().isLoopbackAddress()){
                byte[] quads = intf.getInetAddresses().nextElement().getAddress();
                quads[0] = (byte)255;
                return InetAddress.getByAddress(quads);
            }
        }else{
            if(!intf.isLoopback()){
                List<InterfaceAddress> intfaddrs = intf.getInterfaceAddresses();
                return intfaddrs.get(0).getBroadcast(); //return first IP address
            }
        }
    }
    return null;
}

To receice broadcast:

        try {
            socketReceiver = new DatagramSocket(BROADCAST_PORT);
            socketReceiver.setBroadcast(true);
            DatagramPacket packet = new DatagramPacket(buffRecv, buffRecv.length);
            while(Thread.currentThread() == cThreadReceiver){
                socketReceiver.receive(packet);
                //here you receive the packet and can check the sender IP address
            }
        } catch (Exception e) {
            e.printStackTrace();
            if(socketReceiver != null) try {socketReceiver.close();} catch (Exception e1) {}
        }

You will need to do some editing but should start you in the right track.