Getting the 'external' IP address in Java

122,210

Solution 1

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

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

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

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

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

Share:
122,210
Julio
Author by

Julio

Updated on July 08, 2022

Comments

  • Julio
    Julio almost 2 years

    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;
        }
    }
    
  • Martijn Courteaux
    Martijn Courteaux almost 14 years
    You don't have to parse html. The first line of the webpage source of whatismyip.com is your external IP.
  • Admin
    Admin about 12 years
    I would suggest implementing at least two servers that serves your ip, in case one of them is down at the moment (with correct error handling of course). My choise would be externalip.net (click the "Need an API?" link). Have been using that site for well over a year now, haven't had any problems so far and it's a fast service that always returns a quick response.
  • pavon
    pavon over 11 years
    Thank You! While this solution won't work when the software is behind a NAT, it is still very helpful for server software that you know won't be behind a NAT, or as a fallback if the software cannot connect to another server to get it's own IP. In particular for software intended to be run on LANs disconnected from the internet, it is the way to go.
  • araisbec
    araisbec over 11 years
    Awesome link; I will be using this as part of a proof of concept on a University networking assignment!
  • Kingsolmn
    Kingsolmn over 11 years
    Another alternative would be if you have access to a web server or host account that runs PHP simply use the code @bakkal provided above and point it to your own PHP file that simply contains echo $_SERVER['REMOTE_ADDR'];. If this is the only or first output line of the script you're all set.
  • Kingsolmn
    Kingsolmn over 11 years
    Whatsmyip.com does not appear to support this type of automation any more.
  • Bruno Bossola
    Bruno Bossola about 9 years
    Or not, as it does not answer the original question, and it looks like an academic exercise
  • Bruno Bossola
    Bruno Bossola about 9 years
    Quite interesting, it works as expected without the use of external services but simply talking to the gateway. The GPL license however will probably limit its adoption.
  • Sion
    Sion about 8 years
    for those who use groovy its even easier: println new URL("http://checkip.amazonaws.com").text
  • Jus12
    Jus12 over 7 years
    Site is giving me a login screen. Probably not the original.
  • Adam893
    Adam893 about 7 years
    This is excellent! I will try it when i get home. This is exactly the kind of problem solving i was looking for. Don't know why it hasn't been voted higher.
  • Sam
    Sam over 5 years
    @stivlo Can [checkip.amazonaws.com] be used for commercial purpose?
  • Thomas Carlisle
    Thomas Carlisle over 4 years
    To be fair, this answer does answer the question and the other dozen answers all basically say the same thing but show code or URLs specific to any given choice of external ip checker.