简体   繁体   中英

How does InetAddress class getLocalHost() return “Preferred” IP address?

I'm starting to dive into obtaining IP addresses through Java. I understand that a machine can have various IPs through different network interfaces, so I'm somewhat confused about some sample code I've found that appears to return the "Preferred" IP address (Preferred per Windows 7 command line ipconfig /all).

When I run the following code on my local computer, 26 NetworkInterface objects are returned, some with multiple InetAddress objects (including the "Preferred" one):

Enumeration<NetworkInterface> eNI = null;
    NetworkInterface ni = null;

    Enumeration<InetAddress> eIA = null;
    InetAddress ia = null;

    try {
        eNI = NetworkInterface.getNetworkInterfaces();
    } catch (Exception e) {
    }

    while (eNI.hasMoreElements()) {

        ni = eNI.nextElement();
        System.out.println("NtwkIntfc name: " + ni.getName());
        System.out.println("NtwkIntfc disp name: " + ni.getDisplayName());

        try {
            System.out.println("NtwkIntfc hardware addr: " + Hex.encodeHexString(ni.getHardwareAddress()));
        } catch (Exception e) {
        }

        eIA = ni.getInetAddresses();

        while (eIA.hasMoreElements()) {

            ia = eIA.nextElement();

            System.out.println("InetAddress host address: " + ia.getHostAddress());
            System.out.println("InetAddress host name: " + ia.getHostName());

        }
    }

However this much simpler code simply returns the "Preferred" IPv4 address:

try {
        InetAddress thisIp = InetAddress.getLocalHost();  
        System.out.println("IP:" + thisIp.getHostAddress());
    } catch (Exception e) {
        e.printStackTrace();
    }

I can't seem to find the NetworkInterface (and InetAddress from it) property/method that identifies it as "Preferred", so I'm wondering how the class method InetAddress.getLocalHost() does it? And furthermore, is this Preferred IP a standard networking concept or some type of Windows specific concept?

Thanks.

take a look at metric in network settings. also look at "route print" under windows 7 command line. i think the lower the metric the more "preferred" the adapter is.

Check out the source code for InetAddress.getLocalHost() .

Briefly, it gets the IP addresses bound to the host name, and returns the first entry from the returned array of IP addresses.

I don't see anything specific to this being preferred , other than it's an address mapped to the machine hostname (note however a machine can have multiple names too)

I think 'Preferred' may somehow refer to the most general entry in the routing table. Who knows what those Windows crazies were thinking.

However, this address may also correspond to the address that is most likely to be a public IP/assigned by DHCP. If you're looking for code that gets the most likely address to be public/used to open a port on, this is what I use to get an IPv4 address:

public static InetAddress getNetworkAddr() {
    InetAddress localAddr = null;

    // Find our public IP address
    Enumeration<NetworkInterface> netInterfaces;
    try {
        netInterfaces = NetworkInterface.getNetworkInterfaces();
        while (netInterfaces.hasMoreElements()) {               
            NetworkInterface ni = (NetworkInterface) netInterfaces.nextElement();               
            Enumeration<InetAddress> addresses = ni.getInetAddresses();             
            while( addresses.hasMoreElements() ) {
                InetAddress addr = addresses.nextElement();

                // System.out.println("Checking out " + ni.getName() + " with address " + addr.toString());

                if (!addr.isSiteLocalAddress() && 
                        !addr.isLoopbackAddress() && 
                        !addr.isLinkLocalAddress() &&
                        addr.getHostAddress().indexOf(":") == -1) { // MAC/IPv6 address detection
                    System.out.println("Interface " + ni.getName()
                            + " seems to be InternetInterface. I'll take address " + addr.toString());
                    System.out.println("Associated hostname: " + addr.getHostName());
                    localAddr = addr;
                    break;
                }
            }   
            if( localAddr != null ) break;
        }
    } catch( NoSuchElementException e) {
        System.out.println("Couldn't find a public address");
        localAddr = null;
    } catch (SocketException e) {
        e.printStackTrace();
        localAddr = null;
    }

    return localAddr;
}

An other solution seams to work with sockets (not the best one)

Socket socket = new Socket("www.somesite.com", 80); 
InetAddress localhost = socket.getLocalAddress(); 
System.out.println("Address of local host is " + localhost);
socket.close(); 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM