在项目开发过程中,需要获取linux服务器ip作为zookeeper节点名称,原先使用的是以下的方法:

public static String getIpAddress() {
		String hostAddress = "";
		try {
			InetAddress address = InetAddress.getLocalHost();
 
			hostAddress = address.getHostAddress();
 
 
 
		} catch (UnknownHostException e) {
			e.printStackTrace();
		}
		return hostAddress;
	}

但是该方法获取到的是127.0.0.1

查询服务器上面IP发现:

[mm_cbms1@localhost ~]$ ip address
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1000
    link/ether 00:50:56:a2:0d:1b brd ff:ff:ff:ff:ff:ff
    inet 10.12.8.243/24 brd 10.12.8.255 scope global eth0
    inet6 fe80::250:56ff:fea2:d1b/64 scope link 

       valid_lft forever preferred_lft forever

这里首先要了解上面列出的接口中的含义:

1、linux的网络接口之扫盲

  (1)网络接口的命名
  这里并不存在一定的命名规范,但网络接口名字的定义一般都是要有意义的。例如:
  eth0: ethernet的简写,一般用于以太网接口。
  wifi0:wifi是无线局域网,因此wifi0一般指无线网络接口。
  ath0: Atheros的简写,一般指Atheros芯片所包含的无线网络接口。
  lo: local的简写,一般指本地环回接口。
  (2)网络接口如何工作
  网络接口是用来发送和接受数据包的基本设备。
  系统中的所有网络接口组成一个链状结构,应用层程序使用时按名称调用。
  每个网络接口在linux系统中对应于一个struct net_device结构体,包含name,mac,mask,mtu…信息。
  每个硬件网卡(一个MAC)对应一个网络接口,其工作完全由相应的驱动程序控制。
  (3)虚拟网络接口
  虚拟网络接口的应用范围非常广泛。最着名的当属“lo”了,基本上每个linux系统都有这个接口。
  虚拟网络接口并不真实地从外界接收和发送数据包,而是在系统内部接收和发送数据包,因此虚拟网络接口不需要驱动程序。
  虚拟网络接口和真实存在的网络接口在使用上是一致的。
  (4)网络接口的创建
  硬件网卡的网络接口由驱动程序创建。而虚拟的网络接口由系统创建或通过应用层程序创建。
  驱动中创建网络接口的函数是:register_netdev(struct net_device *)或者register_netdevice(struct net_device *)。
  这两个函数的区别是:register_netdev(…)会自动生成以”eth”作为打头名称的接口,而register_netdevice(…)需要提前指定接口名称.事实上,register_netdev(…)也是通过调用register_netdevice(…)实现的。

  2、LINUX中的lo(回环接口)

  1) 什么是LO接口?
  在LINUX系统中,除了网络接口eth0,还可以有别的接口,比如lo(本地环路接口)。

  2) LO接口的作用是什么?

 假如包是由一个本地进程为另一个本地进程产生的, 它们将通过外出链的’lo’接口,然后返回进入链的’lo’接口。

其实getLocalHost方法获取的是lo接口对应的IP地址,了解了上述问题那java编码如何获取正确的地址呢?

java为了方便网络编程,提供了表示IP地址的类、表示网络接口(这个接口是指网卡)的类,表示网络连接接口的类,例如InetAddress,但是测试发现NetworkInterface类同样提供了获取本地计算机网络接口相关的信息的方法。尽管InetAddress类提供获取IP地址的方法,但是要想获取本机的网络接口的详细信息,还需要依赖NetworkInterface接口中的方法。测试发现下面方法可以获得服务器对应的IP地址,在linux服务器上和本地测试通过


public static String getInet4Address() {
		Enumeration<NetworkInterface> nis;
		String ip = null;
		try {
			nis = NetworkInterface.getNetworkInterfaces();
			for (; nis.hasMoreElements();) {
				NetworkInterface ni = nis.nextElement();
				Enumeration<InetAddress> ias = ni.getInetAddresses();
				for (; ias.hasMoreElements();) {
					InetAddress ia = ias.nextElement();
					//ia instanceof Inet6Address && !ia.equals("")
					if (ia instanceof Inet4Address && !ia.getHostAddress().equals("127.0.0.1")) {
						ip = ia.getHostAddress();
					}
				}
			}
		} catch (SocketException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return ip;
	}
public static InetAddress getCurrentIp() {
        try {
            Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
            while (networkInterfaces.hasMoreElements()) {
                NetworkInterface ni = (NetworkInterface) networkInterfaces.nextElement();
                Enumeration<InetAddress> nias = ni.getInetAddresses();
                while (nias.hasMoreElements()) {
                    InetAddress ia = (InetAddress) nias.nextElement();
                    if (!ia.isLinkLocalAddress() && !ia.isLoopbackAddress() && ia instanceof Inet4Address) {
                        return ia;
                    }
                }
            }
        } catch (SocketException e) {
        	logger.error(e.getStackTrace());
        }
        return null;
    }

上述两个方法都可以获取正确的IP地址

GitHub 加速计划 / li / linux-dash
6
1
下载
A beautiful web dashboard for Linux
最近提交(Master分支:3 个月前 )
186a802e added ecosystem file for PM2 4 年前
5def40a3 Add host customization support for the NodeJS version 4 年前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