How to write a java program which will tell me whether I have internet access or not. I donot want to ping or create connection with some external url because if that server will be down then my program will not work. I want reliable way to detect which will tell me 100% guarantee that whether I have internet connection or not irrespective of my Operating System. I want the program for the computers who are directly connected to internet.
I have tried with the below program
URL url = new URL("http://www.xyz.com/");
URLConnection conn = url.openConnection();
conn.connect();
I want something more appropriate than this program
Thanks
Sunil Kumar Sahoo
It depends on what you mean by "internet" connection. Many computers are not connected directly to the internet, so even if you could check whether they have a network connection, it doesn't always mean they can access the internet.
The only 100% reliable way to test whether the computer can access some other server is to actually try.
Effective connectivity to the internet (i.e. where you can actually do stuff) depends on lots of things being correct, on your machine, your local net, your router, your modem, your ISP and so on. There are lots of places where a failure or misconfiguration will partly or completely block network access.
It is impossible to test all of these potential failure points with any certainty ... or even to enumerate them. (For example, you typically have no way of knowing what is happening inside your ISP's networking infrastructure.)
As #codeka says: "the only 100% reliable way to test whether the computer can access some other server is to actually try".
I think if you were to open up a HTTP session with all of:
www.google.com
www.microsoft.com
www.ibm.com
www.ford.com
and at least one of them came back with a valid response, you would have internet connectivity. Don't keep testing once you get a valid response since that would be a waste.
Feel free to expand on that list with some more mega-corporations in case you fear that all four of them may be down at the same time :-)
Of course, even that method can be tricked if someone has taken control of your DNS servers but it's probably about as reliable as you're going to get.
Just put a try/catch block around the code you mentioned. If an exception is thrown/caught then you don't have connectivity.
boolean connectivity;
try {
URL url = new URL("http://www.xyz.com/");
URLConnection conn = url.openConnection();
conn.connect();
connectivity = true;
} catch (Exception e) {
connectivity = false;
}
For better results investigate what kind of exceptions can be thrown and handle each individually.
You can check the connectivity by ask the Internet Protocol from InetAddress class. If you get an exception, or for example you use getLocalHost() -- which is returns the address of the local host -- give you the following output:
localhost/127.0.0.1 instead of fully qualified name like for example jaf-stephen-lenovoG40-80/152.6.44.13 then you're not connected to the Internet.
public static void main(String[] args) {
try {
InetAddress address = InetAddress.getByName("www.facebook.com");
System.out.println(address);
} catch (UnknownHostException e) {
System.err.println("Couldn't find www.facebook.com");
}
}
if you're connected to the Internet, you'll get the following output:
www.facebook.com/31.13.78.35
Enumaration<NetworkInterface> networkInterface = null;
networkInterface = NetworkInterface.getNetworkInterfaces();
for(NetworkInterface interface : Collections.list(networkInterface)){
System.out.println("Internet Available status is :"+ interface.isUp());
}
Related
This question already has answers here:
Java socket API: How to tell if a connection has been closed?
(9 answers)
Closed 5 years ago.
When I'm using e.g. PuTTY and my connection gets lost (or when I do a manual ipconfig /release on Windows), it responds directly and notifies my connection was lost.
I want to create a Java program which monitors my Internet connection (to some reliable server), to log the date/times when my internet fails.
I tried use the Socket.isConnected() method but that will just forever return "true". How can I do this in Java?
Well, the best way to tell if your connection is interrupted is to try to read/write from the socket. If the operation fails, then you have lost your connection sometime.
So, all you need to do is to try reading at some interval, and if the read fails try reconnecting.
The important events for you will be when a read fails - you lost connection, and when a new socket is connected - you regained connection.
That way you can keep track of up time and down time.
Even though TCP/IP is "connection oriented" protocol, normally no data is sent over an idle connection. You can have a socket open for a year without a single bit sent over it by the IP stack. In order to notice that a connection is lost, you have to send some data on the application level.(*) You can try this out by unplugging the phone cable from your ADSL modem. All connections in your PC should stay up, unless the applications have some kind of application level keepalive mechanism.
So the only way to notice lost connection is to open TCP connection to some server and read some data from it. Maybe the most simple way could be to connect to some FTP server and fetch a small file - or directory listing - once in a while. I have never seen a generic server which was really meant to be used for this case, and owners of the FTP server may not like clients doing this.
(*) There is also a mechanism called TCP keepalive but in many OS's you have to activate it for all applications, and it is not really practical to use if you want to notice loss of connection quickly
If the client disconnects properly, a read() will return -1, readLine() returns null, readXXX() for any other X throws EOFException. The only reliable way to detect a lost TCP connection is to write to it. Eventually this will throw an IOException 'connection reset', but it takes at least two writes due to buffering.
Why not use the isReachable() method of the java.net.InetAddress class?
How this works is JVM implementation specific but:
A typical implementation will use ICMP ECHO REQUESTs if the privilege can be obtained, otherwise it will try to establish a TCP connection on port 7 (Echo) of the destination host.
If you want to keep a connection open continually so you can see when that fails you could connect to server running the ECHO protocol yourself rather than having isReachable() do it for you and read and write data and wait for it to fail.
You might want to try looking at the socket timeout interval. With a short timeout (I believe the default is 'infinite timeout') then you might be able to trap an exception or something when the host becomes unreachable.
Okay so I finally got it working with
try
{
Socket s = new Socket("stackoverflow.com",80);
DataOutputStream os = new DataOutputStream(s.getOutputStream());
DataInputStream is = new DataInputStream(s.getInputStream());
while (true)
{
os.writeBytes("GET /index.html HTTP/1.0\n\n");
is.available();
Thread.sleep(1000);
}
}
catch (IOException e)
{
System.out.println("connection probably lost");
e.printStackTrace();
}
Not as clean as I hoped but it's not working if I leave out the os.writeBytes().
You could ping a machine every number of seconds, and this would be pretty accurate. Be careful that you don't DOS it.
Another alternative would be run a small server on a remote machine and keep a connection to it.
Its probably simpler to connect to yahoo/google or somewhere like this.
URL yahoo = new URL("http://www.yahoo.com/");
URLConnection yc = yahoo.openConnection();
int dataLen = yc.getContentLength() ;
Neil
The isConnected()method inside Socket.java class is a little misleading. It does not tell you if the socket is currently connected to a remote host (like if it is unclosed). Instead, it tells you whether the socket has ever been connected to a remote host. If the socket was able to connect to the remote host at all, this method returns true, even after that socket has been closed. To tell if a socket is currently open, you need to check that isConnected() returns true and isClosed() returns false.
For example:
boolean connected = socket.isConnected() && !socket.isClosed();
I want to find the IP address to a server on a local network in short time. I know the port that the application is using on the server.
I've tried this, but its too slow. Even when I know the IP, the responstime is too long (like 4 seconds or so for each IP). Considered this method, it would take minutes to scan the whole subnet from 10.0.0.0 to 10.0.0.255.
String ip = "10.0.0.45";
try {
InetAddress ping = InetAddress.getByName(ip);
Socket s = new Socket(ping, 32400);
System.out.println("Server found on IP: " + ping.getCanonicalHostName());
s.close();
} catch (IOException e) {
System.out.println("Nothing");
}
}
I could use threads, but that would still be slow. Ive seen application finding the IP in milliseconds out there. How do they do this? Java code would be appreciated!
You'll want to do two things - use threads to check many hosts simultaneously, and give the socket connection a lower timeout.
This answer show a very similar example.
I can suggest to look for source code of angry ip scanner. It is fast enough I think.
https://github.com/angryziber/ipscan
I am trying to download a xml text file from a web server using this method:
static void download (String url , String fileName) throws IOException{
FileWriter xmlWriter;
xmlWriter = new FileWriter(fileName);
System.out.println("URL to download is : " + url);
// here Exception is thrown/////////////////////////////////
BufferedReader inputTxtReader = new BufferedReader
(new BufferedReader(new InputStreamReader(addURL.openStream())));
////////////////////////////////////////////////////////
String str ;
String fileInStr = "";
str = inputTxtReader.readLine();
while (!(str == null) ){///&& !(str.equals("</tv>"))
fileInStr += (str + "\r\n");
str = inputTxtReader.readLine();
}
xmlWriter.write(fileInStr);
xmlWriter.flush();
xmlWriter.close();
System.out.println("File Downloaded");
}
Sometimes this exception is thrown (where I specified is code):
java.net.SocketException: Network is unreachable: connect
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333)
at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:195)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:182)
at java.net.Socket.connect(Socket.java:518)
at java.net.Socket.connect(Socket.java:468)
at sun.net.NetworkClient.doConnect(NetworkClient.java:157)
at sun.net.www.http.HttpClient.openServer(HttpClient.java:389)
at sun.net.www.http.HttpClient.openServer(HttpClient.java:516)
at sun.net.www.http.HttpClient.<init>(HttpClient.java:233)
at sun.net.www.http.HttpClient.New(HttpClient.java:306)
at sun.net.www.http.HttpClient.New(HttpClient.java:318)
at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(HttpURLConnection.java:788)
at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:729)
at sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:654)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:977)
at java.net.URL.openStream(URL.java:1009)
at MessagePanel.download(MessagePanel.java:640)
at WelcomThread.run(MainBody2.java:891)
Please guide me
Thank you all.
You are facing a connection breakdown. Does this happen in 3G, WiFi or "plain" connection on a computer?
Anyway, you must assume that the connection may be lost from time to time, when writing your app. For example, with mobiles, this happens frequently in the tube, in basements, etc. With PC apps, this is less frequent but occurs sometimes.
A retry can be a good solution. And a clean error message that explains the network is not available at this moment too.
I faced situation of getting java.net.SocketException not sometimes but every time. I've added -Djava.net.preferIPv4Stack=true to java command line and my program started to work properly.
"Network is unreachable" means just that. You're not connected to a network. It's something outside of your program. Could be a bad OS setting, NIC, router, etc.
I haven't tested with your code so it would be totally different case though, still I'd like to share my experience. (Also this must be too late answer though, I hope this answer still would help somebody in the future)
I recently faced similar experience like you such as some times Network is unreachable, but sometimes not. In short words, what was cause is too small time out. It seems Java throws IOException with stating "Network is unreachable" when the connection fails because of it. It was so misleading (I would expect something like saying "time out") and I spent almost a month to detect it.
Here I found another post about how to set time out.
Alternative to java.net.URL for custom timeout setting
Again, this might not the same case as you got experienced, but somebody for the future.
this just happened to me. None of the answers helped, as the issue was I have recently changed the target host configuration and put incorrect host value there. So it could just be wrong connection details as well.
I faced this error after updating my network adapter configuration (migration to a NIC coupled network by PowerShell commandlet New-NetSwitchTeam). My guess is, that something in the java configuration must be adapted to reflect this change to the java system. But it is unclear where the changes should take place. I am investigating further.
freshman, both here and in Java
i know codes like:
Socket clientSocket=null;
try
{
clientSocket=new Socket(192.168.2.3,1111);
System.out.println("port open");
clientSocket.close();
}
catch(Exception e)
{
System.out.println("port closed");
}
can be used to test whether certain port is open(here is port 1111 on 192.168.2.3), just wandering is there any other way?? not using socket() maybe??
To simplyfy things a bit: yes, establishing a connection is correct way to probe for open port, and if you even find other method, it will be using socket() under the hood.
Complexity of the whole problem comes from the fact that "open port" is a number one suspect in every security book out there. System administrators use a bunch of tricks to fight so called "port scanning". This includes reporting a "false positive" (claiming that port is open while it is not) to any software that behaves like a port scanner (that is: makes a connection and disconnects without sending any data).
So in reality the best way is to establish connection, send request and process response. Every other approach can fail under certain network/host/security configurations, leaving your user puzzled as to why his application doesn't work when it claims there is no problem with connection.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to check if internet connection is present in java?
I want to see if anyone has an easy way of detecting if there is an internet connection when using Java. The current app used the "InternetGetConnectedState" method in the WinInit DLL for windows, but my app needs to be cross-platform for mac operation and this way will not work. I do not know JNI at all either to use DLLs in Java and it became frustrating fast.
Only ways I could think of were tring to open a URL connection to a website and if that fails, return false. My other way is below, but I didn't know if this was generally stable. If I unplug my network cable i do get an UnknownHostException when trying to create the InetAddress. Otherwise if the cable is connected I get a valid InetAddress object. I didnt test the below code on a mac yet.
Thanks for any examples or advice you can provide.
UPDATE: Final code block is at the bottom. I decided to take the advice of an HTTP request (in this case Google). Its simple and sends a request to the site for data to be returned. If I cannot get any content from the connection, there is no internet.
public static boolean isInternetReachable()
{
try {
InetAddress address = InetAddress.getByName("java.sun.com");
if(address == null)
{
return false;
}
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return false;
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return false;
}
return true;
}
Final Code Block:
//checks for connection to the internet through dummy request
public static boolean isInternetReachable()
{
try {
//make a URL to a known source
URL url = new URL("http://www.google.com");
//open a connection to that source
HttpURLConnection urlConnect = (HttpURLConnection)url.openConnection();
//trying to retrieve data from the source. If there
//is no connection, this line will fail
Object objData = urlConnect.getContent();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return false;
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return false;
}
return true;
}
That's a perfectly reasonable approach to solving the problem. The bad thing is that you are really testing DNS rather than testing the whole network, but in practice you can often get by with treating those as equivalent.
The other thing to remember, is that you will need to set a system property to turn off dns caching in the java runtime. Otherwise it may continue to report that the network is up based upon cached data (even though it is down).
Another approach would be to actually open an HTTP request to some network address such as this every so often.
I must add that although the final code block given above is good, it has one flaw - it is possible for it to take a very long time to contact the address specified, but the address is still reachable.
In my instance when testing with one address the method would return true, but take 10 seconds or longer to get a response. In this case the server was reachable, but not for any useful purposes since the connection was so slow. This occurs because the default timeout for HttpURLConnection is 0, or infinite.
For this reason I'd recommend you do the checking off the UI thread, and add urlConnect.setConnectTimeout(1000); before calling urlConnect.getContent();
This way you know the address is reachable, and that it won't take 5 years to download a 10k file.
(You might of course want to change the the timeout time to suit your needs)
Also I'd recommend not checking a generic address (google.com etc) unless your program generally accesses more than a few domains. If you're just accessing one or two then check that domain.
Note that it could return false if the java.sun.com is not responding! In this case you should check another site to be certain.
Haven't tested this, but I suggest looking at java.net.NetworkInterface.getNetworkInterfaces(). This returns an Enumeration of all network interfaces on the machine, or null if there are none.
I'm not sure if it's safe to assume that a non-null response ensures a valid network connection -- depending on your needs, you may or may not need to filter out loopback addresses (which I think you could do with java.net.NetworkInterface.getInetAddresses() on each returned NetworkInterface, and then calling InetAddress.isLoopbackAddress() on each one.)
The only way to be CERTAIN that you can reach a given service, is to do a dummy request to that service. Pings may be blocked by firewalls. Some server may be reachable, others not. If you need to talk to a webservice, have a static page to return for these requests.
Also, remember to ask the user before trying to reach out.
A problem with the first solution is that InetAddress has a cache, so, when you lose the connection for the next few invocation the name is resolved via the java cache.
With the URL connection aproach you have the problem that you use getContent that should fetch html so there you have data consumption. If the invocations are done very often that could be a problem (more so if you dont have an unlimited data plan on the device running the software).
I think the best solution would be to do a TCP connection to the 80 port an close it inmediatly after a successfull connection. That would behave as the final code but would have much less traffic.
The question doesn't really have a meaning. There is no such thing as a 'connection to the Internet'. You have to try to create one. The Windows API referred to only tells you whether your modem is dialled in or not, and I've seen it actually cause dial-ins, which is not exactly the idea. Not that I've had a dial-in for the last 8 years or so.