I would like to create a singleton that contains the MAC address of the system it is running on, based on a supplied network interface.
I have written the following code:
public class NodeMac {
private static final String INSTANCE = getMacAddress();
private static String networkInterfaceName;
#Value("${machine.network.interface}")
public void setNetworkInterfaceName(String networkInterfaceName) {
NodeMac.networkInterfaceName = networkInterfaceName;
}
private NodeMac() { }
public static String getInstance() {
return INSTANCE;
}
private static String getMacAddress() {
try {
NetworkInterface network = NetworkInterface.getByName(networkInterfaceName);
byte[] mac = network.getHardwareAddress();
System.out.print("Current MAC address : ");
StringBuilder sb = new StringBuilder();
for (int i = 0; i < mac.length; i++) {
sb.append(String.format("%02X%s", mac[i], (i < mac.length - 1) ? "-" : ""));
}
return sb.toString();
} catch (SocketException | NullPointerException e) {
throw new RuntimeException(
"Failed to extract MAC address for network interface with name " + networkInterfaceName, e);
}
}
}
And in application.properties:
machine.network.interface=eno1
However, I can't find any way to get the property value that contains the name of the network interface. It is always null, no matter how I try to access it.
What is the correct way to do this? Is it an anti-pattern to have a property in a singleton?
Edit
So you're struggling to create single instance pojo class with injected #Value. If you can work with bean then this is the way to go:
#Component // This will default give you a single ton bean
public class NodeMac {
#Value("${machine.network.interface}")
private String networkInterfaceName;
public String getMacAddress() {
try {
NetworkInterface network = NetworkInterface.getByName(networkInterfaceName);
byte[] mac = network.getHardwareAddress();
System.out.print("Current MAC address : ");
StringBuilder sb = new StringBuilder();
for (int i = 0; i < mac.length; i++) {
sb.append(String.format("%02X%s", mac[i], (i < mac.length - 1) ? "-" : ""));
}
return sb.toString();
} catch (SocketException | NullPointerException e) {
throw new RuntimeException(
"Failed to extract MAC address for network interface with name " + networkInterfaceName, e);
}
}
}
OLD
How do you come up with this expression:
String key = System.getProperty("machine.network.interface");
The machine unlikely have only one network interface so there can't be a single key returned.
Indeed, oracle already writes a tutorial here
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");
}
Is it possible to get the IP address of the device using some code?
This is my helper util to read IP and MAC addresses. Implementation is pure-java, but I have a comment block in getMACAddress() which could read the value from the special Linux(Android) file. I've run this code only on few devices and Emulator but let me know here if you find weird results.
// AndroidManifest.xml permissions
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
// test functions
Utils.getMACAddress("wlan0");
Utils.getMACAddress("eth0");
Utils.getIPAddress(true); // IPv4
Utils.getIPAddress(false); // IPv6
Utils.java
import java.io.*;
import java.net.*;
import java.util.*;
//import org.apache.http.conn.util.InetAddressUtils;
public class Utils {
/**
* Convert byte array to hex string
* #param bytes toConvert
* #return hexValue
*/
public static String bytesToHex(byte[] bytes) {
StringBuilder sbuf = new StringBuilder();
for(int idx=0; idx < bytes.length; idx++) {
int intVal = bytes[idx] & 0xff;
if (intVal < 0x10) sbuf.append("0");
sbuf.append(Integer.toHexString(intVal).toUpperCase());
}
return sbuf.toString();
}
/**
* Get utf8 byte array.
* #param str which to be converted
* #return array of NULL if error was found
*/
public static byte[] getUTF8Bytes(String str) {
try { return str.getBytes("UTF-8"); } catch (Exception ex) { return null; }
}
/**
* Load UTF8withBOM or any ansi text file.
* #param filename which to be converted to string
* #return String value of File
* #throws java.io.IOException if error occurs
*/
public static String loadFileAsString(String filename) throws java.io.IOException {
final int BUFLEN=1024;
BufferedInputStream is = new BufferedInputStream(new FileInputStream(filename), BUFLEN);
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream(BUFLEN);
byte[] bytes = new byte[BUFLEN];
boolean isUTF8=false;
int read,count=0;
while((read=is.read(bytes)) != -1) {
if (count==0 && bytes[0]==(byte)0xEF && bytes[1]==(byte)0xBB && bytes[2]==(byte)0xBF ) {
isUTF8=true;
baos.write(bytes, 3, read-3); // drop UTF8 bom marker
} else {
baos.write(bytes, 0, read);
}
count+=read;
}
return isUTF8 ? new String(baos.toByteArray(), "UTF-8") : new String(baos.toByteArray());
} finally {
try{ is.close(); } catch(Exception ignored){}
}
}
/**
* Returns MAC address of the given interface name.
* #param interfaceName eth0, wlan0 or NULL=use first interface
* #return mac address or empty string
*/
public static String getMACAddress(String interfaceName) {
try {
List<NetworkInterface> interfaces = Collections.list(NetworkInterface.getNetworkInterfaces());
for (NetworkInterface intf : interfaces) {
if (interfaceName != null) {
if (!intf.getName().equalsIgnoreCase(interfaceName)) continue;
}
byte[] mac = intf.getHardwareAddress();
if (mac==null) return "";
StringBuilder buf = new StringBuilder();
for (byte aMac : mac) buf.append(String.format("%02X:",aMac));
if (buf.length()>0) buf.deleteCharAt(buf.length()-1);
return buf.toString();
}
} catch (Exception ignored) { } // for now eat exceptions
return "";
/*try {
// this is so Linux hack
return loadFileAsString("/sys/class/net/" +interfaceName + "/address").toUpperCase().trim();
} catch (IOException ex) {
return null;
}*/
}
/**
* Get IP address from first non-localhost interface
* #param useIPv4 true=return ipv4, false=return ipv6
* #return address or empty string
*/
public static String getIPAddress(boolean useIPv4) {
try {
List<NetworkInterface> interfaces = Collections.list(NetworkInterface.getNetworkInterfaces());
for (NetworkInterface intf : interfaces) {
List<InetAddress> addrs = Collections.list(intf.getInetAddresses());
for (InetAddress addr : addrs) {
if (!addr.isLoopbackAddress()) {
String sAddr = addr.getHostAddress();
//boolean isIPv4 = InetAddressUtils.isIPv4Address(sAddr);
boolean isIPv4 = sAddr.indexOf(':')<0;
if (useIPv4) {
if (isIPv4)
return sAddr;
} else {
if (!isIPv4) {
int delim = sAddr.indexOf('%'); // drop ip6 zone suffix
return delim<0 ? sAddr.toUpperCase() : sAddr.substring(0, delim).toUpperCase();
}
}
}
}
}
} catch (Exception ignored) { } // for now eat exceptions
return "";
}
}
Disclaimer: Ideas and example code to this Utils class came from
several SO posts and Google. I have cleaned and merged all examples.
With permission ACCESS_WIFI_STATE declared in AndroidManifest.xml:
<uses-permission
android:name="android.permission.ACCESS_WIFI_STATE"/>
One can use the WifiManager to obtain the IP address:
Context context = requireContext().getApplicationContext();
WifiManager wm = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
String ip = Formatter.formatIpAddress(wm.getConnectionInfo().getIpAddress());
public static String getLocalIpAddress() {
try {
for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
NetworkInterface intf = en.nextElement();
for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) {
InetAddress inetAddress = enumIpAddr.nextElement();
if (!inetAddress.isLoopbackAddress() && inetAddress instanceof Inet4Address) {
return inetAddress.getHostAddress();
}
}
}
} catch (SocketException ex) {
ex.printStackTrace();
}
return null;
}
I've added inetAddress instanceof Inet4Address to check if it is a ipv4 address.
I used following code:
The reason I used hashCode was because I was getting some garbage values appended to the ip address when I used getHostAddress . But hashCode worked really well for me as then I can use Formatter to get the ip address with correct formatting.
Here is the example output :
1.using getHostAddress : ***** IP=fe80::65ca:a13d:ea5a:233d%rmnet_sdio0
2.using hashCode and Formatter : ***** IP=238.194.77.212
As you can see 2nd methods gives me exactly what I need.
public String getLocalIpAddress() {
try {
for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
NetworkInterface intf = en.nextElement();
for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) {
InetAddress inetAddress = enumIpAddr.nextElement();
if (!inetAddress.isLoopbackAddress()) {
String ip = Formatter.formatIpAddress(inetAddress.hashCode());
Log.i(TAG, "***** IP="+ ip);
return ip;
}
}
}
} catch (SocketException ex) {
Log.e(TAG, ex.toString());
}
return null;
}
Though there's a correct answer, I share my answer here and hope that this way will more convenience.
WifiManager wifiMan = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
WifiInfo wifiInf = wifiMan.getConnectionInfo();
int ipAddress = wifiInf.getIpAddress();
String ip = String.format("%d.%d.%d.%d", (ipAddress & 0xff),(ipAddress >> 8 & 0xff),(ipAddress >> 16 & 0xff),(ipAddress >> 24 & 0xff));
Below code might help you.. Don't forget to add permissions..
public String getLocalIpAddress(){
try {
for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces();
en.hasMoreElements();) {
NetworkInterface intf = en.nextElement();
for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) {
InetAddress inetAddress = enumIpAddr.nextElement();
if (!inetAddress.isLoopbackAddress()) {
return inetAddress.getHostAddress();
}
}
}
} catch (Exception ex) {
Log.e("IP Address", ex.toString());
}
return null;
}
Add below permission in the manifest file.
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
happy coding!!
kotlin minimalist version
fun getIpv4HostAddress(): String {
NetworkInterface.getNetworkInterfaces()?.toList()?.map { networkInterface ->
networkInterface.inetAddresses?.toList()?.find {
!it.isLoopbackAddress && it is Inet4Address
}?.let { return it.hostAddress }
}
return ""
}
You do not need to add permissions like what is the case with the solutions provided so far. Download this website as a string:
http://www.ip-api.com/json
or
http://www.telize.com/geoip
Downloading a website as a string can be done with java code:
http://www.itcuties.com/java/read-url-to-string/
Parse the JSON object like this:
https://stackoverflow.com/a/18998203/1987258
The json attribute "query" or "ip" contains the IP address.
private InetAddress getLocalAddress()throws IOException {
try {
for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
NetworkInterface intf = en.nextElement();
for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) {
InetAddress inetAddress = enumIpAddr.nextElement();
if (!inetAddress.isLoopbackAddress()) {
//return inetAddress.getHostAddress().toString();
return inetAddress;
}
}
}
} catch (SocketException ex) {
Log.e("SALMAN", ex.toString());
}
return null;
}
Method getDeviceIpAddress returns device's ip address and prefers wifi interface address if it connected.
#NonNull
private String getDeviceIpAddress() {
String actualConnectedToNetwork = null;
ConnectivityManager connManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
if (connManager != null) {
NetworkInfo mWifi = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
if (mWifi.isConnected()) {
actualConnectedToNetwork = getWifiIp();
}
}
if (TextUtils.isEmpty(actualConnectedToNetwork)) {
actualConnectedToNetwork = getNetworkInterfaceIpAddress();
}
if (TextUtils.isEmpty(actualConnectedToNetwork)) {
actualConnectedToNetwork = "127.0.0.1";
}
return actualConnectedToNetwork;
}
#Nullable
private String getWifiIp() {
final WifiManager mWifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
if (mWifiManager != null && mWifiManager.isWifiEnabled()) {
int ip = mWifiManager.getConnectionInfo().getIpAddress();
return (ip & 0xFF) + "." + ((ip >> 8) & 0xFF) + "." + ((ip >> 16) & 0xFF) + "."
+ ((ip >> 24) & 0xFF);
}
return null;
}
#Nullable
public String getNetworkInterfaceIpAddress() {
try {
for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements(); ) {
NetworkInterface networkInterface = en.nextElement();
for (Enumeration<InetAddress> enumIpAddr = networkInterface.getInetAddresses(); enumIpAddr.hasMoreElements(); ) {
InetAddress inetAddress = enumIpAddr.nextElement();
if (!inetAddress.isLoopbackAddress() && inetAddress instanceof Inet4Address) {
String host = inetAddress.getHostAddress();
if (!TextUtils.isEmpty(host)) {
return host;
}
}
}
}
} catch (Exception ex) {
Log.e("IP Address", "getLocalIpAddress", ex);
}
return null;
}
In your activity, the following function getIpAddress(context) returns the phone's IP address:
public static String getIpAddress(Context context) {
WifiManager wifiManager = (WifiManager) context.getApplicationContext()
.getSystemService(WIFI_SERVICE);
String ipAddress = intToInetAddress(wifiManager.getDhcpInfo().ipAddress).toString();
ipAddress = ipAddress.substring(1);
return ipAddress;
}
public static InetAddress intToInetAddress(int hostAddress) {
byte[] addressBytes = { (byte)(0xff & hostAddress),
(byte)(0xff & (hostAddress >> 8)),
(byte)(0xff & (hostAddress >> 16)),
(byte)(0xff & (hostAddress >> 24)) };
try {
return InetAddress.getByAddress(addressBytes);
} catch (UnknownHostException e) {
throw new AssertionError();
}
}
This is a rework of this answer which strips out irrelevant information, adds helpful comments, names variables more clearly, and improves the logic.
Don't forget to include the following permissions:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
InternetHelper.java:
public class InternetHelper {
/**
* Get IP address from first non-localhost interface
*
* #param useIPv4 true=return ipv4, false=return ipv6
* #return address or empty string
*/
public static String getIPAddress(boolean useIPv4) {
try {
List<NetworkInterface> interfaces =
Collections.list(NetworkInterface.getNetworkInterfaces());
for (NetworkInterface interface_ : interfaces) {
for (InetAddress inetAddress :
Collections.list(interface_.getInetAddresses())) {
/* a loopback address would be something like 127.0.0.1 (the device
itself). we want to return the first non-loopback address. */
if (!inetAddress.isLoopbackAddress()) {
String ipAddr = inetAddress.getHostAddress();
boolean isIPv4 = ipAddr.indexOf(':') < 0;
if (isIPv4 && !useIPv4) {
continue;
}
if (useIPv4 && !isIPv4) {
int delim = ipAddr.indexOf('%'); // drop ip6 zone suffix
ipAddr = delim < 0 ? ipAddr.toUpperCase() :
ipAddr.substring(0, delim).toUpperCase();
}
return ipAddr;
}
}
}
} catch (Exception ignored) { } // if we can't connect, just return empty string
return "";
}
/**
* Get IPv4 address from first non-localhost interface
*
* #return address or empty string
*/
public static String getIPAddress() {
return getIPAddress(true);
}
}
WifiManager wm = (WifiManager) getSystemService(WIFI_SERVICE);
String ipAddress = BigInteger.valueOf(wm.getDhcpInfo().netmask).toString();
public static String getdeviceIpAddress() {
try {
for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
NetworkInterface intf = en.nextElement();
for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) {
InetAddress inetAddress = enumIpAddr.nextElement();
if (!inetAddress.isLoopbackAddress() && inetAddress instanceof Inet4Address) {
return inetAddress.getHostAddress();
}
}
}
} catch (SocketException ex) {
ex.printStackTrace();
}
return null;
}
You can use LinkProperties. It's recommended for new Android versions.
This function retrieves local IP address for both WiFi and Mobile Data. It requires Manifest.permission.ACCESS_NETWORK_STATE permission.
#Nullable
public static String getDeviceIpAddress(#NonNull ConnectivityManager connectivityManager) {
LinkProperties linkProperties = connectivityManager.getLinkProperties(connectivityManager.getActiveNetwork());
InetAddress inetAddress;
for(LinkAddress linkAddress : linkProperties.getLinkAddresses()) {
inetAddress = linkAddress.getAddress();
if (inetAddress instanceof Inet4Address
&& !inetAddress.isLoopbackAddress()
&& inetAddress.isSiteLocalAddress()) {
return inetAddress.getHostAddress();
}
}
return null;
}
Recently, an IP address is still returned by getLocalIpAddress() despite being disconnected from the network (no service indicator). It means the IP address displayed in the Settings> About phone> Status was different from what the application thought.
I have implemented a workaround by adding this code before:
ConnectivityManager cm = getConnectivityManager();
NetworkInfo net = cm.getActiveNetworkInfo();
if ((null == net) || !net.isConnectedOrConnecting()) {
return null;
}
Does that ring a bell to anyone?
Simply use Volley to get the ip from this site
RequestQueue queue = Volley.newRequestQueue(this);
String urlip = "http://checkip.amazonaws.com/";
StringRequest stringRequest = new StringRequest(Request.Method.GET, urlip, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
txtIP.setText(response);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
txtIP.setText("didnt work");
}
});
queue.add(stringRequest);
in Kotlin, without Formatter
private fun getIPAddress(useIPv4 : Boolean): String {
try {
var interfaces = Collections.list(NetworkInterface.getNetworkInterfaces())
for (intf in interfaces) {
var addrs = Collections.list(intf.getInetAddresses());
for (addr in addrs) {
if (!addr.isLoopbackAddress()) {
var sAddr = addr.getHostAddress();
var isIPv4: Boolean
isIPv4 = sAddr.indexOf(':')<0
if (useIPv4) {
if (isIPv4)
return sAddr;
} else {
if (!isIPv4) {
var delim = sAddr.indexOf('%') // drop ip6 zone suffix
if (delim < 0) {
return sAddr.toUpperCase()
}
else {
return sAddr.substring(0, delim).toUpperCase()
}
}
}
}
}
}
} catch (e: java.lang.Exception) { }
return ""
}
A device might have several IP addresses, and the one in use in a particular app might not be the IP that servers receiving the request will see. Indeed, some users use a VPN or a proxy such as Cloudflare Warp.
If your purpose is to get the IP address as shown by servers that receive requests from your device, then the best is to query an IP geolocation service such as Ipregistry (disclaimer: I work for the company) with its Java client:
https://github.com/ipregistry/ipregistry-java
IpregistryClient client = new IpregistryClient("tryout");
RequesterIpInfo requesterIpInfo = client.lookup();
requesterIpInfo.getIp();
In addition to being really simple to use, you get additional information such as country, language, currency, the time zone for the device IP and you can identify whether the user is using a proxy.
This is the easiest and simple way ever exist on the internet...
First of all, add this permission to your manifest file...
"INTERNET"
"ACCESS_NETWORK_STATE"
add this in onCreate file of Activity..
getPublicIP();
Now Add this function to your MainActivity.class.
private void getPublicIP() {
ArrayList<String> urls=new ArrayList<String>(); //to read each line
new Thread(new Runnable(){
public void run(){
//TextView t; //to show the result, please declare and find it inside onCreate()
try {
// Create a URL for the desired page
URL url = new URL("https://api.ipify.org/"); //My text file location
//First open the connection
HttpURLConnection conn=(HttpURLConnection) url.openConnection();
conn.setConnectTimeout(60000); // timing out in a minute
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
//t=(TextView)findViewById(R.id.TextView1); // ideally do this in onCreate()
String str;
while ((str = in.readLine()) != null) {
urls.add(str);
}
in.close();
} catch (Exception e) {
Log.d("MyTag",e.toString());
}
//since we are in background thread, to post results we have to go back to ui thread. do the following for that
PermissionsActivity.this.runOnUiThread(new Runnable(){
public void run(){
try {
Toast.makeText(PermissionsActivity.this, "Public IP:"+urls.get(0), Toast.LENGTH_SHORT).show();
}
catch (Exception e){
Toast.makeText(PermissionsActivity.this, "TurnOn wiffi to get public ip", Toast.LENGTH_SHORT).show();
}
}
});
}
}).start();
}
Here is kotlin version of #Nilesh and #anargund
fun getIpAddress(): String {
var ip = ""
try {
val wm = applicationContext.getSystemService(WIFI_SERVICE) as WifiManager
ip = Formatter.formatIpAddress(wm.connectionInfo.ipAddress)
} catch (e: java.lang.Exception) {
}
if (ip.isEmpty()) {
try {
val en = NetworkInterface.getNetworkInterfaces()
while (en.hasMoreElements()) {
val networkInterface = en.nextElement()
val enumIpAddr = networkInterface.inetAddresses
while (enumIpAddr.hasMoreElements()) {
val inetAddress = enumIpAddr.nextElement()
if (!inetAddress.isLoopbackAddress && inetAddress is Inet4Address) {
val host = inetAddress.getHostAddress()
if (host.isNotEmpty()) {
ip = host
break;
}
}
}
}
} catch (e: java.lang.Exception) {
}
}
if (ip.isEmpty())
ip = "127.0.0.1"
return ip
}
Compiling some of the ideas to get the wifi ip from the WifiManager in a nicer kotlin solution:
private fun getWifiIp(context: Context): String? {
return context.getSystemService<WifiManager>().let {
when {
it == null -> "No wifi available"
!it.isWifiEnabled -> "Wifi is disabled"
it.connectionInfo == null -> "Wifi not connected"
else -> {
val ip = it.connectionInfo.ipAddress
((ip and 0xFF).toString() + "." + (ip shr 8 and 0xFF) + "." + (ip shr 16 and 0xFF) + "." + (ip shr 24 and 0xFF))
}
}
}
}
Alternatively you can get the ip adresses of ip4 loopback devices via the NetworkInterface:
fun getNetworkIp4LoopbackIps(): Map<String, String> = try {
NetworkInterface.getNetworkInterfaces()
.asSequence()
.associate { it.displayName to it.ip4LoopbackIps() }
.filterValues { it.isNotEmpty() }
} catch (ex: Exception) {
emptyMap()
}
private fun NetworkInterface.ip4LoopbackIps() =
inetAddresses.asSequence()
.filter { !it.isLoopbackAddress && it is Inet4Address }
.map { it.hostAddress }
.filter { it.isNotEmpty() }
.joinToString()
Blockquote
// get Device Ip Address
open fun getLocalIpAddress(): String? {
try {
val en: Enumeration<NetworkInterface> = NetworkInterface.getNetworkInterfaces()
while (en.hasMoreElements()) {
val networkInterface: NetworkInterface = en.nextElement()
val enumerationIpAddress: Enumeration<InetAddress> = networkInterface.inetAddresses
while (enumerationIpAddress.hasMoreElements()) {
val inetAddress: InetAddress = enumerationIpAddress.nextElement()
if (!inetAddress.isLoopbackAddress && inetAddress is Inet4Address) {
return inetAddress.getHostAddress()
}
}
}
} catch (ex: SocketException) {
ex.printStackTrace()
}
return null
}
If you have a shell ; ifconfig eth0 worked for x86 device too
Please check this code...Using this code. we will get ip from mobile internet...
for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements(); ) {
NetworkInterface intf = en.nextElement();
for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements(); ) {
InetAddress inetAddress = enumIpAddr.nextElement();
if (!inetAddress.isLoopbackAddress()) {
return inetAddress.getHostAddress().toString();
}
}
}
I don't do Android, but I'd tackle this in a totally different way.
Send a query to Google, something like:
https://www.google.com/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=my%20ip
And refer to the HTML field where the response is posted. You may also query directly to the source.
Google will most like be there for longer than your Application.
Just remember, it could be that your user does not have internet at this time, what would you like to happen !
Good Luck
You can do this
String stringUrl = "https://ipinfo.io/ip";
//String stringUrl = "http://whatismyip.akamai.com/";
// Instantiate the RequestQueue.
RequestQueue queue = Volley.newRequestQueue(MainActivity.instance);
//String url ="http://www.google.com";
// Request a string response from the provided URL.
StringRequest stringRequest = new StringRequest(Request.Method.GET, stringUrl,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
// Display the first 500 characters of the response string.
Log.e(MGLogTag, "GET IP : " + response);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
IP = "That didn't work!";
}
});
// Add the request to the RequestQueue.
queue.add(stringRequest);
// #NonNull
public static String getIPAddress() {
if (TextUtils.isEmpty(deviceIpAddress))
new PublicIPAddress().execute();
return deviceIpAddress;
}
public static String deviceIpAddress = "";
public static class PublicIPAddress extends AsyncTask<String, Void, String> {
InetAddress localhost = null;
protected String doInBackground(String... urls) {
try {
localhost = InetAddress.getLocalHost();
URL url_name = new URL("http://bot.whatismyipaddress.com");
BufferedReader sc = new BufferedReader(new InputStreamReader(url_name.openStream()));
deviceIpAddress = sc.readLine().trim();
} catch (Exception e) {
deviceIpAddress = "";
}
return deviceIpAddress;
}
protected void onPostExecute(String string) {
Lg.d("deviceIpAddress", string);
}
}
In all honesty I am only a little familiar with code safety, so this may be hack-ish. But for me this is the most versatile way to do it:
package com.my_objects.ip;
import java.net.InetAddress;
import java.net.UnknownHostException;
public class MyIpByHost
{
public static void main(String a[])
{
try
{
InetAddress host = InetAddress.getByName("nameOfDevice or webAddress");
System.out.println(host.getHostAddress());
}
catch (UnknownHostException e)
{
e.printStackTrace();
}
} }
For kotlin language.
fun contextIP(context: Context): String {
val wm: WifiManager = context.getSystemService(Context.WIFI_SERVICE) as WifiManager
return Formatter.formatIpAddress(wm.connectionInfo.ipAddress)
}
Question: Are the ports wrong (to make an udp punch)?
I got a Java server that save ip and ports from connecting clients and servers. The ip and ports is sent to the client and server so they can start a udp hole punch. I use 2 computer connected to the same NAT. But it refuse to work.
The java server log say:
Send server global ip and port 61721 to client
Send client global ip and port 63105 to server
The server and client start to send udp packets but after some time they timeout.
I used Wireshark to check the hole punch and the client log looks like this:
Source Destination Info
192.168.1.78 206.217.173.176 UDP source port: 50701 Destination Port: 61721
192.168.1.78 206.217.173.176 UDP source port: 50701 Destination Port: 61721
... + 50 more
Server log:
Source Destination Info
192.168.1.73 206.217.173.176 UDP source port: 6510 Destination Port: 63105
192.168.1.73 206.217.173.176 UDP source port: 6510 Destination Port: 63105
... + 50 more
No packets from the client is found on the server log. And no server packets is found on the client log.
This is the Java server code:
Full code can be found on: https://github.com/Parakoopa/GMnet-GATE-PUNCH/tree/master/src/main/java/org/parakoopa/gmnetgate/punch
Server.java
package org.parakoopa.gmnetgate.punch;
import com.google.gson.annotations.Expose;
import java.net.Socket;
public class Server {
/**
* Contains the IP of this server
*/
#Expose private String ip = "";
/**
* Contains the Ports of the Server.
* A port is assigned to an ip, so only one ip per server is possible.
*/
private Integer port = 0;
/**
* Contains the TCP Sockets of the Server.
* For sending the connection requests to the servers.
*/
private Socket tcp_socket = null;
/**
* The 8 data strings.
*/
#Expose private String data1 = "";
#Expose private String data2 = "";
#Expose private String data3 = "";
#Expose private String data4 = "";
#Expose private String data5 = "";
#Expose private String data6 = "";
#Expose private String data7 = "";
#Expose private String data8 = "";
/**
* Time the server was created
*/
#Expose private long createdTime;
public Server(String ip) {
this.createdTime = System.currentTimeMillis() / 1000L;
this.ip = ip;
}
/**
* Contains the Ports of the Server.
* A port is assigned to an ip, so only one ip per server is possible.
*/
public Integer getPort() {
return port;
}
public void setPort(Integer port) {
this.port = port;
}
/**
* Contains the TCP Sockets of the Server.
* For sending the connection requests to the servers.
*/
public Socket getTCPsocket() {
return tcp_socket;
}
public void setTCPsocket(Socket tcp_socket) {
this.tcp_socket = tcp_socket;
}
public String getData1() {
return data1;
}
public void setData1(String data1) {
this.data1 = data1;
}
public String getData2() {
return data2;
}
public void setData2(String data2) {
this.data2 = data2;
}
public String getData3() {
return data3;
}
public void setData3(String data3) {
this.data3 = data3;
}
public String getData4() {
return data4;
}
public void setData4(String data4) {
this.data4 = data4;
}
public String getData5() {
return data5;
}
public void setData5(String data5) {
this.data5 = data5;
}
public String getData6() {
return data6;
}
public void setData6(String data6) {
this.data6 = data6;
}
public String getData7() {
return data7;
}
public void setData7(String data7) {
this.data7 = data7;
}
public String getData8() {
return data8;
}
public void setData8(String data8) {
this.data8 = data8;
}
public long getCreatedTime() {
return createdTime;
}
}
TCPConnection.java:
package org.parakoopa.gmnetgate.punch;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
/**
* Handles incoming TCP connections.
* Stores server sockets and on client request send server ports to client and
* client ports to server via the stored socket.
* #author Parakoopa
*/
public class TCPConnection implements Runnable {
private Mediator main;
private Socket client;
private ServerSocket server;
/** Game Maker Studio seperates strings in buffers with this char (buffer_string). */
private char gm_string_seperator = 0;
/** True, if the "reg" command was used on this connection **/
private boolean isServer = false;
/**
* Set's up a new connection listener that handles all packets of one connection.
* #param main Mediator class instance that this server was created with.
* #param client Socket that the client is connected to.
* #param server Our TCP server socket the client is connected to. (not actually used)
*/
public TCPConnection(Mediator main, Socket client, ServerSocket server) {
this.server = server;
this.client = client;
this.main = main;
}
/**
* Starts listening for incoming packets and responds to it.
*/
#Override
public void run() {
String debug_string = this.client.getInetAddress().getHostAddress()+":"+this.client.getPort()+" | TCP | ";
Mediator.log(debug_string+" Connected!",true);
try {
//TcpNoDelay configures the socket to transfer messages immediately, otherwise GM:S won't pick them up
this.client.setTcpNoDelay(true);
//Input and Output streams. We write bytes out and take Strings in.
OutputStream out = client.getOutputStream();
BufferedReader in = new BufferedReader(
new InputStreamReader(client.getInputStream()));
String inputLine;
Server serverObj;
//Process all packets. This while loop will stop when the peer disconnected.
while ((inputLine = in.readLine()) != null) {
//This will kill Threads (or commands) if the client don't send
//all of the data expected. Needed otherwise this could lead
//to many hanging threads.
client.setSoTimeout(1000);
//Cleans string, it might contain some garbage characters.
inputLine = inputLine.replaceAll("\\p{C}", "");
switch (inputLine) {
case "reg2":
Mediator.log(debug_string+" Server wants to register!",true);
//A server wants to register/reregister. We put the socket in the socket map so we can use it later.
//Check version compatibility
String version = in.readLine().replaceAll("\\p{C}", "");
Mediator.log(debug_string+" Version: "+version,true);
if (!(Mediator.versionCompare(version,Mediator.getUdphpMin()) >= 0)) {
//For now just silently end the connection.
//Proper error messages will follow in the next release
Mediator.log(debug_string+" Server not accepted. Version too old.",true);
client.close();
return;
}
Mediator.log(debug_string+" Server registered!",false);
serverObj = this.main.getServer(this.client.getInetAddress().getHostAddress());
this.isServer = true;
serverObj.setTCPsocket(this.client);
//Write the 8 data strings
serverObj.setData1(in.readLine().replaceAll("\\p{C}", ""));
Mediator.log(debug_string+" Data 1: "+serverObj.getData1(),true);
serverObj.setData2(in.readLine().replaceAll("\\p{C}", ""));
Mediator.log(debug_string+" Data 2: "+serverObj.getData2(),true);
serverObj.setData3(in.readLine().replaceAll("\\p{C}", ""));
Mediator.log(debug_string+" Data 3: "+serverObj.getData3(),true);
serverObj.setData4(in.readLine().replaceAll("\\p{C}", ""));
Mediator.log(debug_string+" Data 4: "+serverObj.getData4(),true);
serverObj.setData5(in.readLine().replaceAll("\\p{C}", ""));
Mediator.log(debug_string+" Data 5: "+serverObj.getData5(),true);
serverObj.setData6(in.readLine().replaceAll("\\p{C}", ""));
Mediator.log(debug_string+" Data 6: "+serverObj.getData6(),true);
serverObj.setData7(in.readLine().replaceAll("\\p{C}", ""));
Mediator.log(debug_string+" Data 7: "+serverObj.getData7(),true);
serverObj.setData8(in.readLine().replaceAll("\\p{C}", ""));
Mediator.log(debug_string+" Data 8: "+serverObj.getData8(),true);
break;
case "connect":
//A client wants to connect. Now the interesting part begins
//Wait for next line that contains the requested IP adress.
String requested_server = in.readLine().replaceAll("\\p{C}", "");
String debug_string2 = debug_string + " Client <-> "+requested_server+" ->";
Mediator.log(debug_string2+" Connecting...",false);
if (this.main.getServerMap().containsKey(requested_server)) {
//SERVER FOUND
serverObj = this.main.getServer(requested_server);
//get server connection socket from the map (stored above)
Socket gameserver = serverObj.getTCPsocket();
if (!gameserver.isClosed()) {
String connect_to_server = requested_server;
//Get server port
int connect_to_port = serverObj.getPort();
//Send server port to client
Mediator.log(debug_string2+" Found server",true);
Mediator.log(debug_string2+" Send server port "+connect_to_port+" to client",true);
out.write((byte) 255);
out.write((connect_to_server+this.gm_string_seperator).getBytes());
out.write((String.valueOf(connect_to_port)+this.gm_string_seperator).getBytes());
//Send buffer to client
out.flush();
//Get client port
Client clientObj = this.main.getClient(this.client.getInetAddress().getHostAddress());
int connect_to_port_server = clientObj.getPort();
Mediator.log(debug_string2+" Send client port "+connect_to_port_server+" to server",true);
//Get an output stream for the server socket. We will contact the server with this.
OutputStream out_server = gameserver.getOutputStream();
out_server.write((byte) 255);
out_server.write((this.client.getInetAddress().getHostAddress()+this.gm_string_seperator).getBytes());
out_server.write(String.valueOf(connect_to_port_server+this.gm_string_seperator).getBytes());
//Send buffer to server
out_server.flush();
//We are done! Client and Server now connect to each other and the hole is punched!
Mediator.log(debug_string2+" CONNECTED!",false);
} else {
//SERVER FOUND BUT SOCKET IS DEAD
Mediator.log(debug_string+" CONNECTION FAILED - Server not reachable",false);
out.write((byte) 254);
out.flush();
}
} else {
//SERVER NOT FOUND
Mediator.log(debug_string+" CONECTION FAILED - Server not found",false);
out.write((byte) 254);
out.flush();
}
this.main.destroyClient(this.client.getInetAddress().getHostAddress());
break;
case "lobby2":
if (Mediator.isLobby() || Mediator.isTesting()) {
Mediator.log(debug_string+" Sending lobby based on requested filters",true);
HashMap<String, Server> servers = new HashMap<String, Server>(main.getServerMap());
String filter_data1 = in.readLine().replaceAll("\\p{C}", "");
String filter_data2 = in.readLine().replaceAll("\\p{C}", "");
String filter_data3 = in.readLine().replaceAll("\\p{C}", "");
String filter_data4 = in.readLine().replaceAll("\\p{C}", "");
String filter_data5 = in.readLine().replaceAll("\\p{C}", "");
String filter_data6 = in.readLine().replaceAll("\\p{C}", "");
String filter_data7 = in.readLine().replaceAll("\\p{C}", "");
String filter_data8 = in.readLine().replaceAll("\\p{C}", "");
final String filter_sortby = in.readLine().replaceAll("\\p{C}", "");
final String filter_sortby_dir = in.readLine().replaceAll("\\p{C}", "");
String filter_limit = in.readLine().replaceAll("\\p{C}", "");
//Skip servers with <INV> gamename (this might happen if a server was created using UDP connection but never initialized via TCP)
//TODO: Remove these invalid servers after some time.
Iterator<Map.Entry<String, Server>> iterInv = servers.entrySet().iterator();
while (iterInv.hasNext()) {
Map.Entry<String, Server> entry = iterInv.next();
if (entry.getValue().getData1().equals("<INV>")) {
iterInv.remove();
}
}
if (!"".equals(filter_data1)) {
Iterator<Map.Entry<String, Server>> iter = servers.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry<String, Server> entry = iter.next();
if (!entry.getValue().getData1().equals(filter_data1)) {
iter.remove();
}
}
}
if (!"".equals(filter_data2)) {
Iterator<Map.Entry<String, Server>> iter = servers.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry<String, Server> entry = iter.next();
if (!entry.getValue().getData2().equals(filter_data2)) {
iter.remove();
}
}
}
if (!"".equals(filter_data3)) {
Iterator<Map.Entry<String, Server>> iter = servers.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry<String, Server> entry = iter.next();
if (!entry.getValue().getData3().equals(filter_data3)) {
servers.remove(entry.getKey());
}
}
}
if (!"".equals(filter_data4)) {
Iterator<Map.Entry<String, Server>> iter = servers.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry<String, Server> entry = iter.next();
if (!entry.getValue().getData4().equals(filter_data4)) {
iter.remove();
}
}
}
if (!"".equals(filter_data5)) {
Iterator<Map.Entry<String, Server>> iter = servers.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry<String, Server> entry = iter.next();
if (!entry.getValue().getData5().equals(filter_data5)) {
iter.remove();
}
}
}
if (!"".equals(filter_data6)) {
Iterator<Map.Entry<String, Server>> iter = servers.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry<String, Server> entry = iter.next();
if (!entry.getValue().getData6().equals(filter_data6)) {
iter.remove();
}
}
}
if (!"".equals(filter_data7)) {
Iterator<Map.Entry<String, Server>> iter = servers.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry<String, Server> entry = iter.next();
if (!entry.getValue().getData7().equals(filter_data7)) {
iter.remove();
}
}
}
if (!"".equals(filter_data8)) {
Iterator<Map.Entry<String, Server>> iter = servers.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry<String, Server> entry = iter.next();
if (!entry.getValue().getData8().equals(filter_data8)) {
iter.remove();
}
}
}
Server[] arr = servers.values().toArray(new Server[servers.values().size()]);
Arrays.sort(arr, new Comparator<Server>() {
#Override
public int compare(Server o1, Server o2) {
int mp = 1;
int rt = 0;
if ("ASC".equals(filter_sortby_dir)) {
mp = -1;
}
switch (filter_sortby) {
default:
case "date":
rt = new Long(o1.getCreatedTime()).compareTo(o2.getCreatedTime()) * mp;
break;
case "data1":
rt = o1.getData1().compareTo(o2.getData1()) * mp;
break;
case "data2":
rt = o1.getData2().compareTo(o2.getData2()) * mp;
break;
case "data3":
rt = o1.getData3().compareTo(o2.getData3()) * mp;
break;
case "data4":
rt = o1.getData4().compareTo(o2.getData4()) * mp;
break;
case "data5":
rt = o1.getData5().compareTo(o2.getData5()) * mp;
break;
case "data6":
rt = o1.getData6().compareTo(o2.getData6()) * mp;
break;
case "data7":
rt = o1.getData7().compareTo(o2.getData7()) * mp;
break;
case "data8":
rt = o1.getData8().compareTo(o2.getData8()) * mp;
break;
}
return rt;
}
});
if (!"".equals(filter_limit) && Integer.valueOf(filter_limit) <= arr.length) {
arr = Arrays.copyOfRange(arr, 0, Integer.valueOf(filter_limit));
}
Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
String json = gson.toJson(arr);
out.write((byte) 249);
out.write(json.getBytes());
out.write(10);
//Send buffer to server
out.flush();
}
break;
case "istesting":
out.write((byte) 248);
if (Mediator.isTesting()) {
Mediator.log(debug_string+" Sending if testing is enabled",true);
out.write((byte) 1);
} else {
out.write((byte) 0);
}
//Send buffer
out.flush();
break;
case "testinginfos":
out.write((byte) 247);
if (Mediator.isTesting()) {
Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
out.write(Mediator.getName().getBytes());
out.write(10);
out.write(Mediator.getVersion().getBytes());
out.write(10);
out.write(Mediator.getUdphpMin().getBytes());
out.write(10);
Mediator.log(debug_string+" Sending testing information",true);
} else {
out.write((byte) 0);
}
//Send buffer
out.flush();
break;
case "version":
out.write((byte) 246);
out.write(Mediator.getVersion().getBytes());
out.write(10);
Mediator.log(debug_string+" Sending version information",true);
//Send buffer
out.flush();
break;
default:
//Ignore unknown commands (client disconnection will cause an unknown command)
break;
}
//Disable timout again and wait for next command
client.setSoTimeout(0);
}
client.close();
Mediator.log(debug_string+" Disconnected!",true);
//Cleanup, when they loose TCP connection, this data can't be used anymore, so it's safe to remove
if (this.isServer) {
this.main.destroyServer(this.client.getInetAddress().getHostAddress());
Mediator.log(debug_string+" Server deleted!",false);
}
} catch (Exception ex) {
Mediator.log(debug_string+" Disconnected (e: "+ex.getClass().getName()+")",true);
//Cleanup, when they loose TCP connection, this data can't be used anymore, so it's safe to remove
if (this.isServer) {
this.main.destroyServer(this.client.getInetAddress().getHostAddress());
Mediator.log(debug_string+" Server deleted!",false);
}
}
}
}
The ports where not wrong. The NAT had been updated by my provider behind my back. They made it more "secure". UDP Punch is not possible anymore with my NAT because it treat punch as an attack and block it.
Is there a way in Java to tell it to return IPv6 only? I've tried everything and can't get it to work.
try
{
InetAddress inet = InetAddress.getByName(hostName);
boolean status = inet.isReachable(5000);
if (status)
{
System.out.println(inet.getCanonicalHostName() + " Host Reached\t" + java.net.Inet6Address.getByName(hostName).getHostAddress());
}
else
{
System.out.println(inet.getCanonicalHostName() + " Host Unreachable");
}
}
catch (UnknownHostException e)
{
System.err.println("Host does not exists");
}
catch (IOException e)
{
System.err.println("Error in reaching the Host");
}
The line I use to try to return IPv6 only:
System.out.println(inet.getCanonicalHostName() + " Host Reached\t" + java.net.Inet6Address.getByName(hostName).getHostAddress());
This keeps returning IPv4. Anyone have any idea of why its doing this?
java.net.Inet6Address does not override getByName()
so it will always return the specific IPv4-Address,
unless your parameter itself is in the form of an valid IPv6-Address, in this case this method will return an Inet6Address-Object.
For example:
getByName("stackoverflow.com") --> Inet4Address
getByName("2001:0db8:85a3:08d3:1319:8a2e:0370:7344") --> Inet6Address
InetAddress.getByName()-Documentation
Determines the IP address of a host, given the host's name. The host name can either be a machine name, such as "java.sun.com", or a
textual representation of its IP address. If a literal IP address is
supplied, only the validity of the address format is checked.
> For host specified in literal IPv6 address, either the form defined in
RFC 2732 or the literal IPv6 address format defined in RFC 2373 is
accepted.<
So if you want to get an IPv6-Address you need to define it within your parameter, or configure a DNS-Server to return the IPv6-Address instead of the IPv4-Address.
Another way to retrieve the IPv6-Address is using InetAddress.getAllByName("www.google.at") which returns all known IP-Addresses of the host.
For example you can use this method to filter the returned array, which return the first IPv6-Address or null if the host don't have one:
public Inet6Address getIPv6Addresses(InetAddress[] addresses) {
for (InetAddress addr : addresses) {
if (addr instanceof Inet6Address) {
return (Inet6Address) addr;
}
}
return null;
}
UPDATE:
For more functions, especially those affecting DNS-Servers, I recommend using the external library DNSJava, because the plain Java implementation of DNS support is poor.
http://www.dnsjava.org/
Current Code:
public class Ping
{
public void pingHost (String hostName)
{
try
{
InetAddress[] inet = InetAddress.getAllByName(hostName);
String address = this.getIPv4Addresses(inet).getHostAddress();
boolean status = this.getIPv6Addresses(inet).isReachable(5000);
if (status)
{
System.out.println(reverseDns(address) + " Host Reached\t" + this.getIPv6Addresses(inet).getHostAddress());
}
else
{
System.out.println(this.getIPv6Addresses(inet).getCanonicalHostName() + " Host Unreachable");
}
}
catch (UnknownHostException e)
{
System.err.println("Host does not exists");
}
catch (IOException e)
{
System.err.println("Error in reaching the Host");
}
}
public Inet6Address getIPv6Addresses(InetAddress[] addresses)
{
for (InetAddress addr : addresses)
{
if (addr instanceof Inet6Address)
{
return (Inet6Address) addr;
}
}
return null;
}
public Inet4Address getIPv4Addresses(InetAddress[] addresses)
{
for (InetAddress addr : addresses)
{
if (addr instanceof Inet4Address)
{
return (Inet4Address) addr;
}
}
return null;
}
public static String reverseDns(String hostIp) throws IOException
{
Resolver res = new ExtendedResolver();
Name name = ReverseMap.fromAddress(hostIp);
int type = Type.PTR;
int dclass = DClass.IN;
Record rec = Record.newRecord(name, type, dclass);
Message query = Message.newQuery(rec);
Message response = res.send(query);
Record[] answers = response.getSectionArray(Section.ANSWER);
if (answers.length == 0)
return hostIp;
else
return answers[0].rdataToString();
}
}
You could try to define JVM_ARGS
-Djava.net.preferIPv4Stack=false -Djava.net.preferIPv6Addresses=true
with that props it will prefer IPv6 addr on InetAddress#getByName
More info: https://docs.oracle.com/javase/8/docs/technotes/guides/net/ipv6_guide/