解決linux下java程式碼獲取不到本機ip地址
阿新 • • 發佈:2018-12-07
今天在部署完預生產環境的時候發現一個問題,在linux下面java程式碼獲取本機ip地址獲取不到。但是我在測試環境上面是能夠獲取到的。先粘下獲取本機ip的程式碼:
try{ Enumeration<NetworkInterface> allNetInterfaces = NetworkInterface.getNetworkInterfaces(); InetAddress addr = null; while (allNetInterfaces.hasMoreElements()) { NetworkInterface netInterface = (NetworkInterface) allNetInterfaces.nextElement(); //System.out.println(netInterface.getName()); Enumeration<InetAddress> addresses = netInterface.getInetAddresses(); while (addresses.hasMoreElements()) { InetAddress ipTmp = (InetAddress) addresses.nextElement(); if(ipTmp != null && ipTmp instanceof Inet4Address && ipTmp.isSiteLocalAddress() && !ipTmp.isLoopbackAddress() && ipTmp.getHostAddress().indexOf(":")==-1){ addr = ipTmp; } } } if(addr == null) throw new SystemException("獲取本機ip異常"); return addr; }catch(SocketException e){ e.printStackTrace(); throw new SystemException("獲取本機ip異常"); }
這樣的程式碼就不多解釋了,網上一找一大把。 於是又把伺服器的ip配置拿出來
似乎ip看起來也沒有什麼問題,沒辦法了只能一步步除錯程式碼了,於是打上日誌看看。
看到的日誌伺服器ip地址也能獲取出來,但是結合上面的程式碼看有個條件是不滿足的,isSiteLocalAddress()這個方法返回是false,按理說應該是true才對,這方法是javaAPI提供的,然後看下這個方法的原始碼:
/** * Utility routine to check if the InetAddress is a site local address. * * @return a <code>boolean</code> indicating if the InetAddress is * a site local address; or false if address is not a site local unicast address. * @since 1.4 */ public boolean isSiteLocalAddress() { // refer to RFC 1918 // 10/8 prefix // 172.16/12 prefix // 192.168/16 prefix int address = holder().getAddress(); return (((address >>> 24) & 0xFF) == 10) || ((((address >>> 24) & 0xFF) == 172) && (((address >>> 16) & 0xF0) == 16)) || ((((address >>> 24) & 0xFF) == 192) && (((address >>> 16) & 0xFF) == 168)); }
恍然大悟原來私有ip地址是有範圍限制的,
對著伺服器上面的ip一看,果然是不在這個範圍內。這實施小哥把公有的ip拿來配成私有的,導致獲取不到ip。把ip配置成私有ip的範圍問題也就解決了。