您的位置:首页 > 编程语言 > Java开发

java获取本机的所有ip地址 包括IPV6

2015-08-20 21:30 746 查看
最近在项目中遇到了一串比较诡异的问题,如下的同一串代码是演示了如何获取本地所有的ip地址:

/**
 * 
 * author:gaoxingliang@outlook.com
 * created:2015年8月20日 下午9:16:08  
 */
package blog;

import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Enumeration;

/**
 * @author gxl
 *
 */
public class GetLocalIps
{
	public static void main(String[] args) throws SocketException
    {
	    //get all local ips
		Enumeration<NetworkInterface> interfs = NetworkInterface.getNetworkInterfaces();
		while (interfs.hasMoreElements())
		{
			NetworkInterface interf = interfs.nextElement();
			Enumeration<InetAddress> addres = interf.getInetAddresses();
			while (addres.hasMoreElements())
			{
				InetAddress in = addres.nextElement();
				if (in instanceof Inet4Address)
				{
					System.out.println("v4:" + in.getHostAddress());
				}
				else if (in instanceof Inet6Address)
				{
					System.out.println("v6:" + in.getHostAddress());
				}
			}
		}
    }
}


上面的代码在本地环境返回了所有的ip 包括IPV6:

v4:127.0.0.1

v6:0:0:0:0:0:0:0:1

v4:169.254.177.100

v6:fe80:0:0:0:b0f5:493b:f105:b164%eth1

v4:192.168.0.100

v6:fe80:0:0:0:d48a:e3be:7d9d:899c%eth2

但是在运行环境上却只返回了如下的地址:

v4:127.0.0.1

v4:169.254.177.100

v4:192.168.0.100

发现少了IPV6,纳闷了好久,没办就看下java的实现,然后跟踪到如下代码:java.net.NetworkInterface.getNetworkInterfaces()

public static Enumeration<NetworkInterface> getNetworkInterfaces()
        throws SocketException {
        final NetworkInterface[] netifs = getAll();


java的实现:

private native static NetworkInterface[] getAll()
        throws SocketException;


是一个native的方法,于是参考了jdk源码,发现果然是java 运行参数导致的.

jdk源码:

openjdk\jdk\src\solaris\native\java\net\NetworkInterface.c

/*
 * Enumerates all interfaces
 */
static netif *enumInterfaces(JNIEnv *env) {
    netif *ifs;
    int sock;

    /*
     * Enumerate IPv4 addresses
     */

    sock = openSocket(env, AF_INET);
    if (sock < 0 && (*env)->ExceptionOccurred(env)) {
        return NULL;
    }

    ifs = enumIPv4Interfaces(env, sock, NULL);
    close(sock);

    if (ifs == NULL && (*env)->ExceptionOccurred(env)) {
        return NULL;
    }

    /* return partial list if exception occure in the middle of process ???*/

    /*
     * If IPv6 is available then enumerate IPv6 addresses.
     */
#ifdef AF_INET6

        /* User can disable ipv6 expicitly by -Djava.net.preferIPv4Stack=true,
         * so we have to call ipv6_available()
         */
        if (ipv6_available()) {

           sock =  openSocket(env, AF_INET6);
           if (sock < 0 && (*env)->ExceptionOccurred(env)) {
               freeif(ifs);
               return NULL;
           }

           ifs = enumIPv6Interfaces(env, sock, ifs);
           close(sock);

           if ((*env)->ExceptionOccurred(env)) {
              freeif(ifs);
              return NULL;
           }

       }
#endif

    return ifs;
}


有-Djava.net.preferIPv4Stack=true 参数后便不会有IPV6的地址.

jdk源码:
http://pan.baidu.com/s/1jGvmnrw
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: