Check service availability from java - java

How can I check service using java? I found this article, but it is only for checking hostname.
My question is how can I check is service on port x running, ex: myhostname:8080 or myhostname:8099 , I might be running service n or p on those ports but it would be visible trough web if I do it manually, how can I achieve same effect in java?

That snippet sends a ping, which you can't manipulate to achieve what you want. Just open a socket and catch any exceptions.
bool success = true;
try {
(new Socket(host, port)).close();
} catch (UnknownHostException e) {
// unknown host
success = false;
} catch (IOException e) {
// io exception, service probably not running
success = false;
}
If you need to detect which service is running, then you need to read the first bytes sent and compare them to what you know each service should send. This might require a few passes back and forth.

Since your services are web, you might want to add a verification of the response code.
boolean available = false;
HttpURLConnection conn = null;
try {
conn = (HttpURLConnection) new URL("http://yourdomain/").openConnection();
conn.connect();
if(conn.getResponseCode() == 200)
available = true;
}
catch(IOException e) {
}
finally {
if(conn != null)
conn.disconnect();
}

Just attempt to connect to the socket.
InetAddress addr = InetAddress.getByName("myhostname");
Socket socket = new Socket(addr, 8099);
If that doesn't thrown an exception then the host is accepting connections on that port. If it isn't you'll typically get a ConnectException.

Just attempt to use the service and deal with the exceptions as they arise. There's generally no point in testing any resource for availability prior to using it. What if it was available when you tested and not when you used it?

You can use sockets to do this.
new Socket("localhost", 8080).getInputStream()
Surround that with a try catch block and you have a solution.

Related

Java RMI Registry.lookup() - no response

