简体   繁体   English

如何使用Java获取客户端的LAN IP?

[英]How to get the LAN IP of a client using Java?

How can i get the LAN IP-address of a computer using Java? 如何使用Java获取计算机的LAN IP地址? I want the IP-address which is connected to the router and the rest of the network. 我想要连接到路由器和网络其余部分的IP地址。

I've tried something like this: 我尝试过这样的事情:

Socket s = new Socket("www.google.com", 80);
String ip = s.getLocalAddress().getHostAddress();
s.close();

This seem to work on some cases, but sometimes it returns the loopback-address or something completely different. 这似乎适用于某些情况,但有时它会返回loopback-address或完全不同的东西。 Also, it requires internet connection. 此外,它需要互联网连接。

Does anyone got a more accurate method of doing this? 有没有人有更准确的方法这样做?

EDIT: Thought it would be better to ask here than in a comment.. 编辑:认为这里问题比评论更好..

What if you got many interfaces? 如果你有很多接口怎么办? For example, one for cable, one for wifi and one for virtual box or so. 例如,一个用于电缆,一个用于wifi,一个用于虚拟盒子等。 Is it impossible to actually see which one is connected to the network? 是否无法真正看到哪一个连接到网络?

Try java.net.NetworkInterface 试试java.net.NetworkInterface

import java.net.NetworkInterface;

...

for (
    final Enumeration< NetworkInterface > interfaces =
        NetworkInterface.getNetworkInterfaces( );
    interfaces.hasMoreElements( );
)
{
    final NetworkInterface cur = interfaces.nextElement( );

    if ( cur.isLoopback( ) )
    {
        continue;
    }

    System.out.println( "interface " + cur.getName( ) );

    for ( final InterfaceAddress addr : cur.getInterfaceAddresses( ) )
    {
        final InetAddress inet_addr = addr.getAddress( );

        if ( !( inet_addr instanceof Inet4Address ) )
        {
            continue;
        }

        System.out.println(
            "  address: " + inet_addr.getHostAddress( ) +
            "/" + addr.getNetworkPrefixLength( )
        );

        System.out.println(
            "  broadcast address: " +
                addr.getBroadcast( ).getHostAddress( )
        );
    }
}

At first: There is no single address. 起初:没有单一地址。 Your machine has at least two adresses (127.0.0.1 on "lo" and maybe 192.168.1.1 on "eth1"). 您的机器至少有两个地址(“lo”为127.0.0.1,“eth1”为192.168.1.1)。

You want this: Listing network interfaces 你想要这个: 列出网络接口

As you may expect, you cannot automatically detect which one is connected to any of your routers, since this needs potentially complex parsing of your routing tables. 正如您所料,您无法自动检测哪个路由器连接到哪个路由器,因为这需要对路由表进行复杂的解析。 But if you just want any non-local address this should be enought. 但是,如果您只是想要任何非本地地址,那么应该这样做。 To be sure, try to use this at least one time on vista or Windows 7, since they add IPv6 addresses. 可以肯定的是,尝试在vista或Windows 7上至少使用一次,因为它们会添加IPv6地址。

import java.io.*;
import java.net.*;
import java.util.*;
import static java.lang.System.out;

public class ListNets 
{
    public static void main(String args[]) throws SocketException {
        Enumeration<NetworkInterface> nets = NetworkInterface.getNetworkInterfaces();
        for (NetworkInterface netint : Collections.list(nets))
            displayInterfaceInformation(netint);
    }

    static void displayInterfaceInformation(NetworkInterface netint) throws SocketException {
        out.printf("Display name: %s\n", netint.getDisplayName());
        out.printf("Name: %s\n", netint.getName());
        Enumeration<InetAddress> inetAddresses = netint.getInetAddresses();
        for (InetAddress inetAddress : Collections.list(inetAddresses)) {
            out.printf("InetAddress: %s\n", inetAddress);
        }
        out.printf("\n");
     }
}  

The following is sample output from the example program: 以下是示例程序的示例输出:

Display name: bge0
Name: bge0
InetAddress: /fe80:0:0:0:203:baff:fef2:e99d%2
InetAddress: /121.153.225.59

Display name: lo0
Name: lo0
InetAddress: /0:0:0:0:0:0:0:1%1
InetAddress: /127.0.0.1

This is a method I've used for a while. 这是我用了一段时间的方法。 It includes a little hack to figure out the externally visible ip-address as well. 它包括一个小的黑客,以找出外部可见的IP地址。

private List<String> getLocalHostAddresses() {

    List<String> addresses = new ArrayList<String>();

    try {
        Enumeration<NetworkInterface> e = NetworkInterface.getNetworkInterfaces();

        while (e.hasMoreElements()) {
            NetworkInterface ni = e.nextElement();
            Enumeration<InetAddress> e2 = ni.getInetAddresses();
            while (e2.hasMoreElements())
                addresses.add(e2.nextElement().getHostAddress());
        }
        URL u = new URL("http://whatismyip.org");
        BufferedReader in = new BufferedReader(new InputStreamReader(
                u.openStream()));
        addresses.add(in.readLine());
        in.close();
    } catch (Exception ignore) {
    }

    return addresses;
}

As Daniel already pointed out, you cannot know which interface is the one "connected". 正如Daniel已经指出的那样,你无法知道哪个界面是“连接”的。 What if, for example, the computer has multiple network interface cards which are both connected to separate physical LANs? 例如,如果计算机有多个网络接口卡都连接到不同的物理LAN,该怎么办?

Let the user decide which interface to use or try them all, depending on what your use case is. 让用户决定使用哪个界面或全部尝试,具体取决于您的用例。

try {
    InetAddress addr = InetAddress.getLocalHost();

    // Get IP Address
    byte[] ipAddr = addr.getAddress();

    // Get hostname
    String hostname = addr.getHostName();
} catch (UnknownHostException e) {
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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