Getting the 'external' IP address in Java

JavaNetworkingNetwork ProgrammingIp AddressExternal

Java Problem Overview


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.

My following IPAddress class only gets the local IP address of the machine.

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

Java Solutions


Solution 1 - Java

I am not sure if you can grab that IP from code that runs on the local machine.

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:

request.getRemoteAddr()

Or simply use already-existing services that do this, then parse the answer from the service to find out the IP.

Use a webservice like AWS and others

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

Solution 2 - Java

One of the comments by @stivlo deserves to be an answer:

You can use the Amazon service 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();
				}
			}
		}
	}
}

Solution 3 - Java

The truth is: 'you can't' in the sense that you posed the question. NAT happens outside of the protocol. There is no way for your machine's kernel to know how your NAT box is mapping from external to internal IP addresses. Other answers here offer tricks involving methods of talking to outside web sites.

Solution 4 - Java

All this are still up and working smoothly! (as of 10 Feb 2022)

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!

Solution 5 - Java

As @Donal Fellows wrote, you have to query the network interface instead of the machine. This code from the javadocs worked for me:

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

Solution 6 - Java

Make a HttpURLConnection to some site like www.whatismyip.com and parse that :-)

Solution 7 - Java

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

Solution 8 - Java

http://jstun.javawi.de/ will do it - provided your gateway device does STUN )most do)

Solution 9 - Java

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!

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!

Solution 10 - Java

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
import java.util.regex.Pattern;

public class ExternalIPUtil {

    private static final Pattern IPV4_PATTERN = Pattern.compile("^(([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.){3}([01]?\\d\\d?|2[0-4]\\d|25[0-5])$");

    private static final String[] IPV4_SERVICES = {
            "http://checkip.amazonaws.com/",
            "https://ipv4.icanhazip.com/",
            "http://bot.whatismyipaddress.com/"
            // and so on ...
    };

    public static String get() throws ExecutionException, InterruptedException {
        List<Callable<String>> callables = new ArrayList<>();
        for (String ipService : IPV4_SERVICES) {
            callables.add(() -> get(ipService));
        }

        ExecutorService executorService = Executors.newCachedThreadPool();
        try {
            return executorService.invokeAny(callables);
        } finally {
            executorService.shutdown();
        }
    }

    private static String get(String url) throws IOException {
        try (BufferedReader in = new BufferedReader(new InputStreamReader(new URL(url).openStream()))) {
            String ip = in.readLine();
            if (IPV4_PATTERN.matcher(ip).matches()) {
                return ip;
            } else {
                throw new IOException("invalid IPv4 address: " + ip);
            }
        }
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        System.out.println("IP: " + get());
    }
}

Get from multiple IP services concurrently such as:

and ExecutorService.invokeAny(tasks) return the result of the first successfully thread. Other tasks that have not completed will be cancelled.

Solution 11 - Java

If you are using JAVA based webapp and if you want to grab the client's (One who makes the request via a browser) external ip try deploying the app in a public domain and use request.getRemoteAddr() to read the external IP address.

Solution 12 - Java

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

Solution 13 - Java

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:

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJulioView Question on Stackoverflow
Solution 1 - JavabakkalView Answer on Stackoverflow
Solution 2 - JavaWillView Answer on Stackoverflow
Solution 3 - JavabmarguliesView Answer on Stackoverflow
Solution 4 - JavaFranciscoBouzaView Answer on Stackoverflow
Solution 5 - JavadomihView Answer on Stackoverflow
Solution 6 - Javanc3bView Answer on Stackoverflow
Solution 7 - JavaSparkoenigView Answer on Stackoverflow
Solution 8 - Javauser461467View Answer on Stackoverflow
Solution 9 - JavaJackView Answer on Stackoverflow
Solution 10 - JavaxxgView Answer on Stackoverflow
Solution 11 - JavaJayView Answer on Stackoverflow
Solution 12 - JavaMohsen AbasiView Answer on Stackoverflow
Solution 13 - JavaCarlos AlmaView Answer on Stackoverflow