2012-01-06 9 views
34

Vì vậy, tôi đang cố gắng lấy địa chỉ IP của máy của tôi trong mạng cục bộ của tôi (cần là 192.168.178.41).Nhận địa chỉ IP cục bộ mà không cần kết nối Internet

ý định đầu tiên của tôi là sử dụng một cái gì đó như thế này:

InetAddress.getLocalHost().getHostAddress(); 

nhưng nó chỉ trả về 127.0.0.1, đó là chính xác nhưng không phải là rất hữu ích cho tôi.

Tôi đã tìm kiếm xung quanh và tìm thấy câu trả lời này https://stackoverflow.com/a/2381398/717341, mà chỉ đơn giản tạo ra một Socket -Connection một số web-page (ví dụ như "google.com") và nhận được địa chỉ host nội bộ từ các ổ cắm:

Socket s = new Socket("google.com", 80); 
System.out.println(s.getLocalAddress().getHostAddress()); 
s.close(); 

Điều này làm việc cho máy của tôi (nó trả về 192.168.178.41), nhưng nó cần phải kết nối với internet để làm việc. Vì ứng dụng của tôi không yêu cầu kết nối internet và có thể có vẻ "đáng ngờ" khi ứng dụng tìm cách kết nối với google mỗi khi nó được khởi chạy, tôi không thích ý tưởng sử dụng nó.

Vì vậy, sau khi một số nghiên cứu tôi càng loạng choạng trên NetworkInterface đẳng cấp, trong đó (với một số công việc) cũng không trả lại mong muốn IP-Địa chỉ:

Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces(); 
while (interfaces.hasMoreElements()){ 
    NetworkInterface current = interfaces.nextElement(); 
    System.out.println(current); 
    if (!current.isUp() || current.isLoopback() || current.isVirtual()) continue; 
    Enumeration<InetAddress> addresses = current.getInetAddresses(); 
    while (addresses.hasMoreElements()){ 
     InetAddress current_addr = addresses.nextElement(); 
     if (current_addr.isLoopbackAddress()) continue; 
     System.out.println(current_addr.getHostAddress()); 
    } 
} 

Trên máy tính của tôi, điều này sẽ trả về như sau:

name:eth1 (eth1) 
fe80:0:0:0:226:4aff:fe0d:592e%3 
192.168.178.41 
name:lo (lo) 

Nó tìm thấy cả hai giao diện mạng của tôi và trả về IP mong muốn nhưng tôi không chắc địa chỉ khác (fe80:0:0:0:226:4aff:fe0d:592e%3) có nghĩa là gì.

Ngoài ra, tôi chưa tìm cách lọc nó từ địa chỉ trả về (bằng cách sử dụng isXX() -methods của InetAddress -object), sau đó sử dụng RegEx, mà tôi thấy rất "bẩn".

Bất kỳ suy nghĩ nào khác ngoài sử dụng RegEx hoặc internet?

+2

fe80: 0: 0: 0: 226: 4aff: fe0d: 592e trông giống như một địa chỉ IPv6 –

+0

'fe80 :: ... 'là một IPv6 địa chỉ link-local s – fge

+0

Và nhân tiện, bạn muốn "lọc" cái gì? Và tất nhiên, bạn có biết rằng một chiếc máy có thể được multihomed? – fge

Trả lời

24

fe80: 0: 0: 0: 226: 4aff: fe0d: 592e là địa chỉ ipv6 ;-) của bạn.

Kiểm tra này sử dụng

if (current_addr instanceof Inet4Address) 
    System.out.println(current_addr.getHostAddress()); 
else if (current_addr instanceof Inet6Address) 
    System.out.println(current_addr.getHostAddress()); 

Nếu bạn chỉ chăm sóc cho IPv4, sau đó chỉ cần loại bỏ các trường hợp IPv6. Nhưng hãy cẩn thận, IPv6 là tương lai ^^.

P.S .: Kiểm tra xem một số break s của bạn có phải là continue s.

+1

'getHostAddress()' hiện diện trong lớp cơ sở 'InetAddress', không cần phải đúc ở đây (http://docs.oracle.com/javase/6/docs/api/java/net/InetAddress.html#getHostAddress()) – skaffman

+0

Trông khá đẹp và nó hoạt động. Mặc dù chỉ để lọc chúng, bạn không cần phôi. Tôi nhận thức được IPv6 là tương lai, nhưng đối với nhu cầu hiện tại của tôi, một IPv4 sẽ làm tốt ;-) Và tất nhiên bạn đang đúng về 'break'. Tôi đã sửa lại điều đó. Cảm ơn đến đây! –

+0

@skaffman: Điểm lấy - bỏ đi – yankee

2

Câu trả lời của Yankee là chính xác cho phần đầu tiên.Để in ra địa chỉ IP, bạn có thể lấy nó như một mảng byte và chuyển đổi đó để đại diện bình thường chuỗi như thế này:

StringBuilder ip = new StringBuilder(); 
for(byte b : current_addr.getAddress()) { 
    // The & here makes b convert like an unsigned byte - so, 255 instead of -1. 
    ip.append(b & 0xFF).append('.'); 
} 
ip.setLength(ip.length() - 1); // To remove the last '.' 
System.out.println(ip.toString()); 
+0

Điều gì sẽ là lợi thế so với việc sử dụng 'current_addr.getHostAddress()'? –

+0

@Lukas Knuth: Lúc đầu, tôi không có các bản in trong câu trả lời của tôi. Tôi chỉnh sửa chúng vào bài viết một phút sau đó vì tôi nghĩ rằng có thể khá hữu ích ;-). Russell có lẽ không thấy phiên bản đó. – yankee

+0

Rất tiếc, lỗi của tôi - tôi cho rằng getHostAddress đang in toàn bộ văn bản mà yankee phải hối hận. Tôi không nhận thấy bản in hiện tại. –

5
import java.net.*; 

public class Get_IP 
{ 
    public static void main(String args[]) 
    { 
     try 
     { 
      InetAddress addr = InetAddress.getLocalHost(); 
      String hostname = addr.getHostName(); 
      System.out.println(addr.getHostAddress()); 
      System.out.println(hostname); 
     }catch(UnknownHostException e) 
     { 
      //throw Exception 
     } 


    } 

}

+3

Như tôi đã đề cập ở trên, điều này cung cấp cho bạn '127.0.0.1' trên Linux. Tuy nhiên, điều này có thể làm việc với các hệ thống Windows ... –

+0

nó được đề cập lúc đầu. – Mavlarn

8
public static String getIp(){ 
    String ipAddress = null; 
    Enumeration<NetworkInterface> net = null; 
    try { 
     net = NetworkInterface.getNetworkInterfaces(); 
    } catch (SocketException e) { 
     throw new RuntimeException(e); 
    } 

    while(net.hasMoreElements()){ 
     NetworkInterface element = net.nextElement(); 
     Enumeration<InetAddress> addresses = element.getInetAddresses(); 
     while (addresses.hasMoreElements()){ 
      InetAddress ip = addresses.nextElement(); 
      if (ip instanceof Inet4Address){ 

       if (ip.isSiteLocalAddress()){ 

        ipAddress = ip.getHostAddress(); 
       } 

      } 

     } 
    } 
    return ipAddress; 
} 
+0

mã này sẽ bỏ qua ip 127.0.0.1 trong linux –

+0

Điều này khác với câu trả lời và những gì tôi đã cung cấp? –

+0

trong linux mã của bạn sẽ trả về 127.0.0.1 –

13

Đây cũng là một java 8 cách để làm việc đó:

public static String getIp() throws SocketException { 

    return Collections.list(NetworkInterface.getNetworkInterfaces()).stream() 
      .flatMap(i -> Collections.list(i.getInetAddresses()).stream()) 
      .filter(ip -> ip instanceof Inet4Address && ip.isSiteLocalAddress()) 
      .findFirst().orElseThrow(RuntimeException::new) 
      .getHostAddress(); 
} 
+1

Đây là giải pháp duy nhất trả về địa chỉ IP LAN thực của tôi. Cảm ơn bạn! – Pali