Return IPv6 in Java - java

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/

Related

FTPClient FTPFile details not available

I am trying to get the list of files from remote FTP server. The ftpClient.listFiles() returned null and I had to set setUnparseableEntries to true to get the list of files. Even then the list of files do not have any information like name and only information it has is rawlisting and others are null. So I cannot do ftpFile.getName. Here is the code
public FTPFile[] process() throws Exception {
String message = null;
FTPFile[] files = null;
FTPClient ftpClient = new FTPClient();
FTPClientConfig config = new FTPClientConfig();
config.setServerTimeZoneId("America/Chicago");
config.setUnparseableEntries(true);
ftpClient.configure(config);
if ( !connectToServer() ) return null;
if ( !changeDirectory() ) {
disconnectFromServer();
return null;
}
files = getListofFiles();
disconnectFromServer();
return files;
}
private boolean connectToServer() {
boolean result = true;
String message = null, url = null;
// attempt to connect to the target server
try {
url = fo.getServerInfo().getConnectionURL();
LOGGER.debug("Connecting to: " + url);
ftpClient.connect(fo.getServerInfo().getHostName(),
fo.getServerInfo().getHostPort());
ftpClient.enterLocalPassiveMode();
} catch(SocketException e) {
result = false;
message = "Could not connect to server at " + url;
} catch(IOException e) {
result = false;
message = "Could not connect to server at " + url;
}
if ( !result ) return result;
// After connection attempt, you should check the reply code to verify success.
Integer replyCode = ftpClient.getReplyCode();
if ( !FTPReply.isPositiveCompletion(replyCode) ) {
message = "Reply Code - " + replyCode.toString() + " is negative.";
try {
ftpClient.disconnect();
} catch(Exception e) {
message = "Could not disconnect cleanly from server.";
LOGGER.error(message);
}
} else {
message = "Reply Code - " + replyCode.toString() + " is positive.";
}
Boolean logonOk = false;
try {
logonOk = ftpClient.login(fo.getServerInfo().getUserName(),
fo.getServerInfo().getUserPassword());
} catch(IOException e) {
message = "IOException during logon attempt.";
LOGGER.error(message);
}
if ( !logonOk ) {
result = false;
message = "Logon UNsuccessful.";
} else {
message = "Logon successful.";
LOGGER.error(message);
executionMessageLog.add(message);
}
if ( !result ) return result;
// attempt to log onto the target server
return result;
}
Following method is trying to get the list of files. I could see the file name using listNames and also listFiles shows list of files but name, modified date are empty and only has value in rawlisting in the format "04-01-20 11:31AM 8975 test.TXT". So how to get the name and modified date from the raw listing and why I could not get FTPFile name using getName
private FTPFile[] getListofFiles(){
String message = null;
FTPFile[] files = null;
try {
String[] filenames = ftpClient.listNames(fileListInfo.getFilePath());
files = ftpClient.listFiles(); /*Has only rawlisting and others are null*/
}
catch(IOException e) {
message = "IOException during getListofFiles attempt:";
LOGGER.error(message);
executionMessageLog.add(message);
message = e.getMessage();
LOGGER.error(message);
executionMessageLog.add(message);
}
return files;
}
04-01-20 11:31AM 8975 test.TXT
That's quite unusual format. So it's possible that Apache Commons Net library cannot parse it with the default configuration.
You might need to explicitly specify one of the available parsers. The available parsers are in src\main\java\org\apache\commons\net\ftp\parser. Or if there's no parser specifically compatible with your server, you might need to build your own (you can base it on ConfigurableFTPFileEntryParserImpl).
Though actually, for an ad-hoc solution, easier would be that you just parse the "rawlisting" you already have.

How to get all addresses Ip and mac of connected devices to local network using java

I'm creating a java project that shows hostname , ip and mac address of connected devices using java . I use InetAddress but it only shows me the Ip's and hostname of connected computers without MAC and also can't see connected mobiles like Android devices.
I tried almost every solution on StackOverFlow but none of theme seems to work
public class HostDiscovery
{
private String address;
private int discoveryTimeout;
HostDiscovery( String address, int discoveryTimeout)
{
this.address = address;
this.discoveryTimeout = discoveryTimeout;
}
public Future<HostDiscoveryResult> multithreadedHostDicovery(final ExecutorService exService){
return exService.submit(() -> {
try
{
String HostName = null;
String MacAddress = null;
boolean result = InetAddress.getByName(address).isReachable(discoveryTimeout);
InetAddress ip = InetAddress.getByName(address);
if (result)
{
HostName = InetAddress.getByName(address).getHostName();
if(HostName.endsWith(".mshome.net")){
HostName = HostName.replaceAll(".mshome.net", "");
}
MacAddress = getMacAddress(ip);
}
return new HostDiscoveryResult(address, result, HostName, MacAddress);
} catch (SocketException ex)
{
return new HostDiscoveryResult(address, false, null, null);
}
});
}
private static String getMacAddress(InetAddress ip) throws UnknownHostException {
String address = null;
try {
NetworkInterface network = NetworkInterface.getByInetAddress(ip);
byte[] mac = network.getHardwareAddress();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < mac.length; i++) {
sb.append(String.format("%02X%s", mac[i], (i < mac.length - 1) ? "-" : ""));
}
address = sb.toString();
} catch (SocketException ex) {
ex.printStackTrace();
}
return address;
}
}

