I have a need to create a http or https URL object from an IPv4 address (String or InetAddress objects - either one is ok) in Java. I have been at this for 10 hours now.
Attempts that hit a wall described below:
Attempt #1: I tried to make the URL by assembling a string, and then feeding it to a URL constructor.
Textbook states that a URL can be "protocol://host", with host being either a host name or IP address. but creating a URL like this: URL a = new URL("http://151.101.65.69"); and opening a stream to this URL (a) gives a HTTP error 500 (Internal Server Error - An unexpected condition occurred that the server does not know how to handle).
What get me fuming is that URL a = new URL("http://stackoverflow.com"); works.
At this point I am stuck. I have no Idea what to change, or how to move forward.
Attempt #2: I tried to do a reverse lookup on the IP address using "getHostName()" method in the InetAddress class.
this should return the host name by doing a reverse DNS lookup. Yet, I keep trying it for 151.101.65.69 (stackoverflow web server IP address), and the look up fails. By fails I mean the IP address is returned as string rather than the host name as a string. I read the Oracle docs http://docs.oracle.com/javase/1.5.0/docs/api/java/net/InetAddress.html#getHostName(), but I don't understand how to overcome the "security manager" the document mentions (or if it is indeed the reason the reverse lookup fails).
I also tried "getCannonicalHostName()", but that didn't fly either.
I am trying to figure out how to open a website using the IP address. It looks like my browser is running into the same issue as my code. I read up on How to access site through IP address when website is on a shared host? but I do not have any user names, as I want to be able to open any website that a user has an IP address for. Adding a port (such as 80) does not seem to work; neither does leaving the user name blank or using a generic 'user' or 'guest'.
I need is to create a URL object from an IPv4 String or InetAddress object, and I am stuck. I understand that a knowledgeable programmer such as you, may say that making URLs from IP addresses is not what IP addresses are for, or point out that I am not including a file portion of the URL, but that is not the problem at this moment. Could you please help me with my core challenge?
The answer provided by D.B. is good. I had very similar code; but you will find that this code will not work every time. There are IPv4 addresses you pass to the code offered D.B.'s answer which will not be able to open a URL stream (for example the IP address for stackoverflow). I thought the problem was my coding, and that is what I was hoping to get help with on stackoverflow. But I now realize the problem was my lack of understanding when asking this question. What I now understand, is that having an IPv4 address is not sufficient to open every website on the web. Anytime a server hosts multiple websites, the IP address can be used to connect to the server, but not to simultaneously identify the website we want to open/access. This gentleman explains this quite well: http://ask-leo.com/why_doesnt_accessing_a_site_by_its_ip_address_work.html
#D.B. thanks for taking the time to help. Much appreciated!
The following code works for me.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.UnknownHostException;
public class InetAddressMain {
public static void main(String[] args) {
try {
InetAddress addr = InetAddress.getByName("172.217.4.110");
URL url = new URL("http://"+addr.getHostAddress());
InputStream is = url.openStream();
InputStreamReader isReader = new InputStreamReader(is);
BufferedReader reader = new BufferedReader(isReader);
String line;
while((line = reader.readLine()) != null){
System.out.println(line);
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Output:
<!doctype html><html itemscope="" itemtype="http://schema.org/WebPage" lang="en"><head><meta content="Search the world's information, including webpages, images, videos and more. Google has many special features to help you find exactly what you're looking for." ... [output shortened for readability]
Related
In some code i use similar code to Oracle's tutorial: Reading directly from a URL. Oracle's code also here below:
import java.net.*;
import java.io.*;
public class URLReader {
public static void main(String[] args) throws Exception {
URL oracle = new URL("http://www.oracle.com/");
BufferedReader in = new BufferedReader(
new InputStreamReader(oracle.openStream()));
String inputLine;
while ((inputLine = in.readLine()) != null)
System.out.println(inputLine);
in.close();
}
}
This code worked before but it doesnt anymore. Even if i try the exact same code, inputLine never has any value. I dont know if it has something to do with java versions or something elso but i would like to know why this happens, and what is a good alternative.
If you replace http://www.oracle.com/ by http://www.google.com/ it works.
It's because a GET http://www.oracle.com/ gives
HTTP/1.1 301 Moved Permanently
If you run
curl www.oracle.com
You obtain the same effect. You have to follow the redirect with
curl -L www.oracle.com
to obtain the html content. In Java, you also have to follow the redirect, such as in this article :
https://www.mkyong.com/java/java-httpurlconnection-follow-redirect-example/
Oracle -
When you run the program, you should see, scrolling by in your command
window, the HTML commands and textual content from the HTML file
located at http://www.oracle.com/. Alternatively, the program might
hang or you might see an exception stack trace. If either of the
latter two events occurs, you may have to set the proxy host so that
the program can find the Oracle server.
You can set the proxy host through the command line. Depending on
your network configuration, you might also need to set the proxy
port. If necessary, ask your system administrator for the name of the
proxy host on your network.
UNIX
java -Dhttp.proxyHost=proxyhost
[-Dhttp.proxyPort=portNumber] URLReader
DOS shell (Windows 95/NT)
java -Dhttp.proxyHost=proxyhost
[-Dhttp.proxyPort=portNumber] URLReader
Also, I have actually ran it on my IDE but it only works with HTTPS
As loris securo commented i needed to use https instead of http. And that fixed my problems.
I found code to fetch host name from IP address. The code is some what like shown below:
import java.net.InetAddress;
import java.net.UnknownHostException;
public class GetHostName{
public static void main(String a[]){
try{
InetAddress host = InetAddress.getByName("74.125.68.94");
System.out.println(host.getHostName());
}
catch(UnknownHostException ex){
ex.printStackTrace();
}
}
}
It shows output like:
sc-in-f94.1e100.net
But when i fired this IP address (74.125.68.94) through the browser it opens up Google website.
So my question is how can i fecth URL like http://www.google.com from an IP address rather than displaying sc-in-f94.1e100.net using java?
You can't do that.
Usually, several domains can be reach on same IP. You can just identify the hostname like you already do. This is the name of the machine, equivalent to the IP, which serves the domain.
Moreover, an IP is just an address of a machine which also can serve any domain because it can be a web server or not.
You are actually doing everything right. The thing is that today many host names can live on the same server. This way you can easily convert the host name to the IP address of the server but when you attempt to do the reverse, you only get the name of the server which is in this case sc-in-f94.1e100.net.
Here is an excerpt from hcidata:
In the early years of the Internet, each sub-domain would have a unique IP address so it was common for a host machine to have only one sub domain name. Nowadays, the common practice is to have many sub-domains with the same IP address. It is also common for the domain name to be converted to the IP address of the host machine that runs the www sub domain.
I hope this will clear things up for you.
This question already has answers here:
Getting the IP address of the current machine using Java
(19 answers)
Closed 9 years ago.
What is the best way to get IP address in Java? I was trying getLocalHost(), but it returns my computer IP addrees. I want something like this.
Also I was trying to get IP by HTML from services like that, but I think it's not good idea.
The following uses Amazon web services and works for me.
import java.net.*;
import java.io.*;
public class IPTest{
public static void main(String args[]) throws Exception{
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("My IP address:"+ip);
}
}
You want to get your internet (someone will call public, I don't totally agree on that term) ip address. Basically you have two options, or call an external service (it does not need to be a site like that, it can be a STUN, or anything made for that), or you can get it from your modem/router/NAT.
You could use UPnP if enabled in the device, this is a good approach.
Other option is instead of trying to parse or get the results from an external service,
you get it from your device web page, some devices even not need admin rights to get that information, so you only need to parse the page for the information.
Most of the answers just say you to use an external service, like you said its not a good idea. In my opniation its not the best one, because you be dependent on an external service provider. If it changes anything you need to change too, as if they get the service broken.
So, if you can implement in your own LAN its better, just not easier.
I set up a static IP and did port forwarding on my notebook, and now I have a static IP address, but it's relatively static, every time I re-start the machine, I get another address, and since I have a "static" IP I can now do Paypal IPN messaging. But how can I get this static IP from my Java program ? One way I can think of is to visit : http://portforward.com/ and on that page it tells me what my external IP is, so I can extract it with Java code, is there any other way that I can do in my Java code to get this info ?
The best solution is probably dynamic DNS. Essentially, you run a program on your computer (or router) that notifies a DNS server when your IP changes. Then, you can just tell PayPal the domain name.
There is a public service you can call with your script to retrieve your external IP address. Bear in mind they have changed the link location once. If you control your own server, you should probably write your own PHP script to simply return the address of the caller to the script.
http://www.whatismyip.com/faq/automation.asp - follow the developers link they provide
import java.net.*;
import java.io.*;
URL myExternalIP = new URL("PUT THE LINK HERE");
BufferedReader in = new BufferedReader(new InputStreamReader(
myExternalIP.openStream()));
String ip = in.readLine(); //you get the IP as a String
System.out.println(ip);
Your own server script is a simple one-liner. Create a file called whatismyip.php and here's the content.
<? echo $_SERVER['REMOTE_ADDR']?>
I see three ways of doing this:
As you discovered, querying an external server what IP you're apparently connecting from. This is simple but you require such a service to be available and, usually, that no transparent proxy messes with your results.
IGD, a sub-protocol of UPnP can give you the result very easily if your port forwarding devices supports it (many do). Google "IGD JAVA" for libraries and samples.
Register for a dynamic DNS service and then lookup your own DNS name.
You can use the NetworkInterface class:
Enumeration<NetworkInterface> ifcs = NetworkInterface.getNetworkInterfaces();
while(ifcs.hasMoreElements()){
NetworkInterface ifc = ifcs.nextElement();
System.out.println("Adresses of: "+ifc.getDisplayName());
Enumeration<InetAddress> adresses = ifc.getInetAddresses();
while(adresses.hasMoreElements()){
System.out.println(adresses.nextElement().getHostAddress());
}
}
This snippet will show you all of the interfaces and the IPs bound to them. You will need to look through the list to find the appropriate interface (see also NetworkInterface.getByName(String name)) And then look at the addresses for that interface. Once you have found the appropriate InetAdress you can use that to get the string or byte representation.
I've been asked to activate a certain piece of code if i was in my college. So I need to find the iP of where i am to match to my colleges iP. Was wonderng how to do this in java? I have already tried a loop back interface.
By using NetworkInterface.getNetworkInterfaces() and calling getInetAddresses() on each interface, you can see all IP addresses assigned to your computer. To check if you have an IP in your university's range, you could do something like this:
boolean onCampusNetwork() {
for(Enumeration<NetworkInterface> ifaces = NetworkInterface.getNetworkInterfaces(); ifaces.hasMoreElements();) {
NetworkInterface iface = ifaces.nextElement();
for(Enumeration<InetAddress> addresses = iface.getInetAddresses(); addresses.hasMoreElements;) {
InetAddress address = addresses.nextElement();
// return true if address is in the university's range; something like:
if(address.toString().startsWith("10.0")) {
return true;
}
}
}
// None of the IP addresses were in the university's range.
return false;
}
I haven't run this code, but it should do what you need.
Isn't there supposed to be some kind of protocol for automatic proxy discovery and configuration? Does your college have this already setup? Then it would be better if your code discovered the correct settings and had an option to override the settings.
There are all kinds of websites out there that will give you your public ip (or the public IP of your gateway, which I assume is what you want). You could tell the program to make an HTTP connection to one of those sites and get the page with the info on it. Since these sites have a very predictable format, the result would be very easy to parse with a regex or two. This only works if you have an internet connection though.
Alternatively, you could have the program try to connect to one of your college's intranet servers. If it can make the connection to a site that is not accessible to the outside world, it's on the LAN.