简体   繁体   English

在 Java 中获取“外部”IP 地址

[英]Getting the 'external' IP address in Java

I'm not too sure how to go about getting the external IP address of the machine as a computer outside of a network would see it.我不太确定如何获取机器的外部 IP 地址,因为网络外部的计算机会看到它。

My following IPAddress class only gets the local IP address of the machine.我下面的 IPAddress 类只获取机器的本地 IP 地址。

public class IPAddress {

    private InetAddress thisIp;

    private String thisIpAddress;

    private void setIpAdd() {
        try {
            InetAddress thisIp = InetAddress.getLocalHost();
            thisIpAddress = thisIp.getHostAddress().toString();
        } catch (Exception e) {
        }
    }

    protected String getIpAddress() {
        setIpAdd();
        return thisIpAddress;
    }
}

I am not sure if you can grab that IP from code that runs on the local machine.我不确定您是否可以从本地机器上运行的代码中获取该 IP。

You can however build code that runs on a website, say in JSP, and then use something that returns the IP of where the request came from:但是,您可以构建在网站上运行的代码,例如在 JSP 中,然后使用返回请求来源 IP 的内容:

request.getRemoteAddr()

Or simply use already-existing services that do this, then parse the answer from the service to find out the IP.或者简单地使用已经存在的服务来执行此操作,然后解析来自服务的答案以找出 IP。

Use a webservice like AWS and others使用 AWS 等网络服务

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

URL whatismyip = new URL("http://checkip.amazonaws.com");
BufferedReader in = new BufferedReader(new InputStreamReader(
                whatismyip.openStream()));

String ip = in.readLine(); //you get the IP as a String
System.out.println(ip);

One of the comments by @stivlo deserves to be an answer: @stivlo 的评论之一值得回答:

You can use the Amazon service http://checkip.amazonaws.com您可以使用亚马逊服务http://checkip.amazonaws.com

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;

public class IpChecker {

    public static String getIp() throws Exception {
        URL whatismyip = new URL("http://checkip.amazonaws.com");
        BufferedReader in = null;
        try {
            in = new BufferedReader(new InputStreamReader(
                    whatismyip.openStream()));
            String ip = in.readLine();
            return ip;
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

The truth is: 'you can't' in the sense that you posed the question.事实是:从你提出问题的意义上说,“你不能”。 NAT happens outside of the protocol. NAT 发生在协议之外。 There is no way for your machine's kernel to know how your NAT box is mapping from external to internal IP addresses.您机器的内核无法知道您的 NAT 盒如何从外部 IP 地址映射到内部 IP 地址。 Other answers here offer tricks involving methods of talking to outside web sites.这里的其他答案提供了涉及与外部网站交谈的方法的技巧。

All this are still up and working smoothly!所有这些都还在正常运行! (as of 23 Sep 2019) (截至 2019 年 9 月 23 日)

Piece of advice: Do not direcly depend only on one of them;忠告:不要直接依赖其中之一; try to use one but have a contigency plan considering others!尝试使用一个,但有一个考虑到其他人的应急计划! The more you use, the better!用得越多越好!

Good luck!祝你好运!

As @Donal Fellows wrote, you have to query the network interface instead of the machine.正如@Donal Fellows 所写,您必须查询网络接口而不是机器。 This code from the javadocs worked for me:来自 javadocs 的这段代码对我有用:

The following example program lists all the network interfaces and their addresses on a machine:以下示例程序列出了机器上的所有网络接口及其地址:

import java.io.*;
import java.net.*;
import java.util.*;
import static java.lang.System.out;

public class ListNets {

    public static void main(String args[]) throws SocketException {
        Enumeration<NetworkInterface> nets = NetworkInterface.getNetworkInterfaces();
        for (NetworkInterface netint : Collections.list(nets))
            displayInterfaceInformation(netint);
    }

    static void displayInterfaceInformation(NetworkInterface netint) throws SocketException {
        out.printf("Display name: %s\n", netint.getDisplayName());
        out.printf("Name: %s\n", netint.getName());
        Enumeration<InetAddress> inetAddresses = netint.getInetAddresses();
        for (InetAddress inetAddress : Collections.list(inetAddresses)) {
            out.printf("InetAddress: %s\n", inetAddress);
        }
        out.printf("\n");
     }
} 

The following is sample output from the example program:以下是示例程序的示例输出:

Display name: TCP Loopback interface
Name: lo
InetAddress: /127.0.0.1

Display name: Wireless Network Connection
Name: eth0
InetAddress: /192.0.2.0

From docs.oracle.com来自docs.oracle.com

与 www.whatismyip.com 等网站建立 HttpURLConnection 并解析它:-)

How about this?这个怎么样? It's simple and worked the best for me :)这很简单,对我来说效果最好:)

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;


public class IP {
    public static void main(String args[]) {
        new IP();
    }

    public IP() {
        URL ipAdress;

        try {
            ipAdress = new URL("http://myexternalip.com/raw");

            BufferedReader in = new BufferedReader(new InputStreamReader(ipAdress.openStream()));

            String ip = in.readLine();
            System.out.println(ip);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

http://jstun.javawi.de/会做 - 只要你的网关设备做 STUN )大多数做)

It's not that easy since a machine inside a LAN usually doesn't care about the external IP of its router to the internet.. it simply doesn't need it!这并不容易,因为局域网内的机器通常不关心其路由器到互联网的外部 IP。它根本不需要它!

I would suggest you to exploit this by opening a site like http://www.whatismyip.com/ and getting the IP number by parsing the html results.. it shouldn't be that hard!我建议你通过打开一个像http://www.whatismyip.com/这样的网站并通过解析 html 结果来获取 IP 号来利用它......它不应该那么难!

System.out.println(pageCrawling.getHtmlFromURL("http://ipecho.net/plain"));

如果您使用的是基于 JAVA 的 web 应用程序,并且您想获取客户端(通过浏览器发出请求的人)的外部 ip,请尝试在公共域中部署应用程序并使用 request.getRemoteAddr() 读取外部 IP 地址。

An alternative solution is to execute an external command, obviously, this solution limits the portability of the application.另一种解决方案是执行外部命令,显然,这种解决方案限制了应用程序的可移植性。

For example, for an application that runs on Windows, a PowerShell command can be executed through jPowershell, as shown in the following code:例如,对于运行在 Windows 上的应用程序,可以通过 jPowershell 执行 PowerShell 命令,如下代码所示:

public String getMyPublicIp() {
    // PowerShell command
    String command = "(Invoke-WebRequest ifconfig.me/ip).Content.Trim()";
    String powerShellOut = PowerShell.executeSingleCommand(command).getCommandOutput();

    // Connection failed
    if (powerShellOut.contains("InvalidOperation")) {
        powerShellOut = null;
    }
    return powerShellOut;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM