Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can two different socket instances listen to same TCP port ( Port already in use )

Tags:

java

tcp

sockets

I have a TcpServer class that is responsible to, well, act like a tcp server. You can find the class below :

public class TcpServer {
    private ServerSocket serverSocket;
    private Socket socket;
    private int locallyBoundPort;

    public TcpServer() {


    }

    public TcpServer(int locallyBoundPort) {
        try {
            this.serverSocket = new ServerSocket(locallyBoundPort);
            serverSocket.setReuseAddress(true);
        } catch (IOException e) {
            System.out.println("Error at binding to port TCP : " + locallyBoundPort + "...cause : " + e.getMessage());
        }
        socket = null;

    }

    public void accept() {
        try {
            socket = serverSocket.accept();
            socket.setReuseAddress(true);
        } catch (IOException e) {
            System.out.println("Error at accept : " + locallyBoundPort);
        }
    }



    public void send(Data data) throws IOException {
        if(socket != null) {

            ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());
            out.writeObject(data);

        }
    }

    public Data receive() throws ClassNotFoundException, IOException {
        if(socket != null) {

                ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
                return (Data) in.readObject();

        } else {
            return null;
        }
    }

    public boolean bind(int port) throws IOException {
        try {
            this.serverSocket = new ServerSocket(port);
            this.locallyBoundPort = port;
        } catch(IOException e) {
            return false;
        }
        return true;

    }

    public void close() {
        try {
            serverSocket.close();
            socket.close();
        } catch (IOException e) {
            OzumUtils.print("IOException in close, TcpServer");
        }

    }

    public int getLocallyBoundPort() {
        return locallyBoundPort;
    }

    public Socket getSocket() {
        return socket;
    }

    public ServerSocket getServerSocket() {
        return serverSocket;
    }
}

And I have a code piece that does this :

TcpServer tcpServer = new TcpServer(LocalPort);
while(1)
{
    tcpServer.accept();
    Thread thread = new Thread(new runnable(tcpServer));
    thread.start();
    tcpServer = new TcpServer(LocalPort);
}

However I am getting a port already in use error. I thought two different socket instances could listen to the same port as multiplexing allows two connections through the same port when the connector has different ip or port ? What am I missing?

like image 470
Ozum Safa Avatar asked Jan 26 '15 14:01

Ozum Safa


People also ask

Can multiple sockets listen on the same port?

For TCP, no. You can only have one application listening on the same port at one time. Now if you had 2 network cards, you could have one application listen on the first IP and the second one on the second IP using the same port number. For UDP (Multicasts), multiple applications can subscribe to the same port.

Can 2 processes use the same port?

Yes, different applications can bind to the same port on different transport protocols. They can also open the same port on the same protocol but different IP addresses.

Can two UDP sockets bind same port?

Yes, it is also possible to have multiple sockets using a single UDP port. With the caveat that only broadcast & multicast packets are going to be multiplexed, unicast packets will only be delivered to the first socket.

How many TCP ports can be open at the same time?

Ports and Protocols. Between the protocols User Datagram Protocol (UDP) and Transmission Control Protocol (TCP), there are 65,535 ports available for communication between devices.


1 Answers

You cannot bind two tcp server sockets to the same port. reuseAddress is really for client sockets, and it does not work the way you think it does ... and the way you are using it would not do anything at all either way (because you are setting it after binding).

You don't really need to bind twice to the same port either. Just remove this line tcpServer = new TcpServer(LocalPort); from the bottom of your while loop, and you'll be all set.

The way this works is that you bind your server socket once and listen to the port. When a connection arrives, it forks a client socket for you to communicate with the client, and the original server socket continues to listen for more connections.

Basically, you need to remove the socket member (and any other state) from your TcpServer, and make the accept method return the accepted socket. Then make your runnable take that socket as a parameter instead of the TcpServer, and use that to serve the client connection. Then just keep calling accept in the loop, and forking threads for new connections same way you do know, except do not recreate the server every time.

Or, alternatively, remove the server socket and port from TcpServer, create the socket outside the loop, then while(true) call accept on it, create a new TcpServer with the returned client socket, and use it in a thread to process the connection.

Do not forget to close client sockets after you are done with them.

like image 139
Dima Avatar answered Oct 27 '22 00:10

Dima