My purpose is check if a host (local or remote) is running and check if the port is open too.
I have a class with the following:
boolean localStatus = new ControlIpPortAddress("127.0.0.1", 61616).control();
logger.info("localStatus: {}", localStatus);
boolean remoteStatus = new ControlIpPortAddress("192.168.4.5", 8080).control();
logger.info("remoteStatus: {}", remoteStatus);
Where the control
method is:
public boolean control(){
logger.info("Starting");
boolean status = false;
InetAddress inetAddress = null;
SocketChannel socketChannel = null;
InetSocketAddress socketAddress = null;
try {
inetAddress = InetAddress.getByName(ipAddress);
}
catch (UnknownHostException uhe) {
logger.error("Error: {}, Class: {}" , uhe.getMessage(), uhe.getClass());
uhe.printStackTrace();
return false;
}
socketAddress = new InetSocketAddress(inetAddress, portAddress);
try {
logger.info("1");
socketChannel = SocketChannel.open();
logger.info("2");
status = socketChannel.connect(socketAddress);
logger.info("3");
socketChannel.configureBlocking(false);
logger.info("4");
socketChannel.finishConnect();
logger.info("5");
socketChannel.close();
}
catch (IOException ioe) {
logger.error("Error: {}, Class: {}" , ioe.getMessage(), ioe.getClass());
return false;
}
logger.info("Ending");
return status;
}
When I execute my program it hangs, check the following output
INFO rastructure.support.ControlIpPortAddress: 26 - Starting
INFO rastructure.support.ControlIpPortAddress: 46 - 1
INFO rastructure.support.ControlIpPortAddress: 48 - 2
INFO rastructure.support.ControlIpPortAddress: 50 - 3
INFO rastructure.support.ControlIpPortAddress: 52 - 4
INFO rastructure.support.ControlIpPortAddress: 54 - 5
INFO rastructure.support.ControlIpPortAddress: 63 - Ending
INFO ructure.support.LocalHostStatusCondition: 27 - localStatus: true
INFO rastructure.support.ControlIpPortAddress: 26 - Starting
INFO rastructure.support.ControlIpPortAddress: 46 - 1
INFO rastructure.support.ControlIpPortAddress: 48 - 2
//doom - hang
How we can see, the SocketChannel's connect
method is the problem. I already did a research on Google and the results are not clear, it says if the host does not exists or if is down, it is the default behavior, remains hang it.
Wondered if exists an adequate and elegant way, through Java itself, to just throw an exception after to set a timeout. Even worst, seems the API does not let set an explicit timeout.
Thank You.
Your code doesn't make sense. You're doing the connect in blocking mode, which either completes or throws an exception, and then putting the channel into non blocking mode and calling finishConnect(),
which isn't required at all unless you did the connect in non-blocking mode, which you didn't. You should:
connect()
OP_CONNECT
with a timeoutfinishConnect(),
and if it returns true continue using the connected channel: otherwise return to the select stepOR, much more simply
Socket.connect(address, timeout)
, e.g. channel.socket().connect(...)
.Notes: