1. 程式人生 > 程式設計 >java獲取linux伺服器上的IP操作

java獲取linux伺服器上的IP操作

在編碼過程中需要獲取本地IP地址,首先使用的是下面的方法,在Windows環境正常,但是linux伺服器上就獲取不到,

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

這樣在linux上依然獲取到的是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,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伺服器上和本地測試通過

(1)

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;
 }

(2)

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地址,具體NetworkInterface的使用還需要以後應用到了進行深入研究一下

補充知識:Java獲取所有網絡卡IP地址

Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
    while (networkInterfaces.hasMoreElements()) {
      NetworkInterface networkInterface = networkInterfaces.nextElement();
      Enumeration<InetAddress> inetAddresses = networkInterface.getInetAddresses();
      while (inetAddresses.hasMoreElements()) {
        InetAddress inetAddress = inetAddresses.nextElement();
        if (inetAddress.isLoopbackAddress()) {//迴路地址,如127.0.0.1
        	System.out.println("loop addr:" + inetAddress);
        } else if (inetAddress.isLinkLocalAddress()) {//169.254.x.x
        	System.out.println("link addr:" + inetAddress);
        } else {
          //非連結和迴路真實ip
        	System.out.println("ip:" + inetAddress);
        }
      }
    }

結果:

loop addr:/127.0.0.1
loop addr:/0:0:0:0:0:0:0:1
ip:/192.168.10.89

以上這篇java獲取linux伺服器上的IP操作就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支援我們。