Can two different socket instances listen on the same TCP port (port is already in use)

I have a TcpServer class that responds, well, acting like a tcp server. You can find the following class:

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 code 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 an error already using the port. I thought that two different socket instances could listen on the same port, since multiplexing allows two connections on the same port when the connector has different ip or port? What am I missing?

+5
source share
2 answers

You cannot associate two tcp server sockets with the same port. reuseAddress valid for client sockets, and it doesn't work the way you think it does ... and the way you use it will not do anything anyway (because you install it after binding).

You really don't need to bind to the same port twice. Just delete this line tcpServer = new TcpServer(LocalPort); from the bottom of your while , and everything will be installed.

How it works, you bind your server socket once and listen on the port. When the connection arrives, it expands the client socket so that you can 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 force the accept method to return the received socket. Then make your runnable socket as a parameter instead of TcpServer and use it to serve the client connection. Then just keep calling accept in a loop and format the streams for new connections just like you know, except that don't recreate the server every time.

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

Remember to close client sockets after you are done with them.

+5
source

No, you cannot use a port that is already in a listening state. However, any number of clients can connect to the same port. You do not need to listen to the port again, you just create a new thread to process the current connection and wait for a new one. For example, suppose you have a TcpConnectionHanlder class that implements Runnable and accepts a Socket as parameter, the loop will look like

 while (true) { //while(1) is not valid Java syntax final Socket tcpSocket = tcpServer.accept(); // Get socket for incoming connection final Thread thread = new Thread(new TcpConnectionHanlder(tcpSocket)); // Create a thread for this socket/client connection thread.start(); // Launch the thread // tcpServer = new TcpServer(LocalPort); <- not needed, port still listening. } 

Then, in your TcpConnectionHanlder instance TcpConnectionHanlder you process that particular client (socket).

+1
source

Source: https://habr.com/ru/post/1211924/


All Articles