I am experiencing an error which I am at a loss to explain. I feel like I'm so close but I just can't seem to get a connection.
I have setup two RMI server objects on a remote server and I want to connect to and use these. I am able to connect to the RMIRegistry on the server on port 1099 and with the call Registry.list() I get the correct names of the stubs which are setup on the server.
Now for my code...
Server object 1
Registry registry = null;
try {
registry = LocateRegistry.createRegistry(1099);
} catch (RemoteException e){
System.out.println("Registry already exists - connecting...");
try {
registry = LocateRegistry.getRegistry(1099);
String[] objects = registry.list();
for (int n=0; n<objects.length; n++){
System.out.println(objects[n]);
}
} catch (RemoteException ex) {
ex.printStackTrace();
System.out.println("RMI registry connection fail.");
System.exit(1);
}
}
BioBingoLogic bb = null;
bb = new BioBingoLogic();
BioBingoInterface bbStub = null;
try {
bbStub = (BioBingoInterface)
UnicastRemoteObject.exportObject(bb, 9753);
} catch (RemoteException e){
e.printStackTrace();
System.out.println("RemoteServer export fail.");
System.exit(1);
}
try {
registry.rebind("BioBingoServer", bbStub);
} catch (RemoteException e){
e.printStackTrace();
System.out.println("Registry rebind fail.");
System.exit(1);
}
Server object 2
Completely the same as Server object 1 only exported on port 9754 and called "DatabaseServer".
Output
My output from these two objects is in the following picture:
Output from running the two server objects.
Client side
The server objects work as I expect them to. It is the Client which doesn't seem to be able to connect to the individual server objects.
System.out.println("Creating RMI Registry stub.");
Registry remoteRegistry = null;
try {
remoteRegistry = LocateRegistry.getRegistry("biobingo", 1099);
String[] objects = remoteRegistry.list();
System.out.println("\nObjects in stub:");
for (int n = 0; n < objects.length; n++) {
System.out.println(objects[n]
}
System.out.println();
System.out.println("Connecting to BioBingoServer object.");
try {
game = (BioBingoInterface) remoteRegistry.lookup("BioBingoServer");
db = (DatabaseInterface) remoteRegistry.lookup("DatabaseServer");
} catch (Exception e) {
e.printStackTrace();
System.out.println("Stub not found.");
System.exit(1);
}
} catch (RemoteException e) {
e.printStackTrace();
System.out.println("Registry not found.");
System.exit(1);
}
System.out.println("Connected to BioBingoServer.");
System.out.println("Connected to DatabaseServer");
biobingo is the IP of the remote server registered with the alias in my hosts file.
Output
This is where the problem arises....
I get the output in the following picture:
Output from client side application
It should be understood from the picture, that I never get an exception of any kind. It just hangs on the call Registry.lookup() until it, I suppose, gets a timeout from the server and executes the next part of the client code - calls to the server object then throws a RemoteException.
It should be noted that the remote server is behind a NAT, however, the NAT and its firewall is setup to allow all incoming TCP traffic, from all IP's, on all the specified ports; 1099 + 9753 + 9754.
I have also verified that the ports are indeed open with a port scanner.
This is where I am at a loss...
Any suggestions to what is preventing me from connecting to the server objects, when I am entirely able to connect to the RMIRegistry?
Any help is greatly appreciated - thank you!
---------------------------------------------
EDIT
---------------------------------------------
I tried running the server objects and client with the java vm option:
-Dsun.rmi.transport.tcp.logLevel=VERBOSE
The following picture shows the output and includes description of the flow and where the possible error occurs:
output with java vm option.
Client output
No output, just a 3 minute delay on Registry.lookup(). Afterwards the following code is executed and then on function calls to the RMI stub there’s a 3 minute delay followed by a ConnectException saying *connection timed out to 10.230.56.71` (which is the local IP of the server, although I’m connecting to it’s global IP - so it seems that my call does find it’s way to the NAT which the server is behind).
Server output
Nothing, really.

Continuously connecting to a server via a Socket until a connection is established

I have a client that I want to try to continuously connect to a server until a connection is established (i.e. until I start the server).
clientSocket = new Socket();
while (!clientSocket.isConnected()) {
try {
clientSocket.connect(new InetSocketAddress(serverAddress, serverPort));
} catch (IOException e) {
e.printStackTrace();
}
// sleep prevents a billion SocketExceptions from being printed,
// and hopefully stops the server from thinking it's getting DOS'd
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
After the first attempt, I get a ConnectionException; expected, since there is nothing to connect to. After that, however, I start getting SocketException: Socket closed which doesn't make sense to me since clientSocket.isClosed() always returns false, before and after the connect() call.
How should I change my code to get the functionality I need?
You can't reconnect a Socket, even if the connect attempt failed. You have to close it and create a new one.

Checking if Booting Server is Ready for SSH with Java

I'm wanting to use Java to check if a server that's in a state of booting up is reachable yet via SSH (port 22). Currently, I'm just looping using the isReachable method like so ...
reachable = InetAddress.getByName(host).isReachable(timeout);
But this of course doesn't specifically check SSH port 22, so my Java application may jump the gun and try to SSH into the host when it's "reachable" but not necessarily via SSH. Any recommendations for how best to check if a server is ready to be SSH'ed into?
In order to specifically check for port 22, you could use standard Java Sockets, e.g.:
Socket socket = null;
boolean reaching = false;
try {
socket = new Socket("yourserver.com", 22);
reaching = true;
}catch(Exception e){
reaching = false;
}finally{
if(socket != null){
try {
socket.close();
}catch(IOException e){}
}
}
System.out.println(reaching);
In order to avoid unpleasant blocking, you could also set a timeout:
try {
int timeout = 3000; // timeout in ms
socket = new Socket();
socket.connect(new InetSocketAddress("yourserver.com",22), timeout);
reaching = true;
} catch(Exception e) {
reaching = false;
}

socket programming code not running forever

I have a 2 nodes that should always communicate with each other, but they don't seem to talk for more than 1 interaction. After successfully sending and receiving 1 message, they stop.
My code looks like this:
The initiator:
try {
Socket client = new Socket(ip, port);
OutputStream toNode = client.getOutputStream();
DataOutputStream out = new DataOutputStream(toNode);
out.writeUTF("Start:Message");
System.out.println("Sent data");
InputStream fromNode = client.getInputStream();
DataInputStream in = new DataInputStream(fromNode);
if(in.readUTF().equals("Return Message")) {
System.out.println("Received data");
out.writeUTF("Main:Message");
System.out.println("Sent data again");
}
else
System.out.println("Error");
client.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
The responder:
while(true) {
Socket server;
try {
server = s.accept();
DataInputStream in = new DataInputStream(server.getInputStream());
String msg = in.readUTF();
String[] broken_msg = msg.split(":");
if(broken_msg.length > 0)
System.out.println("Looping");
String ret;
if (broken[0].equalsIgnoreCase("Start")) {
ret = "Return Message";
DataOutputStream out = new DataOutputStream(server.getOutputStream());
out.writeUTF(ret);
}
else if (broken[0].equalsIgnoreCase("Main")) {
//Do Useful work
}
} catch (IOException e) {
e.printStackTrace();
}
}
My output looks like this:
Looping
and:
Sent data
Received data
Sent data again
You are looping around the accept() call, accepting new connections, but your actual I/O code only reads one message per connection. You need an inner loop around the readUTF() calls, handling the entire connection until EOFException is thrown. Normally all the I/O for a connection is handled in a separate thread.
In order for programs to do repetitive actions, you would generally use looping of some sort, including for loops, while loops and do-while loops. For something like this where you don't know how many times you'd need to communicate in advance, then you would need to use a while loop, not a for loop.
Having said that, you have no while loops whatsoever inside of your connection code... so without code that would allow continued communication, your program will stop, exactly as you've programmed it to do.
Solution: fix this. Put in while loops where continued communication is needed.

Detecting port availability in Java fails

I try to check if port 80 is available using the following method :
Sockets: Discover port availability using Java
I have a Java application that checks if port 80 is available, if so, it runs a small web server listening on port 80. It works great to detect if another Java application listens on port 80, e.g. if I run my application two times, the second instance will correctly tell me that the port 80 is being used.
The problem is that I have WAMP running and listening on port 80, and that if I run my Java application after I started WAMP, it won't tell me that the port 80 is busy. It seems that it only tells me if another Java application uses the port 80.
That goes beyond my understanding ... any help is greatly appreciated!
Code snippet:
int port = 80;
if(!Connection.isPortAvailable(port)) {
logger.info("Port " + port + " is already in use");
}
// in Connection class
public static boolean isPortAvailable(int port) {
ServerSocket ss = null;
DatagramSocket ds = null;
try {
ss = new ServerSocket(port);
ss.setReuseAddress(true);
ds = new DatagramSocket(port);
ds.setReuseAddress(true);
return true;
} catch (IOException e) {
} finally {
if (ds != null) {
ds.close();
}
if (ss != null) {
try {
ss.close();
} catch (IOException e) {
/* should not be thrown */
}
}
}
return false;
}
The correct answer to all questions of this nature is to try to use it and catch the exception. Not try to see if it's available and then try to use it and still have to handle the exception, which has several obvious problems:
There is a timing window between 'see' and 'try' during which the situation can change (both ways).
You still have to catch failures in the 'use' part anyway.
It is basically just trying to predict the future. This is supposed to be computer science, not fortune-telling.
This applies to most values of 'it', including network ports, files, any resource really.
I was able to reproduce your problem by running WampServer (verified that it was running by visiting localhost:80) and running a minimal java program given your example code.
The code in the try block did not throw an exception when WampServer was running. However, modify the first few lines of the try block like this
ss = new ServerSocket();
ss.bind(new InetSocketAddress("127.0.0.1", port));
and isPortAvailable will properly detect when WampServer is running and when it is not. Using "0.0.0.0" instead of "127.0.0.1" didn't work with WampServer, but did properly detect when IIS was running. You can check both by closing the first socket
ss = new ServerSocket();
ss.bind(new InetSocketAddress("0.0.0.0", port));
ss.close();
ss = new ServerSocket();
ss.bind(new InetSocketAddress("127.0.0.1", port));

Categories

Resources