[java] Java를 사용하여 현재 머신의 IP 주소 얻기

다른 시스템 또는 동일한 시스템의 다른 포트에서 실행되는 다른 노드가있는 시스템을 개발하려고합니다.

이제 모든 노드는 부트 스트랩 노드라고하는 특수 노드의 IP로 대상 IP를 가진 소켓을 만듭니다. 그런 다음 노드는 자체적으로 작성하여 ServerSocket연결 청취를 시작합니다.

부트 스트랩 노드는 노드 목록을 유지 보수하고 조회시 리턴합니다.

이제 필요한 것은 노드가 부트 스트랩 노드에 IP를 등록해야한다는 것입니다. cli.getInetAddress()클라이언트 ServerSocket가 부트 스트랩 노드에 연결하면 사용 했지만 작동하지 않았습니다.

  1. 가능한 경우 클라이언트가 PPP IP를 등록해야합니다.
  2. 그렇지 않으면 LAN IP (사용 가능한 경우);
  3. 그렇지 않으면 동일한 컴퓨터를 가정하여 127.0.0.1을 등록해야합니다.

코드 사용하기 :

System.out.println(Inet4Address.getLocalHost().getHostAddress());

또는

System.out.println(InetAddress.getLocalHost().getHostAddress());

내 PPP 연결 IP 주소는 117.204.44.192이지만 위의 내용은 192.168.1.2입니다.

편집하다

다음 코드를 사용하고 있습니다.

Enumeration e = NetworkInterface.getNetworkInterfaces();
while(e.hasMoreElements())
{
    NetworkInterface n = (NetworkInterface) e.nextElement();
    Enumeration ee = n.getInetAddresses();
    while (ee.hasMoreElements())
    {
        InetAddress i = (InetAddress) ee.nextElement();
        System.out.println(i.getHostAddress());
    }
}

모든 IP 주소를 모두 가져올 수 NetworkInterface있지만 어떻게 구별합니까? 이것은 내가 얻는 결과입니다.

127.0.0.1
192.168.1.2
192.168.56.1
117.204.44.19



답변

import java.net.DatagramSocket;
import java.net.InetAddress;

try(final DatagramSocket socket = new DatagramSocket()){
  socket.connect(InetAddress.getByName("8.8.8.8"), 10002);
  ip = socket.getLocalAddress().getHostAddress();
}

이 방법은 여러 네트워크 인터페이스가있을 때 잘 작동합니다. 항상 선호하는 아웃 바운드 IP를 반환합니다. 목적지 8.8.8.8에 도달 할 필요는 없습니다.

ConnectUDP 소켓에서 다음과 같은 효과가 있습니다. Send / Recv의 대상을 설정하고 다른 주소에서 모든 패킷을 버리고 사용하는 소켓을 “연결된”상태로 전송하여 해당 필드를 설정합니다. 여기에는 시스템의 라우팅 테이블에 따라 대상에 대한 경로가 있는지 확인하고 이에 따라 로컬 엔드 포인트를 설정하는 것이 포함됩니다. 마지막 부분은 공식적으로 문서화되지 않은 것으로 보이지만 버전과 배포판에서 Windows와 Linux 모두에서 안정적으로 작동하는 Berkeley 소켓 API (UDP “연결된”상태의 부작용)의 핵심적인 특성처럼 보입니다.

따라서이 방법은 지정된 원격 호스트에 연결하는 데 사용되는 로컬 주소를 제공합니다. 실제 연결이 설정되지 않았으므로 지정된 원격 IP에 도달 할 수 없습니다.

편집하다:

으로 @macomgil는 말한다, 맥 OS 당신은이 작업을 수행 할 수 있습니다

Socket socket = new Socket();
socket.connect(new InetSocketAddress("google.com", 80));
System.out.println(socket.getLocalAddress());


답변

가장 일반적인 경우에는 약간 까다로울 수 있습니다.

