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?
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.
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With