I'm on a debian-based Linux distro and currently testing and learning about some networking stuff.
So I have 3 terminal open, the first 2 I will run this command to set up 2 netcat servers on port 12345 (based on my research this is possible without getting any error in some systems)
nc -lp 12345
And the 3rd terminal I run this command to connect to the netcat servers
nc localhost 12345
In the 3rd terminal after I ran the command, I typed some random string there and observed the other 2 terminals. Only the terminal that run the netcat server first will receives the text that I typed, the other one will just hang there and didn't output anything.
I tried googling to find out why is this the case but most of the results are about how/why setting applications to run on the same port is possible, but not about the order of receiving request data in this situation
I also tried ask ChatGPT about this one, and it mentioned "Bind in a "weird" passive state but not actually receive traffic (depends on implementation)" to the 2nd netcat servers, which is quite of vague
I also used the this command to print out networking data in my machine and both servers actually occupy the port 12345 for 0.0.0.0
$ netstat -tuldp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:12345 0.0.0.0:* LISTEN 58958/nc
tcp 0 0 0.0.0.0:12345 0.0.0.0:* LISTEN 58941/nc
Can someone explains why there is an order despite both occupying the same hostname and port
In the 3rd terminal after I ran the command, I typed some random string there and observed the other 2 terminals. Only the terminal that run the netcat server first will receives the text that I typed, the other one will just hang there and didn't output anything.
netcat makes a TCP connection, and TCP connections always are established between exactly two peers. There is no "conference call" mode in TCP. So the OS necessarily has to choose just one process to receive each connection.
I also tried ask ChatGPT about this one, and it mentioned "Bind in a "weird" passive state but not actually receive traffic (depends on implementation)" to the 2nd netcat servers, which is quite of vague
It's not any kind of "weird" state – 'passive' is merely an outdated term for what's now more often called a 'listening' socket, but other than that, it's a fundamental part of TCP usage. When you're creating a server that will accept connections (TCP or other), you always start by creating a "listening" socket – and binding it to some local address:port – so every TCP server socket is actually in the 'passive' state.
But that socket will never be associated with any actual connection, and will never receive any data directly – it acts more like a placeholder that spawns new sockets. The only function that can be used on this socket is accept(), which returns a brand new socket for every client that connects, and it's those that send and receive data.
And since connections only have two ends, it means that the inbound 'request to connect' cannot be broadcast across all matching listeners; the system has to choose just one peer, whether it's at random or in some order.
In other words, instead of the "listening" socket acting like a hub for all data sent/received, the server program actually ends up having a loose collection of separate pipes to individual clients.1
Practical example:
$ python
>>> import socket
>>> listener = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
>>> listener.bind(("0.0.0.0", 1234))
>>> listener.listen()
>>> client1, client1_addr = listener.accept()
>>> client1.recv(10)
>>> client2, client2_addr = listener.accept()
[...]
As far as I know, by default the system should prevent you from having two sockets listening on the same local address:port, but programs can opt in to "REUSEADDR" if they want to allow duplication; in that case I believe it's indeed implementation-dependent as to which of the listening sockets will receive each client.
both occupying the same hostname and port
The final note is that sockets are never bound to a hostname. Even if the program accepts the hostname, it'll have to resolve that to an IP address
1 Although connectionless transports like UDP can have just a single "hub" socket for everything; it is connection-based ones like TCP that do not.