Checking internet connectivity of a system using Java - java

I wrote a method which will help us finding whether the system using the proxy to connect with internet which is as follows,
try {
System.out.println("Checking internet connection availability.....");
URL u = new URL("http://www.google.com/");
HttpURLConnection uc = (HttpURLConnection) u.openConnection();
uc.setReadTimeout(1);//I have tried this without timeout and with it too. But it didnt work
System.out.println(uc.getResponseCode());
} catch (Exception ex) {
System.out.println("Unable to connect to internet without proxy.....");
System.out.println("Checking for any proxy settings from the PC");
System.setProperty("java.net.useSystemProxies", "true");
try {
System.setProperty("java.net.useSystemProxies", "true");
URL u = new URL("http://www.google.com/");
HttpURLConnection uc = (HttpURLConnection) u.openConnection();
System.out.println(uc.getResponseCode());
System.out.println("Internet connection available");
} catch (Exception e) {
System.out.println("Internet connection not available :(");
}
}
Initially, I am trying to open the URL connection without proxy (assuming the system don't have proxy to connect with internet).I have set the timeout to 1 ms. Trying to get the response code from the site.
If any error occurs means (like timeout), then in the catch block i am trying to connect to internet with system's proxy, by means of setting the useSystemProxies to true.
But even after that also, I am not able to get the response from the site.
I am using a system with proxy settings.
I have tried the following too in the catch block
Proxy next = ProxySelector.getDefault().select(new URI("http://www.google.com/")).iterator().next();
if (next.address() != null) {
System.out.println("Detecting Proxy configurations.....");
String proxy = next.address().toString();
String proxyHost = proxy.substring(0, proxy.indexOf(":"));
String proxyPort = proxy.substring(proxy.indexOf(":") + 1);
System.out.println("Proxy Configuration : " + proxyHost + " # " + proxyPort);
}
The above block of code also is not working. Can anyone help me out with this?

InetAddress.isReachable
Test whether that address is reachable. Best effort is made by the
implementation to try to reach the host, but firewalls and server
configuration may block requests resulting in a unreachable status
while some specific ports may be accessible. 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. The timeout value, in milliseconds, indicates
the maximum amount of time the try should take. If the operation times
out before getting an answer, the host is deemed unreachable. A
negative value will result in an IllegalArgumentException being
thrown.

In your first code snippet in the catch block try setting the following codes.
System.setProperty("http.proxyHost", "Proxy host");
System.setProperty("http.proxyPort", "Proxy Port");
Seems like your proxy is registered as system proxy and not visible to the JVM.

Related

InetAddress.getAllByName() throws UnknownHostException

As part of an ongoing saga to get my app approved by the Apple review team, I have come up against another road block.
As the title suggests, when calling InetAddress.getAllByName("https://artatlas.io") an UnknownHostException is thrown. This only happens during their testing process. When I test my app on my local NAT64 network (as suggested by Apple); the error never occurs, and the app works as intended.
The code I am running:
System.setProperty("java.net.preferIPv6Addresses", "true");
System.setProperty("networkaddress.cache.negative.ttl", "0");
InetAddress[] addrs;
try {
addrs = InetAddress.getAllByName("https://artatlas.io");
String addresses = "";
for(InetAddress addr: addrs){
addresses += addr + "\n";
}
System.out.println("Addresses: " + addresses + "\n");
} catch (IOException e1) {
e1.printStackTrace();
}
What I've discovered is, anything I append with "https://" seems to return the same, single IP address:
Addresses: https://artatlas.io/122.150.5.20
Addresses: https://google.com/122.150.5.20
Addresses: https://www.google.com/122.150.5.20
I could just get rid of the https, but then I'm concerned my later use of a HttpsURLConnection will fail (my connection MUST be https)
testUrl = new URL("https://artatlas.io");
testConn = (HttpsURLConnection) testUrl.openConnection();
I know that a HttpsURLConnection uses an InetAddress instance to form its connection, so the question is what process does it use to parse the URL string, does it remove the protocol? What's the correct approach here?
The hostname shouldn't include a protocol. The host is the same, no matter what protocol you intend to use with it. Whether the later HTTPS connection fails or not, InetAddress.getAllByName() is unrelated to it (it doesn't and can't guarantee success or failure).
You're dealing with DNS only at this point, so it's just foo.com or 123.45.67.89 or an IPv6 address.

Android dealing with IoT devices with NO Internet connection

I'm trying to build a project where I must pilot an IoT device from smartphone via Wifi.
This device has the SPWF01 Wifi Module integrated, and is configured as an access point (that has no Internet access) with security type WEP. On this access point configuration we also have a TCP Socket Server that intercepts smartphone communications.
On the smartphone side, we have the part which scans and connects to our device's access point(which works, although i get the esclamation point on the wifi icon since it has no Internet access). After we've connected, we start the Client Socket which connects to the server on our IoT device(the ip address of the server socket is actually the gateway of the access point). And here is where the trouble starts, because the client socket won't start. Here is the code:
public void SocketInit(String ip, int port) throws IOException {
InetAddress addr = InetAddress.getByName(ip);
SocketAddress sockaddr = new InetSocketAddress(addr, port);
nsocket = new Socket();
nsocket.setReuseAddress(true);
nsocket.setTcpNoDelay(false);
nsocket.setReceiveBufferSize(700); //Must be less than 730byte witch is the module buffer
nsocket.setSendBufferSize(700);
nsocket.connect(sockaddr, 5000); //5 second connection timeout
}
And here is the exception i get:
java.net.SocketException: socket failed: ENONET (Machine is not on the network)
And I get that error even before reaching nsocket.connect(), precisely on setReuseAddress.
Since the exception I get is ENONET, I thought that it must be because the access point has no internet access so I used the solution proposed here for testing purpose:
adb shell settings put global captive_portal_detection_enabled 0
This is a solution that can't be done programmatically without having root access, but I wanted to test if that was the problem. But although the exclamation mark on the wifi icon had disappeared, the client socket still gave me the same exception error.
Does anybody have a solution for this behaviour? Thank you in advance!
Sometimes the client socket manages to open, with a success rate of 1 out of 20 times. But when it does, i usually get another exception after a couple of messages sent:
java.net.SocketException: recvfrom failed: ECONNRESET (Connection reset by peer)
Here is the code I used to connect to the access point from the smartphone:
WifiConfiguration wc=new WifiConfiguration();
wc.SSID= host;
wc.status = WifiConfiguration.Status.ENABLED;
wc.priority = 40;
wc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
wc.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
wc.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
wc.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
wc.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED);
wc.allowedGroupCiphers.clear();
wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
wc.wepKeys[0] = password;
wc.wepTxKeyIndex = 0;
int netId = mainWifi.addNetwork(wc);
try {
//mainWifi.setWifiEnabled(true);
mainWifi.disconnect();
mainWifi.enableNetwork(netId, true);
mainWifi.reconnect();
startConnectionCheck = true;
System.out.println("enabled network");
} catch (Exception e) {
e.printStackTrace();
System.out.println(e.getMessage());
}
The access point's security type is WEP. That is because the Wifi module can't implement WPA.
Tests done on Marshmallow.
I am not 100% certain if this issue is the same.
I had to do a project a whileback and used Java sockets.
When doing intial testing, I used the local loopback and used ports on the same computer and multiple threads. Eventually it worked well enough to test between two computers. I found it didn't work between two computers. After turning off all my firewalls and protections etc on the network and getting desperate enough to use direct connection ethernet cables, I figured out the issue.
Sockets cares which gateway you use. The solution was for me to use the gateway rather than the loopback... It is obvious looking back now...
Anyway, it is likely that your mobile gateway, wifi gateway, and local loopback are all different.
Here is an ugly code blurbe that I hope gives direction with very little inspiration...
Socket socket = null;
try {
socket = new Socket(ip, port, InetAddress.getLoopbackAddress(), localServerPort);
}
catch (Exception e) {
}
if (socket == null) {
try {
socket = new Socket(ip, port, InetAddress.getLocalHost(), localServerPort);
}
catch (Exception e) {
}
}
if(socket == null) {
throw new Exception("Neither the loop back nor the host could find this sucker.");
}

