I am writing a program that simply tests connections to ports on remote machines and checks if a connection was established or rejected, pretty much a port scanner. While it seems to work on localhost and some sites, for some reason it won't work on most IP addresses, when several of my classmates followed similar approaches and were able to probe these same sites. Some sites, such as wikipedia.org, will only go up to port 21 and then hang. Can anyone see any obvious problems with my code. Thansk in advance.
for(int i = 1; i <= maxPort; i++)
{
boolean found = true;
try
{
String[] hostNameArray = hostName.split(".");
socket = new Socket(hostName, i);
System.out.println("Test");
socket.close();
}
catch(java.net.ConnectException ex)
{
System.out.println("Error" + ex + "\t<"+i+">");
found = false;
}
catch(java.net.UnknownHostException ex)
{
System.out.println("Unknown host");
System.exit(-1);
}
catch(IOException ex)
{
System.out.println("IO Exception");
System.exit(-2);
}
if(found)
{
ports.add(i);
}
}
Places such as google.com will simply stop when I try to create the socket (i.e. the test statement is never printed) while wikipedia.org will simply hang after 21. Thanks again for the help.
Related
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.
we were wanting to build a functionality where if a user is connected to a WiFi network, we can display the details of other devices connected to the same WiFi. How do we go about it?
Right now, we are able to achieve it by:
pinging all the IP addresses on the current network(looping from 1-255) - this is the most time consuming step (code snippet below)
for the IP addresses that responded, fetching their MAC addresses and finally
fetching the manufacturer for the MAC addresses using an external API
we have success in this but the issue is that it takes way too long - around 4-5 minutes to do this. I have a feeling that someone can point us towards a better, faster solution.
There was a similar question(although it was about iOS) but didn't find any answer, hence posting this again. Please pardon if that was against the rules. Any help in this would be highly appreciated.
Here's the snippet of code which is taking too long to give the results back(step 1)
for (int i = 0; i < 255; i++) {
String host = "";
try {
String subnet = "192.168.2";
host = subnet + "." + i;
Process exec = Runtime.getRuntime().exec(String.format(CMD, host));
int i1 = exec.waitFor();
if (i1 == 0) {
InetAddress a = InetAddress.getByName(host);
Log.i("TAG", "run: " + a.getHostAddress());
} else {
throw new IOException("Unable to get ping from runtime");
}
} catch (IOException | InterruptedException e) {
try {
InetAddress a = InetAddress.getByName(host);
if (a.isReachable(200)) {
Log.i("TAG", "run: " + a.getHostAddress());
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
I'm trying to connect my Android APP to a Java server that I've made for it.
I have a problem, the server works good and the APP works fine too when connected to the server.
The problem comes when I close the server and try to connect to it. The suppose is that the Socket.connect() would throw an exception that I would catch, but this exception is not thrown.
I don't know what I'm doing bad, I paste my code here for you to read and maybe somone can help me. Thanks for all mates :D
Connection attributes:
static Socket s;
static DataOutputStream output;
static boolean connected;
The method who needs the connection:
public void enviarDatos(int r, int g, int b){
connect();
if(connected){
panel.setText(panel.getText() + "\nEnviando datos...");
try {
output.writeUTF(r + "," + g + "," + b);
} catch (Exception e) {
panel.setText("Error: " + e.getMessage());
}
disconnect();
}
}
The methods to connect and disconnect are there:
public void connect(){
try {
s = new Socket();
int timeout = 1000;
s.connect(new InetSocketAddress(SERVER_ADDRESS, SERVER_PORT), timeout);
output = new DataOutputStream(s.getOutputStream());
connected = true;
panel.setText("Conexion exitosa.");
} catch (Exception e) {
connected = false;
panel.setText("Error: " + e.getMessage());
}
}
public void disconnect(){
try{
output.close();
s.close();
connected = false;
} catch(Exception e){
panel.setText("Error: " + e.getMessage());
}
}
The first connect() method is different from the one you posted in the large code block where you present both the methods. It's pretty unclear which one you are using to connect. Try adding the int timeout parameter to the connect() like this:
int timeout = 1000; // 1s timeout
s.connect(new InetSocketAddress(SERVER_ADDRESS, SERVER_PORT), timeout);
This should make connect throw an IOException after the timeout expires.
Hope this solves your problem.
I see one potential issue in "disconnect". I think you're trying to close the socket when the output stream is still opened. In this case, the socket may not close properly which may cause issues in reopening. Although you should see an exception being thrown during closing.
In disconnect(), can you try closing output first before closing the socket?
public void disconnect(){
try{
output.close();
s.close();
connected = false;
} catch(Exception e){
panel.setText("Error: " + e.getMessage());
}
}
I don't have the context of this problem, but that's one potential issue I saw. Hopefully it helps.
I have a TCP Server and Client both written in Java and running on separate machines on Rhel 5.3 with jdk1.6. I have handled pretty much all the methods i could find to detect a disconnection on the "Server".
Following is a snippet of the Server code
private void listenforConnection() {
try {
socket = serverSocket.accept();
socket.setTcpNoDelay(true);
socket.setKeepAlive(true);
socket.setSoTimeout(5);
bosTcpOutStream = new BufferedOutputStream(socket.getOutputStream());
bisTcpInStream = new BufferedInputStream(socket.getInputStream());
log("New connection accepted from " + socket.getRemoteSocketAddress().toString());
sendHeartBeatsToClient();
} catch (IOException ie) {
log("Listener IOException : " + ie.getMessage());
}
}
private void sendHeartBeatsToClient() {
try {
while (true) {
long lngCurrentMillis=System.currentTimeMillis() ;
if ((lngCurrentMillis - lngLastSentMessageTime) >= 5000) {
byte[] bHeartBeat = getHeartBeatMessage();
bosTcpOutStream.write(bHeartBeat);
bosTcpOutStream.flush();
lngLastSentMessageTime = System.currentTimeMillis();
log("Heartbeat sent.");
} else {
try {
if (bisTcpInStream.read() == -1) {
log("Read Input Stream returned -1");
break;
}
} catch (SocketTimeoutException se) {
//Do nothing as i am not expecting the client to send anything.
} catch (IOException e) {
log("Read Input Stream error - " + e.getMessage());
break;
}
}
Thread.sleep(1);
}
} catch (IOException e) {
disconnectClientAndCloseSocket();
log("IO Exception" +e.getMessage());
} catch (InterruptedException e) {
disconnectClientAndCloseSocket();
log("Thread interrupted terminating." + e.getMessage());
}
}
I have also modified the tcp-keepalive kernel parameters on the "Server" machine as below:
net.ipv4.tcp_keepalive_time=2
net.ipv4.tcp_keepalive_probes=1
net.ipv4.tcp_keepalive_intvl=2
Now when i am simulating a disconnection by unplugging the network cable of the Client machine(after it has established the connection and received the initial data from the Server), I am seeing two different outcomes which i am unable to understand:-
If i unplug the cable after 10 to 15 seconds of successful client connection. On the "Server" I receive an IO Exception with "no route to host" after 10 minutes of unplugging the cable.
If i unplug the cable after 60 or so seconds of successful client connection. On the "Server" an IO exception is thrown with "Connection timed out" within 10 seconds. This is valid behavior keeping in mind the keep alive settings.
I have tried this a couple of times and i always get the same result.
What i don't understand is why the first outcome takes 10 minutes and it doesn't behave like the second outcome. Am i missing something?
Following code can reproduce the issue:
int errAt = -1;
try {
System.out.println("start...");
for (int i = 0; i < 4000; i++) {
errAt = i;
DatagramSocket result = new DatagramSocket(null);
result.bind(new InetSocketAddress(InetAddress.getLocalHost(), 9005));
result.close();
//System.out.println(i);
}
} catch (Exception e) {
System.out.println("Error: " + e.getMessage());
System.out.println("ErrAt: " + errAt);
e.printStackTrace();
} finally {
System.out.println("end...");
}
In my PC, I'll see "java.net.BindException: Address already in use: Cannot bind" exception after run 2k+ times.
I'm not sure, is this means that the close method didn't close the native socket immediately?
This code works on my Mac even if I set it to run 40,000 iterations. I think the likely problem here is that the socket isn't being closed immediately on Windows but then again you are trying to do thousands of iterations within the space of probably milliseconds.
The following code will continually retry and sleep a small amount of time to let you see if its a delay problem where the socket would be closed within some space of time:
long tCumulative = 0;
int errAt = -1;
System.out.println("start...");
for (int i = 0; i < 4000; i++) {
try {
errAt = i;
DatagramSocket result = new DatagramSocket(null);
result.bind(new InetSocketAddress(InetAddress.getLocalHost(), 9005));
result.close();
//success at last
tCumulative = 0;
} catch (Exception e) {
System.out.println("Error (at="+errAt+") (waited="+tCumulative+"ms): " + e.getMessage());
tCumulative+=50;
Thread.sleep(50);
i--;
}
}
System.out.println("end...");
It is not clear what you are trying to do, but one way to get around the problem of a UDP port still being in use is to set the "reuse address" option before you bind.
Reference: How to set reuse address option for a datagram socket in java code?
If you create the socket but then get e.g. a BindException you aren't closing the socket. It should be closed in a finally {} block.
It is difficult to see the point of this test. Normal UDP programs open one DatagramSocket and leave it open for the life of the process. No sane program would churn through thousands of UDP sockets.