`
san_yun
  • 浏览: 2595895 次
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

关于JAVA取本机ip的一些总结

 
阅读更多

通常绑定本机ip地址 一般如下

 

        InetSocketAddress address = new InetSocketAddress(port);
        Channel serverChannel = bootstrap.bind(address);

 

 

InetSocketAddress默认使用的是什么ip呢?看看内部代码就明白了:

public InetSocketAddress(int port) {
   this(InetAddress.anyLocalAddress(), port);
}

 

InetAddress.anyLocalAddress()一般就是0.0.0.0/0.0.0.0,如果我们有两块网卡,一块内网,一块外网,那么都能访问这个socket,这通常是不安全的。那么通过InetAddress.getLocalHost().getHostAddress()呢?

结果悲剧了,使用上面的代码取回的是127.0.0.1。

 

好了,看看dubbo是怎么解决,dubbo获取本机ip地址的方法封装在com.alibaba.dubbo.common.utils.NetUtils类里面。

import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.Enumeration;
import java.util.regex.Pattern;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class NetUtils {

    private static final Logger  logger           = LoggerFactory.getLogger(NetUtils.class);

    private static final Pattern IP_PATTERN       = Pattern.compile("\\d{1,3}(\\.\\d{1,3}){3,5}$");

    private static final Pattern LOCAL_IP_PATTERN = Pattern.compile("127(\\.\\d{1,3}){3}$");

    public static final String   ANYHOST          = "0.0.0.0";

    public static final String   LOCALHOST        = "127.0.0.1";

    private static boolean isValidAddress(InetAddress address) {
        if (address == null || address.isLoopbackAddress()) return false;
        String name = address.getHostAddress();
        return (name != null && !ANYHOST.equals(name) && !LOCALHOST.equals(name) && IP_PATTERN.matcher(name).matches());
    }

    public static boolean isLocalHost(String host) {
        return host != null && (LOCAL_IP_PATTERN.matcher(host).matches() || host.equalsIgnoreCase("localhost"));
    }

    public static boolean isAnyHost(String host) {
        return "0.0.0.0".equals(host);
    }

    private static volatile InetAddress LOCAL_ADDRESS = null;

    /**
     * 遍历本地网卡,返回第一个合理的IP。
     * 
     * @return 本地网卡IP
     */
    public static InetAddress getLocalAddress() {
        if (LOCAL_ADDRESS != null) {
            return LOCAL_ADDRESS;
        }
        InetAddress localAddress = getLocalAddress0();
        LOCAL_ADDRESS = localAddress;
        return localAddress;
    }

    private static InetAddress getLocalAddress0() {
        InetAddress localAddress = null;
        try {
            localAddress = InetAddress.getLocalHost();
            if (isValidAddress(localAddress)) {
                return localAddress;
            }
        } catch (Throwable e) {
            logger.warn("Failed to retriving ip address, " + e.getMessage(), e);
        }
        try {
            Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
            if (interfaces != null) {
                while (interfaces.hasMoreElements()) {
                    try {
                        NetworkInterface network = interfaces.nextElement();
                        Enumeration<InetAddress> addresses = network.getInetAddresses();
                        if (addresses != null) {
                            while (addresses.hasMoreElements()) {
                                try {
                                    InetAddress address = addresses.nextElement();
                                    if (isValidAddress(address)) {
                                        return address;
                                    }
                                } catch (Throwable e) {
                                    logger.warn("Failed to retriving ip address, " + e.getMessage(), e);
                                }
                            }
                        }
                    } catch (Throwable e) {
                        logger.warn("Failed to retriving ip address, " + e.getMessage(), e);
                    }
                }
            }
        } catch (Throwable e) {
            logger.warn("Failed to retriving ip address, " + e.getMessage(), e);
        }
        logger.error("Could not get local host ip address, will use 127.0.0.1 instead.");
        return localAddress;
    }

}

 简单的说就是通过NetworkInterface遍历网卡address,然后通过isValidAddress校验ip是否正常即可。需要注意的一点是,dubbo通过Pattern.compile("\\d{1,3}(\\.\\d{1,3}){3,5}$")判断ip是否合法,也就是说不能保证只返回内网ip!


我把代码改了一下,保证只返回内网ip:

package com.duitang.dboss.util;

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

/**
 * 
 * @author yunpeng
 *
 */
public class NetUtil {

    private static volatile InetAddress LOCAL_ADDRESS = null;

    /**
     * 遍历本地网卡,返回内网IP。
     * 
     * @return 本地网卡IP
     */
    public static InetAddress getLocalAddress() {
        if (LOCAL_ADDRESS != null) {
            return LOCAL_ADDRESS;
        }
        InetAddress localAddress = getLocalAddress0();
        LOCAL_ADDRESS = localAddress;
        return localAddress;
    }
    
    private static InetAddress getLocalAddress0() {
      
        try {
            Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
            while (interfaces.hasMoreElements()) {
                NetworkInterface network = interfaces.nextElement();
                Enumeration<InetAddress> addresses = network.getInetAddresses();
                while (addresses != null && addresses.hasMoreElements()) {
                    InetAddress address = addresses.nextElement();
                    if (address != null && !address.isLoopbackAddress()) {

                        String name = address.getHostAddress();
                        if (name != null && name.startsWith("192.168")) {
                            return address;
                        }
                    }
                }
            }
        } catch (SocketException e) {
            throw new RuntimeException(e);
        }
        throw new RuntimeException("Could not get local host ip address!");
    }
    
    public static void main(String[] args) {
        System.out.println(NetUtil.getLocalAddress().getHostAddress());
    }
}

 

 

 

分享到:
评论

相关推荐

    java 面试题 总结

    JAVA相关基础知识 1、面向对象的特征有哪些方面 1.抽象: 抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面。抽象并不打算了解全部问题,而只是选择其中的一部分,暂时不用...

    正则表达式语法总结

    这是一篇关于java的正则表达式的语法总结,里面详细介绍了关于如何使用正则表达式,进而仔细看完之后就可以自己设置邮箱、电话号码、电子邮箱、iP地址等等

    java获取地磅称重数据源码-uip:用户界面

    根据之前的实践,可以总结一些结论:DCS、ECS、水处理这三个控制系统的对接一般采取OPC的通信方式,地磅一般采取JDBC的方式读取源数据库,垃圾吊可以采取JDBC或者modbus的方式。 ##通信协议 主要的通信协议是三种,...

    IIS6.0 IIS,互联网信息服务

    多个IP对应多个Web站点 如果本机已绑定了多个IP地址,想利用不同的IP地址得出不同的Web页面,则只需在“默认Web站点”处单击右键,选“新建→站点”,然后根据提示在“说明”处输入任意用于说明它的内容(比如为“我...

    java面试题,180多页,绝对良心制作,欢迎点评,涵盖各种知识点,排版优美,阅读舒心

    get()方法-根据Key从HashMap中取Value 66 HashMap的特点总结: 66 【集合】HashMap在并发场景下的问题和解决方案 67 多线程put后可能导致get死循环 67 多线程put的时候可能导致元素丢失 68 解决方案 68 【集合】...

    基于Java实现银行排号系统【源码+LW文档+PPT+数据库+讲解视频】

    银行排号系统是为解决一些服务业营业大厅排队问题而设计的,它能够有效地提高工作人员的工作效率,也能够使顾客合理的安排等待时间,让顾客感到服务的公平公正。论文首先讨论了排号系统的背景、意义、应用现状以及...

    基于java的局域网聊天系统-毕业设计.doc

    若取 SOCK_STREAM表示要创建的套接字是流套接字,取SOCK_DGRAM创建的是数据报套接字,取 SOCK_RAW表示创建原始套接字。 参数protocol说明该套接字使用的特定协议,如果调用者不希望特别指定使用的协议 ,则置为0,...

    JSP实用技巧集合,jsp编程的一些小技巧总结

    jsp编程的一些小技巧总结,绝对实用。包括JSP编程中常用的js技术。 1.JSP编程中常用的js技术 2. 在下拉列表框里选择一个值后跳出新窗口? 3. 在JSP中启动execl? 4. 两级下拉列表框联动菜单? 5. java中如何把一个目录...

    javascript 取小数点后几位几种方法总结

    javascript 取小数点后几位方法总结 Javascript取float型小数点后两位,例22.123456取成22.12,如何做? 1.通过substring截取。 function getnum() { var num = 22.123456; var result = num.substring(0,s.indexOf...

    优化javascript的执行效率一些方法总结

    1、在低版本浏览器中(如IE6,IE7等)串联字符串时使用数组的join方法就比使用+号来连接高效很多(如[‘aaa’,’bbb’,’ccc’].join()比’aaa’+’bbb’+’ccc’高效); 2、Array: pop比shift高效,... 6、键值对应取

    RED HAT LINUX 6大全

    11.5.3 DNS将名字映射到IP地址及反 序操作 207 11.5.4 前区和反区必须保持同步 207 11.5.5 HUP信号和重启 207 11.5.6 IN-ADDR.ARPA域 207 11.5.7 主机命名方案 208 11.5.8 配置DNS客户:/etc/resolv.conf 208 ...

    javascript 产生随机数的几种方法总结

    javascript 产生随机数的几种方法总结 1、取两个数之间的随机数 function GetRandomNum(Min,Max){ var Range = Max - Min; var Rand = Math.random(); return(Min + Math.round(Rand * Range)); } 2、混合法 ...

    MySQL命令大全

     、例:连接到本机上的MYSQL  首先在打开DOS窗口,然后进入目录mysqlbin,再键入命令mysql -uroot -p,回车后提示你输密码,如果刚安装好MYSQL,超级用户root是没有密码的,故直接回车即可进入到MYSQL中了,MYSQL...

    测试培训教材

    进入10sabin.war\WEB-INF,修改siteadmin.xml中的IP地址: 修改数据库中的数据: 修改后可以登陆 但是还需要修改以前Project的数据库连接属性 否则会提示错误 然后还要修改 C:\Program Files\...

    MYSQL常用命令大全

     1、例1:连接到本机上的MYSQL  首先在打开DOS窗口,然后进入目录 mysqlbin,再键入命令mysql -uroot -p,回车后提示你输密码,如果刚安装好MYSQL,超级用户root是没有密码的,故直接回车即可进入到MYSQL中了,...

    javascript 获取HTML DOM父、子、临近节点

    令人欣慰的是,使用JavaScript获取节点的方法有很多种,这里简单做一下总结(以下方法在IE7和Firefox2.0.0.11测试通过): 1. 通过顶层document节点获取: (1) document.getElementById(elementId):该方法通过...

    网管教程 从入门到精通软件篇.txt

    Windows XP(包括 Windows 2000)的控制台命令是在系统出现一些意外情况下的一种非常有效的诊断和测试以及恢复系统功能的工具。小编的确一直都想把这方面的命令做个总结,这次辛苦老范给我们整理了这份实用的秘笈。 ...

    javascript 短路法代码精简

    碰到一段代码如下 if(n&gt;win) { p=dArry.length-win; } else if(n; p=n; p=((n&gt;win)&&(dArry.length-win))||((n&lt;0)&&0)||n 总结一句话:&&取最后值,||取第一满足的值,高效,但请灵活使用

Global site tag (gtag.js) - Google Analytics