Eugene
Eugene

Reputation: 60204

ServerSocket accept() method

Who knows how the port is chosen when I'm using accept method of ServerSocket class? Is it possible to define a range for the ports the method can choose from? Can I 'take' ports one by one just in order?

ServerSocket sSocket = new ServerSocket(5050);
Socket socket = sSocket.accept();

From the book

Upvotes: 14

Views: 55055

Answers (5)

SimonJ
SimonJ

Reputation: 21306

The diagram is incorrect (and is listed in the unconfirmed errata on the O'Reilly site).

The client chooses its port at random (you don't need to do anything special in Java) and connects to the server on whichever port you specified. Using the netstat commandline tool you can see this.

First, just the listening server socket with no clients:

simon@lucifer:~$ netstat -n -a
Active Internet connections (including servers)
Proto Recv-Q Send-Q  Local Address          Foreign Address     (state)
...
tcp46      0      0  *.5050                 *.*                 LISTEN
...

(there are lots of other entries, I've just removed the unrelated ones)

Now with one client connecting from localhost (127.0.0.1):

simon@lucifer:~$ netstat -n -a
Active Internet connections (including servers)
Proto Recv-Q Send-Q  Local Address          Foreign Address     (state)
...
tcp4       0      0  127.0.0.1.64895        127.0.0.1.5050      ESTABLISHED <- 1
tcp4       0      0  127.0.0.1.5050         127.0.0.1.64895     ESTABLISHED <- 2
tcp46      0      0  *.5050                 *.*                 LISTEN      <- 3
...

Since the client is connecting from the same machine, we see two established connections - one from client to server (1), the other from server to client (2). They have opposite local and foreign addresses (since they're talking to each other) and you can see the server is still using port 5050 while the original server socket (3) continues to listen on the same port.

(this output is from a Mac, but Windows/Linux also have netstat giving similar output)

Upvotes: 28

user207421
user207421

Reputation: 311001

You chose the port, when you said new ServerSocket(5050). All that stuff about using a different port for the accepted socket is 100% BS.

Upvotes: 8

thejh
thejh

Reputation: 45578

A TCP connection consists of four parts:

  • Client IP
  • Client Port
  • Server IP
  • Server Port

There can be, for example, multiple clients connected to the same server port - as long as the clients don't have the same IP and the same prt, it's ok. And for that part, the Operating System takes care.

So it's totally ok to listen just on one port.

Upvotes: 4

khachik
khachik

Reputation: 28703

You can pass 0 as a port number to create a server socket on any free port, or make a method like this to create a server socket for any free port in the given range:

public java.net.ServerSocket createServerSocket(int rangeStart, int rangeEnd)
                            throws java.io.IOException {
  for(int port=rangeStart; port<=randeEnd; port++) {  
    try {
      return new ServerSocket(port);
    } catch(java.net.BindException be) {
      // debug/warning here
      continue;
    }
  }
  throw new java.io.IOException("Failed to create a server socket, all ports between " +
                                rangeStart + " - " + rangeEnd + " are already in use.");
}

The loop doesn't take care of another exception (SecurityException for example), but you can add it.

Upvotes: 2

Codemwnci
Codemwnci

Reputation: 54894

The ServerSocket defines the port as part of the constructor. If you do not specify a port, the socket is not bound (i.e. cannot be accessed).

To get the port of the connecting Socket, use getPort() and not getLocalPort(). The second one will give you the port on your server.

Upvotes: 0

Related Questions