TCP / HTTP listening on ports: how many users can use the same port
So what happens when a server listens for incoming connections on a TCP port? For example, let's say you have a web server on port 80. Suppose your computer has a public IP address of 24.14.181.229, and the person trying to connect to you has an IP address of 10.1.2.3. This person can connect to you by opening a TCP socket up to 24.14.181.229:80. Simple enough.
Intuitively (and erroneously), most people think it looks something like this:
Local Computer | Remote Computer -------------------------------- <local_ip>:80 | <foreign_ip>:80 ^^ not actually what happens, but this is the conceptual model a lot of people have in mind.
This is intuitive, because from the point of view of the client, it has an IP address and connects to the server via IP: PORT. Since the client connects to port 80, should its port also be 80? This is a reasonable thing to think about, but it’s not really what is happening. If this were correct, we could only serve one user to someone else's IP address. As soon as the remote computer connects, it will connect port 80 to port 80, and no one will be able to connect.
Three things to understand:
1.) On the server, the process is listening on the port. As soon as it receives the connection, it passes it to another thread. Communication never forces a listening port.
2.) Connections are uniquely identified by the OS with the following 5-tuple: (local-IP address, local port, remote IP protocol, remote port, protocol). If any element in the tuple is different, then this is a completely independent join.
3.) When the client connects to the server, it selects a random unused port of a high order source. Thus, one client can have up to ~ 64 thousand connections to the server for the same destination port.
So this is really what is created when the client connects to the server:
Local Computer | Remote Computer | Role ----------------------------------------------------------- 0.0.0.0:80 | <none> | LISTENING 127.0.0.1:80 | 10.1.2.3:<random_port> | ESTABLISHED
Looking at what is really going on
First, let me use netstat to see what is happening on this computer. We will use port 500 instead of 80 (because there are a whole bunch of things going on on port 80, since this is a common port, but functionally it does not matter).
netstat -atnp | grep -i ":500 "
As expected, the output is empty. Now start the web server:
sudo python3 -m http.server 500
Now here is the result of running netstat:
Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 0.0.0.0:500 0.0.0.0:* LISTEN -
So now there is one process that is actively listening (State: LISTEN) on port 500. The local address is 0.0.0.0, which is the code for "listening on all IP addresses." A simple mistake is to listen only on port 127.0.0.1, which will only accept connections from the current computer. Thus, this is not a connection, it just means that the process requested to bind () to the IP port, and this process is responsible for processing all connections to this port. This indicates a limitation that there can only be one process on a computer that listens on a port (there are ways to get around this using multiplexing, but this is a much more complicated topic). If the web server is listening on port 80, it cannot exchange this port with other web servers.
So now connect the user to our machine:
quicknet -m tcp -t localhost:500 -p Test payload.
This is a simple script ( https://github.com/grokit/quickweb ) that opens a TCP socket, sends a payload ("test load" in this case), waits a few seconds, and shuts down. The second execution of netstat is as follows:
Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 0.0.0.0:500 0.0.0.0:* LISTEN - tcp 0 0 192.168.1.10:500 192.168.1.13:54240 ESTABLISHED -
If you connect to another client and run netstat again, you will see the following:
Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 0.0.0.0:500 0.0.0.0:* LISTEN - tcp 0 0 192.168.1.10:500 192.168.1.13:26813 ESTABLISHED -
... that is, the client used another random port to connect. Thus, there is never any confusion between IP addresses.