그것의 얼굴에, InetAddress.getLocalHost()당신 에게이 호스트의 IP 주소를 제공해야합니다. 문제는 호스트에 많은 네트워크 인터페이스가있을 수 있고 인터페이스가 둘 이상의 IP 주소에 바인딩 될 수 있다는 것입니다. 또한 모든 IP 주소가 컴퓨터 나 LAN 외부에 도달 할 수있는 것은 아닙니다. 예를 들어 가상 네트워크 장치의 IP 주소, 개인 네트워크 IP 주소 등이 될 수 있습니다.

이것이 의미하는 것은 반환 된 IP 주소 InetAddress.getLocalHost()가 사용하기에 적합하지 않을 수 있다는 것입니다.

이것을 어떻게 다룰 수 있습니까?

  • 한 가지 방법은 NetworkInterface.getNetworkInterfaces()호스트에서 알려진 모든 네트워크 인터페이스를 얻은 다음 각 NI의 주소를 반복하는 것입니다.
  • 또 다른 방법은 호스트에 대해 외부 적으로 보급 된 FQDN을 가져 InetAddress.getByName()와서 기본 IP 주소를 찾는 데 사용 하는 것입니다. (그러나 어떻게 구할 수 있으며 DNS 기반로드 밸런서를 어떻게 처리합니까?)
  • 이전의 변형은 구성 파일 또는 명령 줄 매개 변수에서 기본 FQDN을 가져 오는 것입니다.
  • 또 다른 변형은 구성 파일 또는 명령 줄 매개 변수에서 기본 IP 주소를 얻는 것입니다.

요약 InetAddress.getLocalHost()하면 일반적으로 작동하지만 “복잡한”네트워킹 환경에서 코드가 실행되는 경우 대체 방법을 제공해야 할 수도 있습니다.


모든 네트워크 인터페이스와 관련된 모든 IP 주소를 얻을 수 있지만 어떻게 구별합니까?

  • 127.xxx.xxx.xxx 범위의 모든 주소는 “루프백”주소입니다. “이”호스트 만 볼 수 있습니다.
  • 192.168.xxx.xxx 범위의 모든 주소는 개인 (일명 사이트 로컬) IP 주소입니다. 이들은 조직 내에서 사용하도록 예약되어 있습니다. 10.xxx.xxx.xxx 주소와 172.16.xxx.xxx부터 172.31.xxx.xxx까지 동일하게 적용됩니다.
  • 169.254.xxx.xxx 범위의 주소는 링크 로컬 IP 주소입니다. 이들은 단일 네트워크 세그먼트에서 사용하도록 예약되어 있습니다.
  • 224.xxx.xxx.xxx ~ 239.xxx.xxx.xxx 범위의 주소는 멀티 캐스트 주소입니다.
  • 주소 255.255.255.255는 브로드 캐스트 주소입니다.
  • 다른 것은 유효한 공개 지점 간 IPv4 주소 여야 합니다.

실제로 InetAddress API는 루프백, 링크 로컬, 사이트 로컬, 멀티 캐스트 및 브로드 캐스트 주소 테스트를위한 메소드를 제공합니다. 이 정보를 사용하여 가장 적합한 IP 주소를 정렬 할 수 있습니다.


답변

여기에 https://issues.apache.org/jira/browse/JCS-40의 IP 모호한 해결 방법 코드를 게시하면 (Linux 시스템에서는 InetAddress.getLocalHost ()가 모호합니다) :

/**
 * Returns an <code>InetAddress</code> object encapsulating what is most likely the machine's LAN IP address.
 * <p/>
 * This method is intended for use as a replacement of JDK method <code>InetAddress.getLocalHost</code>, because
 * that method is ambiguous on Linux systems. Linux systems enumerate the loopback network interface the same
 * way as regular LAN network interfaces, but the JDK <code>InetAddress.getLocalHost</code> method does not
 * specify the algorithm used to select the address returned under such circumstances, and will often return the
 * loopback address, which is not valid for network communication. Details
 * <a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4665037">here</a>.
 * <p/>
 * This method will scan all IP addresses on all network interfaces on the host machine to determine the IP address
 * most likely to be the machine's LAN address. If the machine has multiple IP addresses, this method will prefer
 * a site-local IP address (e.g. 192.168.x.x or 10.10.x.x, usually IPv4) if the machine has one (and will return the
 * first site-local address if the machine has more than one), but if the machine does not hold a site-local
 * address, this method will return simply the first non-loopback address found (IPv4 or IPv6).
 * <p/>
 * If this method cannot find a non-loopback address using this selection algorithm, it will fall back to
 * calling and returning the result of JDK method <code>InetAddress.getLocalHost</code>.
 * <p/>
 *
 * @throws UnknownHostException If the LAN address of the machine cannot be found.
 */
private static InetAddress getLocalHostLANAddress() throws UnknownHostException {
    try {
        InetAddress candidateAddress = null;
        // Iterate all NICs (network interface cards)...
        for (Enumeration ifaces = NetworkInterface.getNetworkInterfaces(); ifaces.hasMoreElements();) {
            NetworkInterface iface = (NetworkInterface) ifaces.nextElement();
            // Iterate all IP addresses assigned to each card...
            for (Enumeration inetAddrs = iface.getInetAddresses(); inetAddrs.hasMoreElements();) {
                InetAddress inetAddr = (InetAddress) inetAddrs.nextElement();
                if (!inetAddr.isLoopbackAddress()) {

                    if (inetAddr.isSiteLocalAddress()) {
                        // Found non-loopback site-local address. Return it immediately...
                        return inetAddr;
                    }
                    else if (candidateAddress == null) {
                        // Found non-loopback address, but not necessarily site-local.
                        // Store it as a candidate to be returned if site-local address is not subsequently found...
                        candidateAddress = inetAddr;
                        // Note that we don't repeatedly assign non-loopback non-site-local addresses as candidates,
                        // only the first. For subsequent iterations, candidate will be non-null.
                    }
                }
            }
        }
        if (candidateAddress != null) {
            // We did not find a site-local address, but we found some other non-loopback address.
            // Server might have a non-site-local address assigned to its NIC (or it might be running
            // IPv6 which deprecates the "site-local" concept).
            // Return this non-loopback candidate address...
            return candidateAddress;
        }
        // At this point, we did not find a non-loopback address.
        // Fall back to returning whatever InetAddress.getLocalHost() returns...
        InetAddress jdkSuppliedAddress = InetAddress.getLocalHost();
        if (jdkSuppliedAddress == null) {
            throw new UnknownHostException("The JDK InetAddress.getLocalHost() method unexpectedly returned null.");
        }
        return jdkSuppliedAddress;
    }
    catch (Exception e) {
        UnknownHostException unknownHostException = new UnknownHostException("Failed to determine LAN address: " + e);
        unknownHostException.initCause(e);
        throw unknownHostException;
    }
}


답변

이 목적으로 java의 InetAddress 클래스를 사용할 수 있습니다 .

InetAddress IP=InetAddress.getLocalHost();
System.out.println("IP of my system is := "+IP.getHostAddress());

내 시스템의 출력 = IP of my system is := 10.100.98.228

getHostAddress () 는 다음을 리턴합니다.

텍스트 표현으로 IP 주소 문자열을 반환합니다.

또는 당신은 또한 할 수 있습니다

InetAddress IP=InetAddress.getLocalHost();
System.out.println(IP.toString());

출력 = IP of my system is := RanRag-PC/10.100.98.228


답변

“로컬”주소를 찾을 때 각 컴퓨터에는 단일 네트워크 인터페이스가있을뿐 아니라 각 인터페이스에는 고유 한 로컬 주소가있을 수 있습니다. 이것은 컴퓨터가 항상 여러 “로컬”주소를 소유하고 있음을 의미합니다.