How to check wheather specified port is available for communication?

I am using Java Secure Channel to connect with hosts in a network.
I am using following code:
int port = 22;JSch jsch = new JSch();
try {
session=jsch.getSession(username,hostname,port);
}
catch (JSch Exception e1){
e1.printStackTrace();
}
session.setPassword("mypassword");
try {
session.connect();
}catch (JSchException e1){
System.out.println("Did not connect");
return;
}
By using this code I am able to connect to host.
But if host is unavailable/offline then I have to wait for JSchException.
1) I want to first check whether host is available for communication or not and if available then only try to connect.
2) Also I want to set timeout for connection,if connection doesn't established within that time interval must give exception.
How to check if host is available? and set timeout for connection?
Testing before connecting makes no big sense, as port can become unavailable right after test. Try to use session.setTimeout() to set timeout in millis.
How to check whether specified port is available for communication?
How to check whether specified X is available for Y:
Try to use it for Y. It's an infallible test. Any other technique has timing-window problems.

Establishing the URLConnection to another web application does not work with URLConnection .connect()?

Here is the code i am using the open the URLConnection to another webapllication
try {
URL url = new URL("https://mySecondWebApp/Cart");
HttpsURLConnection conn1 = (HttpsURLConnection) url.openConnection();//line1
conn1 .connect();//line 2 does not establishes the connection
conn1.getInputStream();// line 3 works which means that i get control to my app2 in debugger.But this also passes the control to IOException stating error java.io.FileNotFoundException: https://mySecondWebApp/Cart
}
catch (MalformedURLException e) {
log.error("MalformedURLException" + e);
}
catch (IOException e) {
log.info("getting IO error");
}
I am not getting why line 2 does not establish the connection with app2 while line 3 does?
second thing is why i get the file notfound exception after line 3 even though it sucessfully connect to app2 which i want to avoid.My intention
is just to establish the connection to app2 so that i get control inside my java code of app2
The method name is probably the source of your confusion. openConnection() method does not establish a connection, it just prepares the connection object. here is the link to the API for the method:
URL.openConnection()
the following is written there: "It should be noted that a URLConnection instance does not establish the actual network connection on creation. This will happen only when calling URLConnection.connect()."
EDIT:
I have confused the lines (Thanks Ankit) and therefore the above is not relevant.
Connecet does establish the connection but actually it is not needed here as the method getInputStream will establish the connection if it was not established already.
The connect() method is not expected to do this task, from javadoc:
public abstract void connect()
throws IOException
Opens a communications link to the resource referenced by this URL, if such a connection has not already been established.
If the connect method is called when the connection has already been opened (indicated by the connected field having the value true), the call is ignored.
URLConnection objects go through two phases: first they are created, then they are connected. After being created, and before being connected, various options can be specified (e.g., doInput and UseCaches). After connecting, it is an error to try to set them. Operations that depend on being connected, like getContentLength, will implicitly perform the connection, if necessary.

