views:

401

answers:

11

I want to start a server which listen to a port. I can specify port explicitly and it works. But I would like to find a port in an automatic way. In this respect I have two questions.

  1. In which range of port numbers should I search for? (I used ports 12345, 12346, and 12347 and it was fine).

  2. How can I find out if a given port is not occupied by another software?

+2  A: 

If your server starts up, then that socket was not used.

EDIT

Something like:

ServerSocket s = null ;

try { 
    s = new ServerSocket( 0 ); 
} catch( IOException ioe ){
   for( int i = START; i < END ; i++ ) try {
        s = new ServerSocket( i );
    } catch( IOException ioe ){}
}
// At this point if s is null we are helpless
if( s == null ) {
    throw new IOException(
       Strings.format("Unable to open server in port range(%d-%d)",START,END));
}
OscarRyz
Don't know who voted you down, but I voted you back up. You could set up a recursive function to tries to setup the ServerSocket, and if you get an IOException (or whatever it is), you try again until it successfully gets a port.
jonescb
I thinks it's better to check if a port is available and then try to start listening to this port. It's does not seem to be elegant to start something and then find out that there are some problem and then try to solve these problems.
Roman
@Roman well, yes, that would be better, except for the fact there is no a method to know if a port is available. If `new ServerSocket(0)` is not working for your the alternative is this. I think there are 85% of possibilities you end up using my suggestion.
OscarRyz
A: 

You don't want to find a port automatically in most cases. How are the clients going to know which port the server is listening on if it changes all the time?

jonescb
Every server announce its service with Bonjour. So, clients can see which services are announces and which ports they used. So, it shouldn't be a problem.
Roman
A: 

You can't find a free port using java (and no native extensions). This is OS dependent. Read here for a description of port ranges. You should have a configuration file to let the administrator select appropriate ports

kgiannakakis
+4  A: 

According to Wikipedia, you should use ports 49152 to 65535 if you don't need a 'well known' port.

AFAIK the only way to determine wheter a port is in use is to try to open it.

Andy Johnson
+8  A: 

If you pass 0 as the port number to the constructor of ServerSocket, It will allocate a port for you.

Maurice Perry
Yes, I think it's the most elegant solution but because of some reasons it does not work in my case. But I still need to find out what exactly is wrong.
Roman
@Roman, post your code and let's find out
OscarRyz
@Roman: Why doesn't it work? Update your question to include this (or people will keep suggesting it) and explain why this solution fails for you.
FrustratedWithFormsDesigner
+9  A: 

If you don't mind the port used, specify a port of 0 to the ServerSocket constructor and it will listen on any free port.

ServerSocket s = new ServerSocket(0);
System.out.println("listening on port: " + s.getLocalPort());

If you want to use a specific set of ports, then the easiest way is probably to iterate through them until one works. Something like this:

public ServerSocket create(int[] ports) throws IOException {
    for(int port : ports) {
        try {
            return new ServerSocket(port);
        } catch (IOException ex) {
            continue; // try next port
        }
    }

    // if the program gets here, no port in the range was found
    throw new IOException("no free port found");
}

Could be used like so:

try {
    ServerSocket s = create(new int[] { 3843, 4584, 4843 });
    System.out.println("listening on port: " + s.getLocalPort());
} catch (IOException ex) {
    System.err.println("no available ports");
}
Graham Edgecombe
+3  A: 

See http://java.sun.com/j2se/1.4.2/docs/api/java/net/ServerSocket.html#ServerSocket%28int%29

Creates a server socket, bound to the specified port. A port of 0 creates a socket on any free port.

f1sh
+2  A: 

The Eclipse SDK contains a class SocketUtil, that does what you want. You may have a look into the CVS source code.

jopa
+1  A: 

It may not help you much, but on my (Ubuntu) machine I have a file /etc/services in which at least the ports used/reserved by some of the apps are given. These are the standard ports for those apps.

No guarantees that these are running, just the default ports these apps use (so you should not use them if possible).

There are slightly more than 500 ports defined, about half UDP and half TCP.

The files are made using information by IANA, see IANA Assigned port numbers.

extraneon
there is a similar (and more complete, IIRC) list that comes as part of nmap. +1
rmeador
A: 

In Java, if I use 0 for the port, it might pick a free one, but I need to know what it is to talk to it from the other half of my program (which is in C). Java blocks, and gives an exception if you use getLocalPort().

So how can I find an open port in C (both in Linux and Windows/cygwin) that I can then pass to Java?

A: 

This works for me on Java 6

    ServerSocket serverSocket = new ServerSocket(0);
    System.out.println("listening on port " + serverSocket.getLocalPort());
Peter Lawrey