C# DNS CLASS equivalent in JAVA - GET IPADDRESS in android [duplicate]

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

Why is Java getting the cached version of the host name?

Please refer to this question:
https://askubuntu.com/questions/758432/is-there-another-place-to-host-machine-name?noredirect=1#comment1132454_758432
As you can see, I'm using this method to get the machine name:
private InetAddress getFirstNonLoopbackAddress(boolean preferIpv4, boolean preferIPv6) throws SocketException {
Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces();
while (en.hasMoreElements()) {
NetworkInterface i = en.nextElement();
for (Enumeration<InetAddress> en2 = i.getInetAddresses(); en2.hasMoreElements();) {
InetAddress addr = en2.nextElement();
if (!addr.isLoopbackAddress()) {
if (addr instanceof Inet4Address) {
if (preferIPv6) {
continue;
}
return addr;
}
if (addr instanceof Inet6Address) {
if (preferIpv4) {
continue;
}
return addr;
}
}
}
}
return null;
}
The caller:
InetAddress ip = getFirstNonLoopbackAddress(true, false);
this.machineName = ip.getCanonicalHostName();
But the result is I'm getting the old machine name, before I change it in Ubuntu.
How can I get the real machine/host name as in /etc/hostname file?
The dns always do cache of names. You should do a flush dns in the OS that you are using; On Ubuntu I found this about how to flush the dns:
https://askubuntu.com/questions/414826/how-to-flush-dns-in-ubuntu-12-04
Or try this approach:
Flush DNS using Java

Extract host name/domain name from URL string

I have a URL like http://hostname:port_no/control/login.jsp.
I have the above url stored in some String.Now, I need to extract hostname from the String.
I am doing like this in my Java code
String domain = url.substring(url.indexOf('/') + 2, url.lastIndexOf(':'));
I want to know if there is any better way to do the same.
You can use the java.net.URI-class to extract the hostname from the string.
Here below is a method from which you can extract your hostname from a string.
public String getHostName(String url) {
URI uri = new URI(url);
String hostname = uri.getHost();
// to provide faultproof result, check if not null then return only hostname, without www.
if (hostname != null) {
return hostname.startsWith("www.") ? hostname.substring(4) : hostname;
}
return hostname;
}
This above gives you the hostname, and is faultproof if your hostname does start with either hostname.com/... or www.hostname.com/..., which will return with 'hostname'.
If the given url is invalid (undefined hostname), it returns with null.
java.net.URL aURL;
try {
aURL = new java.net.URL("http://example.com:80/docs/");
System.out.println("host = " + aURL.getHost()); //example.com
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
java.net.URL u = new URL("http://hostname:port_no/control/login.jsp");
System.err.println(u.getHost());
If you want string work, then try the following code sample,
String URL= "http://hostname:port_no/control/login.jsp";
String s_URL[] = ULR.split("//");
String s1 = s_URL[1];
String s2[] = s1.split(":");
String hostname = s2[0];
In Java:
String hostname = url.split("://")[1].split(":")[0];
String portnumber = url.split("://")[1].split(":")[1].split("/")[0];
Hope this helps.
#KarelG's answer is the best answer, though I had specific issues with certain non-standard domains. The example issue is self contained below.
For certain "real world" input values, I had to add a check to the URI scheme to avoid mis-parsing of some addresses. This is the changed code.
import java.net.URI;
import java.net.*;
public class Domain {
public static String getDomainName(String url) {
try {
URI uri = new URI(url);
String domain = uri.getHost();
System.out.println("domain: " + domain);
if (uri.getScheme() != null) {
return domain.startsWith("www.") ? domain.substring(4) : domain;
} else {
return uri.getSchemeSpecificPart();
}
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
Below is the test case and value that was failing.
Domain.java
javac Domain.java
java Domain
import java.net.URI;
import java.net.*;
import java.io.*;
public class Domain {
public static String longname = "https://www.3dprintingmedia.network/longform/page.html";
public static String name = "www.3dprintingmedia.network";
public static void getDomain(String url) {
try {
URI uri = new URI(url);
String domain = uri.getHost();
System.out.println("protocol: " + uri.getScheme());
System.out.println("path: " + uri.getPath());
System.out.println("name: " + name);
System.out.println("domain: " + domain);
System.out.println(domain.startsWith("www.") ? domain.substring(4) : domain);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
System.out.println("Parsing domain: " + name);
getDomain(longname);
getDomain(name);
System.exit(0);
}
}
A solution using Regular expression and group:
String pattern = "(\\w*://)([\\w-_.]+)([:\\w\\W]*)";
Pattern r = Pattern.compile(pattern);
Matcher m = r.matcher(a);
if (m.find())
{
System.out.println(m.group(0));
System.out.println(m.group(1));
System.out.println(m.group(2));
System.out.println(m.group(3));
}
group(2) is the hostname.

Categories

Resources