I'm trying to see what IP's on a list are actually online. I'm currently using
public boolean IsOnline(String ip) {
try (Socket s = new Socket(ip, 80)) {
return true;
} catch (IOException ex) {
}
return false;
}
To check if the server is online. But it takes about 30 seconds for each IP to get checked. Is there a way to get faster results like another kind of method?
Not sure, but would INetAddress.isReachable suffice for your needs? You can't do ICMP messages in Java.
You may use the INetAddress.isReachable
".. 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 only reason I can imagine, why this takes 30 seconds is, that nobody listens to port 80 and your socket connection timeout is 30 seconds. Please check for this by adding ex.printStackTrace() within the catch clause.
Please take a read here: Why are empty catch blocks a bad idea?
How you should "ping" a server, depends on what ports it is listening to. Normally INetAdresse.isReachable() works good. If your administrator blocks ICMP requests you may use the ssh port 22, to probe for the servers existence.
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
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.
I hope you can help. Im fairly new to progamming and Im playing around with java Sockets.
The problem is the code below. for some reason commSocket = new Socket(hostName, portNumber); is returning true even when it has not connected with the server (server not implemented yet!). Any ideas regarding this situation?
For hostName Im passing my local machine IP and for port a manually selected port.
public void networkConnect(String hostName, int portNumber){
try {
networkConnected = false;
netMessage = "Attempting Connection";
NetworkMessage networkMessage = new NetworkMessage(networkConnected, netMessage);
commSocket = new Socket(hostName, portNumber);
// this returns true!!
System.out.println(commSocket.isConnected());
networkConnected = true;
netMessage = "Connected: ";
System.out.println("hellooo");
} catch (UnknownHostException e){
System.out.println(e.getMessage());
} catch (IOException e){
System.out.println(e.getMessage());
}
}
Many thanks.
EDIT: new Socket(.., ..); is blocking isnt it? i thought in that case if that was processed without exceptions then we have a true connection?
EDIT: I played around with anti virus and now it is working!
Had that exact same situation a few days ago on a corporate computer, and searched for it for hours.
Check your antivirus, some antivirus (like E*** N**32) use live TCP scanning that make a connection succeed even if nothing is listening on the target port but will reset it later when you try to read/write from the socket.
Add this to your code:
commSocket.getOutputStream().write(0);
commSocket.getInputStream().read();
If you get a SocketException now, you should really consider to change your antivirus.
Alternatively, set a breakpoint in your application right after creating the socket, and then use netstat -ano (on Windows) to check which process id is associated with the other endpoint of your socket (which should be on your machine if you connect to localhost).
I would suggest you to disable your antivirus, but in some cases even that does not help to unload their broken live TCP scanning driver...
The Socket constructor connects right away and will throw an IOException if it doesn't succeed. So apparently you have connected successfully to a server (this could be one you didn't make yourself).
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();