다른 엔드 포인트에 연결할 때 사용할 다른 “로컬”주소가 자동으로 선택됩니다. 예를 들어에 연결할 때 google.com“외부”로컬 주소를 사용하고 있습니다. 그러나에 연결하면 localhost는 루프백이므로 localhost로컬 주소는 항상 localhost자체입니다.

아래는 통신 할 때 지역 주소를 찾는 방법을 보여줍니다 google.com.

Socket socket = new Socket();
socket.connect(new InetSocketAddress("google.com", 80));
System.out.println(socket.getLocalAddress());


답변

scala의 예 (sbt 파일에 유용) :

  import collection.JavaConverters._
  import java.net._

  def getIpAddress: String = {

    val enumeration = NetworkInterface.getNetworkInterfaces.asScala.toSeq

    val ipAddresses = enumeration.flatMap(p =>
      p.getInetAddresses.asScala.toSeq
    )

    val address = ipAddresses.find { address =>
      val host = address.getHostAddress
      host.contains(".") && !address.isLoopbackAddress
    }.getOrElse(InetAddress.getLocalHost)

    address.getHostAddress
  }


답변

편집 1 : 이전 링크 이후 업데이트 된 코드가 더 이상 존재하지 않습니다.

import java.io.*;
import java.net.*;

public class GetMyIP {
    public static void main(String[] args) {
        URL url = null;
        BufferedReader in = null;
        String ipAddress = "";
        try {
            url = new URL("http://bot.whatismyipaddress.com");
            in = new BufferedReader(new InputStreamReader(url.openStream()));
            ipAddress = in.readLine().trim();
            /* IF not connected to internet, then
             * the above code will return one empty
             * String, we can check it's length and
             * if length is not greater than zero,
             * then we can go for LAN IP or Local IP
             * or PRIVATE IP
             */
            if (!(ipAddress.length() > 0)) {
                try {
                    InetAddress ip = InetAddress.getLocalHost();
                    System.out.println((ip.getHostAddress()).trim());
                    ipAddress = (ip.getHostAddress()).trim();
                } catch(Exception exp) {
                    ipAddress = "ERROR";
                }
            }
        } catch (Exception ex) {
            // This try will give the Private IP of the Host.
            try {
                InetAddress ip = InetAddress.getLocalHost();
                System.out.println((ip.getHostAddress()).trim());
                ipAddress = (ip.getHostAddress()).trim();
            } catch(Exception exp) {
                ipAddress = "ERROR";
            }
            //ex.printStackTrace();
        }
        System.out.println("IP Address: " + ipAddress);
    }
}

실제 버전 : 작동이 중지되었습니다

이 스 니펫이이를 달성하는 데 도움이되기를 바랍니다.

// Method to get the IP Address of the Host.
private String getIP()
{
    // This try will give the Public IP Address of the Host.
    try
    {
        URL url = new URL("http://automation.whatismyip.com/n09230945.asp");
        BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
        String ipAddress = new String();
        ipAddress = (in.readLine()).trim();
        /* IF not connected to internet, then
         * the above code will return one empty
         * String, we can check it's length and
         * if length is not greater than zero,
         * then we can go for LAN IP or Local IP
         * or PRIVATE IP
         */
        if (!(ipAddress.length() > 0))
        {
            try
            {
                InetAddress ip = InetAddress.getLocalHost();
                System.out.println((ip.getHostAddress()).trim());
                return ((ip.getHostAddress()).trim());
            }
            catch(Exception ex)
            {
                return "ERROR";
            }
        }
        System.out.println("IP Address is : " + ipAddress);

        return (ipAddress);
    }
    catch(Exception e)
    {
        // This try will give the Private IP of the Host.
        try
        {
            InetAddress ip = InetAddress.getLocalHost();
            System.out.println((ip.getHostAddress()).trim());
            return ((ip.getHostAddress()).trim());
        }
        catch(Exception ex)
        {
            return "ERROR";
        }
    }
}