How do I have to configure a RMI environment so that I'm able to use it in a "real" network?

Because I didn't want to implement a communication protocol for my client-server based application, I implemented a RMI client and a RMI server on both sides for the information exchange between the two components.
If I try to use my application by starting the two components on the same machine, everything is working fine. But if I split the components to two different computers (Kubuntu 9.04 within as a virtual machine within an Windows 7 RC environment with disabled firewall and a native Ubuntu 9.04 environment), it seems like the RMI client is not able to execute the methods which are defined on the server side. (Every functions call leads to a RMI exception.)
Currently I only set the system property "java.rmi.server.hostname" on both sides to the network interface which should be used for the data exchange and registered the default port for the communication with rmi daemon (?) rmid.
Does somebody has an idea what might be going wrong? Do I have to set some other parameters like "java.rmi.server.codebase" (http://java.sun.com/j2se/1.4.2/docs/guide/rmi/javarmiproperties.html) to be able to use the RMI functionality within my application?
Edit: Okay, here is some additional information for you:
In the initialization phase my client tries to establish a connection to the RMI server of server component, which was initialized using the following two methods:
private void initialize()
{
// set ip address of rmi server
System.setProperty("java.rmi.server.hostname", ipAddress);
// try to register rmi server
try
{
LocateRegistry.createRegistry(Registry.REGISTRY_PORT);
}
catch (Exception e)
{
// ignore
}
}
public void start()
{
System.out.print("starting master control RMI server ...");
try
{
Naming.rebind("MasterControl", this);
}
catch (Exception e)
{
System.out.println("error: could not initialize master control RMI server");
System.exit(1);
}
// set running flag
isRunning = true;
System.out.println(" done");
}
"ipAddress" is here the ip address of the network interface of the server component.
The method which is used by the client component to establish the connection looks like this:
public void connect()
{
// build connection url
String url = "rmi://" + masterControlIpAddress + "/MasterControl";
System.out.println(url);
System.out.print("connecting to master control ...");
// try to connect to master control server
while (connection == null)
{
try
{
connection = (MasterControlInterface) Naming.lookup(url);
id = connection.register(localIpAddress);
}
catch (Exception e)
{
// ignore
}
if (connection == null)
{
try
{
Thread.sleep(100);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
System.out.println(" done");
}
As you can see my client calls a function to register the connection at the server:
#Override
public int register(String ipAddress) throws RemoteException
{
// add connection to registrationHandler
masterControl.registrationHandler.addConnection(ipAddress);
// log
int connectionCount = masterControl.registrationHandler.getConnectionCount();
System.out.println("slave control (" + ipAddress + ") instance has been registered at the master control server under the following id: " + connectionCount);
return connectionCount;
}
If I run my program using a real network connection, the text "slave control ..." is not displayed on the server side. Therefore I'm not sure, if the function is really called by the client component.
After the client component is intialized it tries to notify the server component by calling the following method using it's RMI connection to the server:
public void sendInitializationDone()
{
try
{
connection.initializationDone();
}
catch (RemoteException e)
{
System.out.println("error: could not send 'initializationDone' message to master control");
System.out.println(e);
System.exit(1);
}
}
to set a flag on the server side.
The error occures inside this function on the client side:
java.rmi.ConnectException: Connection refused to host 127.0.1.1; nested exception is: java.net.ConnectException: Connection refused.
I have no idea why the host is here 127.0.1.1 ...
#nos
Of course, I disabled the windows firewall and the protection mechanismn of Kaspersky Internet Security. I don't think that there is a running firewall in my Kubuntu. In generell it is possible to establish a connection, because I already used scp to copy my program to the other machine.
Edit2:
Mhhh, after setting the entry in /etc/hosts which refers to the machine to the ip address of the machine it seems to work, but don't really understand why it does ...
BR,
Markus
You need to add an entry to the hosts file of the machines containing an entry of the form
machinename privateip
e.g.
virtualmachine 192.168.1.16
This will prevent RMI from sending the localhost host name as a 'call me back' address.
To test this approach, run the following code before and after performing the change.
System.out.println(java.net.InetAddress.getLocalHost());
It should output a local address before the changes and a non-local address after the changes.
Using different versions of the JDK on each server could cause this problem.
Use the
java -version
command to make sure that you are using the same version of the jre.

Categories

Resources