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

17 篇文章 0 订阅

最近在项目中遇到了一串比较诡异的问题,如下的同一串代码是演示了如何获取本地所有的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





评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值