206

This might be a very basic question but it confuses me.

Can two different connected sockets share a port? I'm writing an application server that should be able to handle more than 100k concurrent connections, and we know that the number of ports available on a system is around 60k (16bit). A connected socket is assigned to a new (dedicated) port, so it means that the number of concurrent connections is limited by the number of ports, unless multiple sockets can share the same port. So the question.

Jan Schultke
  • 17,446
  • 6
  • 47
  • 96
K J
  • 4,505
  • 6
  • 27
  • 45

7 Answers7

326

TCP / HTTP Listening On Ports: How Can Many Users Share the Same Port

So, what happens when a server listen for incoming connections on a TCP port? For example, let's say you have a web-server on port 80. Let's assume that your computer has the public IP address of 24.14.181.229 and the person that tries to connect to you has IP address 10.1.2.3. This person can connect to you by opening a TCP socket to 24.14.181.229:80. Simple enough.

Intuitively (and wrongly), most people assume that 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 standpoint of the client, he has an IP address, and connects to a server at IP:PORT. Since the client connects to port 80, then his port must be 80 too? This is a sensible thing to think, but actually not what happens. If that were to be correct, we could only serve one user per foreign IP address. Once a remote computer connects, then he would hog the port 80 to port 80 connection, and no one else could connect.

Three things must be understood:

1.) On a server, a process is listening on a port. Once it gets a connection, it hands it off to another thread. The communication never hogs the listening port.

2.) Connections are uniquely identified by the OS by the following 5-tuple: (local-IP, local-port, remote-IP, remote-port, protocol). If any element in the tuple is different, then this is a completely independent connection.

3.) When a client connects to a server, it picks a random, unused high-order source port. This way, a single client can have up to ~64k connections to the server for the same destination port.

So, this is really what gets created when a client connects to a 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 Actually Happens

First, let's use netstat to see what is happening on this computer. We will use port 500 instead of 80 (because a whole bunch of stuff is happening on port 80 as it is a common port, but functionally it does not make a difference).

    netstat -atnp | grep -i ":500 "

As expected, the output is blank. Now let's start a web server:

    sudo python3 -m http.server 500

Now, here is the output of running netstat again:

    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 code for "listening for all ip addresses". An easy mistake to make is to only listen on port 127.0.0.1, which will only accept connections from the current computer. So this is not a connection, this just means that a process requested to bind() to port IP, and that process is responsible for handling all connections to that port. This hints to the limitation that there can only be one process per computer listening on a port (there are ways to get around that using multiplexing, but this is a much more complicated topic). If a web-server is listening on port 80, it cannot share that port with other web-servers.

So now, let's connect a 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 the payload ("Test payload." in this case), waits a few seconds and disconnects. Doing netstat again while this is happening displays 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:54240      ESTABLISHED -

If you connect with another client and do 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 for the connection. So there is never confusion between the IP addresses.

Bibek Shrestha
  • 32,848
  • 7
  • 31
  • 34
N0thing
  • 6,745
  • 3
  • 20
  • 16
  • 30
    This is the best answer I've ever seen on SO. – Jobs Jun 11 '16 at 09:02
  • 2
    @N0thing "This way, a single client can have up to ~64k connections to the server for the same destination port." So in practice , if a client do not connects to same server and port, twice or multiple times concurrently, then a client can have even more than ~64K connections. Is that true. If yes then that implies that from a single port on client side it can have connection to many different server processes (such that socket connection is different). So in all, multiple client sockets can reside on same port on client machine ? Please read my comment to "Remey Lebeau" answer. Thanks :D – Prem KTiw Dec 03 '16 at 16:07
  • 8
    @premktiw: Yes, multiple client sockets can be bound to the same local IP/port pair at the same time, if they are connected to different server IP/Port pairs so the tuples of local+remote pairs are unique. And yes, it is possible for a client to have more than 64K concurrent connections total. From a single port, it can be connected to a potentially infinite number of servers (limited by available OS resources, available router ports, etc) as long as the server IP/port pairs are unique. – Remy Lebeau Dec 04 '16 at 02:40
  • 1
    @RemyLebeau Satisfied . Thank You very very much :D – Prem KTiw Dec 04 '16 at 03:34
  • 2
    @bibstha How does firewall deal with random ports, when all incoming connections are rejecting? – PatrykG Nov 20 '17 at 11:04
  • 2
    @PatrykG random ports are for client and firewalls do not look into connecting client port, rather the destination port. – Bibek Shrestha Nov 21 '17 at 18:37
  • Isn't there a mistake under "So, this is really what gets created when a client connects to a server:". I think that client connects to port 80 of a server, not to some random port. The client establishes the connection from some random port, not 80. Am i right? – mnj Apr 03 '18 at 08:17
  • I had to scroll the way up the text to put a +1. Well done. – Niki Romagnoli Sep 18 '19 at 09:36
  • 1
    @N0thing You said that If a server listens to a port(e.g. 80), when a client connects to it, the requested is handed off to another thread but then how does the server response work with multiple connections at port 80 from different clients? There must me some magic happening at some layer? – Ajak6 Nov 24 '21 at 11:02
  • Remy Lebeau comment needs more clarification and reference. Normally, and with default behavior, it may NOT be possible that "multiple client sockets can be bound to the same local IP/port pair at the same time" (when I tested it on my local machine, it was NOT possible) – obanadingyo Apr 19 '23 at 05:40
  • Most answers focus on the server side (service listening in a single local port), but the TCP "identifying tuple" (SRCIP+SRCPORT+DSTIP+DSTPORT) is also valid for CLIENT connections (TCP sessions established from a random local port to a remote host). This means that a single host can have much more than 64k established TCP sessions as long as they are not all to the same destination. In other words, if we have a proxy server with a single IP address it will be able to establish around 64k connections to EACH destination IP/PORT (one for each local port). – drizin May 11 '23 at 20:53
  • Similar question (that also explains how each client can have up to 64k connections to a single server port): https://stackoverflow.com/questions/2332741/what-is-the-theoretical-maximum-number-of-open-tcp-connections-that-a-modern-lin – drizin May 11 '23 at 21:26
258

A server socket listens on a single port. All established client connections on that server are associated with that same listening port on the server side of the connection. An established connection is uniquely identified by the combination of client-side and server-side IP/Port pairs. Multiple connections on the same server can share the same server-side IP/Port pair as long as they are associated with different client-side IP/Port pairs, and the server would be able to handle as many clients as available system resources allow it to.

On the client-side, it is common practice for new outbound connections to use a random client-side port, in which case it is possible to run out of available ports if you make a lot of connections in a short amount of time.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • 4
    @Remy Connections are discriminated not only by source/destination port/IP, but also by a protocol (TCP, UDP etc.), if I am not mistaken. – Ondrej Peterka Apr 27 '14 at 15:00
  • 2
    @OndraPeterka: yes, but not all platforms restrict on that. For instance, Windows happily allows separate IPv4 and IPv6 server sockets to listen on the same local IP:Port without jumping through hoops, but *Nix systems (including Linux and Android) do not. – Remy Lebeau Apr 27 '14 at 16:46
  • 2
    @RemyLebeau is there a distinction between client-side and server-side sockets? I ask this because I want to connect to multiple servers using a single Socket.AFIK there is no difference between them after the connection has been estabilished. But I can't find the API to **initiate** a connection to several host, port pairs using a single Socket. – user2268997 Mar 27 '15 at 08:28
  • 11
    @user2268997: You cannot use a single socket to connect to multiple servers. You must create a separate socket for each connection. – Remy Lebeau Mar 27 '15 at 16:08
  • In Windows by default two servers can connect to the same address/port, unless you use SO_EXCLUSIVEADDRUSE, see for details https://msdn.microsoft.com/en-us/library/windows/desktop/ms740621(v=vs.85).aspx – Fernando Gonzalez Sanchez Jul 05 '16 at 22:51
  • 4
    @FernandoGonzalezSanchez: A single client can have multiple TCP sockets bound to the same local IP/Port pair as long as they are connected to different remote IP/Port pairs. That is not specific to Windows, that is part of how TCP works in general. – Remy Lebeau Jul 05 '16 at 23:50
  • @Remy Lebeau: Sorry, wasnt clear enough, two servers (not two clients) can *listen* to same ip/port in windows by default without multicasting (which is known issue). Your comment is for client, which is obviously true by design. – Fernando Gonzalez Sanchez Jul 05 '16 at 23:59
  • 2
    @FernandoGonzalezSanchez: Despite what [MSDN documentation](https://msdn.microsoft.com/en-us/library/windows/desktop/ms740621.aspx) says, if two TCP listening sockets try to bind to the same IP/Port (wildcard or otherwise) with `SO_REUSEADDR` enabled on both sockets, the second `bind()` still fails with `WSAEADDRINUSE`. I just tried it. It does not make sense to have two TCP servers listening on the same IP/Port pair, and even the documentation warns against that. – Remy Lebeau Jul 06 '16 at 01:26
  • @RemyLebeau. It's indeed possible (the purpose of SO_EXCLUSIVEADDRUSE is to avoid it), but they don't actually "listen", is a kind of port hijacking. A dysfunctional condition. – Fernando Gonzalez Sanchez Jul 06 '16 at 02:10
  • 1
    @FernandoGonzalezSanchez: I don't know what to tell you then, because like I said earlier, I actually tried it and it failed to bind successfully. I could see how UDP and maybe multicast sockets might allow it, but not unicast TCP sockets. – Remy Lebeau Jul 06 '16 at 02:14
  • @RemyLebeau Is it not possible, even theoretically, to create two client TCP sockets on the same port and connect to the same server? – John Strood Oct 23 '16 at 07:54
  • 1
    @Djack the only way that can work is if the client sockets are bound to different local IP addresses on the same port, or are using different transport protocols. – Remy Lebeau Oct 23 '16 at 15:22
  • @RemyLebeau With respect to your previous reply to Djack, I want to know how servers are different than client, in the sense that they are capable of accepting multiple socket connections through one port, but client is unable to do so . Because it is this strange behavior that allows the server to have lot more connections, but restricting client to have only limited no. of connections. Thanks – Prem KTiw Dec 03 '16 at 14:36
  • @premktiw a given socket connection is uniquely identified by a combination of transport protocol, client IP+port, and server IP+port. Multiple clients can connect to the same server IP+port only if their client IP+port are different from each other. On the server side, every connection has the same server IP+port, so the client IP+port must be different. On the client side, it can connect multiple times to the same server if it binds to a different IP+port for each connection. – Remy Lebeau Dec 03 '16 at 15:24
  • 1
    Okay , what I say is that, use a single port to connect to multiple servers. Shouldn't that be possible ? Because in that case I have different sockets for all the connections. And if that is true then a browser must have been managing the connections to different servers through same port ? – Prem KTiw Dec 03 '16 at 15:44
  • 1
    @RemyLebeau Thanks for reply. Please read the previous comment also . And this also implies that different ports are only needed when there is need to connect to same server concurrently ? And if that is true then a client should not run out of connections, if he do not connects to a server concurrently. – Prem KTiw Dec 03 '16 at 15:54
  • 1
    @premktiw yes, technically a client can use the same local port to connect to multiple different servers concurrently. But typically a client lets the OS pick a random available port for each new outbound connection. A client should bind to a specific local port only when required to do so by protocol or network routing restrictions. – Remy Lebeau Dec 03 '16 at 17:27
  • So you are saying that it is not in the hand of client programmer who is writing a client program to bind multiple socket connections to same port. Why OS always picks a random port for client's each new connection, and the OS for server does not do that ? Thanks – Prem KTiw Dec 04 '16 at 01:06
  • 1
    @premktiw: the client programmer is in full control of how sockets are bound locally. If the programmer wants to use the same port for multiple connections, (s)he must explicitly bind to that port. However, it is *customary* to let the OS choose a random port instead (by explicitly binding to port 0, or by not binding at all so `connect()` binds implicitly) to reduce the possibility of any conflicts. A server *can* bind to a random port, but it is not useful to do so unless the server has a way of announcing the chosen port so clients can then connect to it. – Remy Lebeau Dec 04 '16 at 02:34
  • @premktiw: you really need to stop asking questions here and start doing some research on your own. There is plenty of material on how IP connections work over a network and how ports work. Get yourself some good books on TCP/UDP and general socket programming. – Remy Lebeau Dec 04 '16 at 02:35
  • Would the "Harold's" book on network programming in java will be better ? Please suggest some books . How about Stevens UNIX Network Programming ? I know C, C++ and JAVA – Prem KTiw Dec 04 '16 at 03:36
  • 2
    "*Questions asking us to recommend or find a book, tool, software library, tutorial or other off-site resource are off-topic for Stack Overflow as they tend to attract opinionated answers and spam.*" – Remy Lebeau Dec 04 '16 at 03:38
  • By the last paragraph about PORT EXHAUSTION, someone might assume that 64k is the max of TCP sessions that a client IP can establish, and that's NOT TRUE: In the same sense that SERVER connections can have more than 64k TCP sessions using the same local port (by using a 4-tuple identifier with SRCIP+SRCPORT+DSTIP+DSTPORT), CLIENT connections ALSO use the same 4-tuple identifier so they can have more than 64k TCP sessions using the same local port. High-traffic devices (like routers) will frequently have multiple connections using the same local port (but with different DSTIP/DSTPORT). – drizin May 11 '23 at 20:31
60

A connected socket is assigned to a new (dedicated) port

That's a common intuition, but it's incorrect. A connected socket is not assigned to a new/dedicated port. The only actual constraint that the TCP stack must satisfy is that the tuple of (local_address, local_port, remote_address, remote_port) must be unique for each socket connection. Thus the server can have many TCP sockets using the same local port, as long as each of the sockets on the port is connected to a different remote location.

See the "Socket Pair" paragraph in the book "UNIX Network Programming: The sockets networking API" by W. Richard Stevens, Bill Fenner, Andrew M. Rudoff at: http://books.google.com/books?id=ptSC4LpwGA0C&lpg=PA52&dq=socket%20pair%20tuple&pg=PA52#v=onepage&q=socket%20pair%20tuple&f=false

user202729
  • 3,358
  • 3
  • 25
  • 36
Jeremy Friesner
  • 70,199
  • 15
  • 131
  • 234
  • 8
    What you say is entirely true of the server side. However the structure of the BSD Sockets API means that outgoing client-side ports must be unique in practice, because the `bind()` operation precedes the `connect()` operation, even implicitly. – user207421 Jun 21 '12 at 10:46
  • 1
    @EJP Hi, I thought `bind()` is only used at server side before `accept()?` So client side will bind the particular port as well? – Sam YC Jul 19 '13 at 02:46
  • 6
    @GMsoF: `bind()` can be used on the client side before `connect()`. – Remy Lebeau Apr 27 '14 at 16:42
  • In the most voted answer, you can only have one socket listening on the same port. Is it better to say `Thus the server can have many TCP **connections** using the same local port...` connection and socket are different things right? – joe Apr 02 '21 at 02:52
  • 2
    You can only have one TCP socket *listening* on a port, but you can have multiple *connected* TCP sockets simultaneously using that port for sending and receiving data. (these would be the sockets returned by `accept()` on the listening socket) – Jeremy Friesner Apr 02 '21 at 05:26
13

Theoretically, yes. Practice, not. Most kernels (incl. linux) doesn't allow you a second bind() to an already allocated port. It weren't a really big patch to make this allowed.

Conceptionally, we should differentiate between socket and port. Sockets are bidirectional communication endpoints, i.e. "things" where we can send and receive bytes. It is a conceptional thing, there is no such field in a packet header named "socket".

Port is an identifier which is capable to identify a socket. In case of the TCP, a port is a 16 bit integer, but there are other protocols as well (for example, on unix sockets, a "port" is essentially a string).

The main problem is the following: if an incoming packet arrives, the kernel can identify its socket by its destination port number. It is a most common way, but it is not the only possibility:

  • Sockets can be identified by the destination IP of the incoming packets. This is the case, for example, if we have a server using two IPs simultanously. Then we can run, for example, different webservers on the same ports, but on the different IPs.
  • Sockets can be identified by their source port and ip as well. This is the case in many load balancing configurations.

Because you are working on an application server, it will be able to do that.

peterh
  • 11,875
  • 18
  • 85
  • 108
  • 2
    He didn't ask about making a second `bind()`. – user207421 Mar 03 '17 at 06:18
  • 1
    @user207421 Did you ever seen an OS where listening sockets aren't set up by `bind()`? I can imagine it, yes it is quite possible, but fact is that both WinSock and the Posix API uses the `bind()` call for that, even their parametrization is practically the same. Even if an API doesn't have this call, *somehow you need to say it, from where do you want to read the incoming bytes*. – peterh Feb 11 '19 at 18:11
  • 1
    @user207421 Of course 100k or more TCP connections can be handled with the same ports, `listen()`/`accept()` API calls can create the sockets on a way that the kernel will differentiate them by their incoming ports. The question of the OP can be interpreted on the way that he asks essentially for it. I think, it is quite realistic, but not this is what his question literally means. – peterh Feb 11 '19 at 18:14
0

No. It is not possible to share the same port at a particular instant. But you can make your application such a way that it will make the port access at different instant.

SAKEER T
  • 9
  • 2
-1

Absolutely not, when multiple connections may shave same ports but they must have different IP addresses

Supergamer
  • 411
  • 4
  • 13
-1

No, two different connected sockets cannot share the same port number. In the TCP/IP protocol stack, a socket is identified by a unique combination of an IP address and a port number. Therefore, it is possible for two sockets to bind to the same port number on the same host if they are using different IP addresses.

  • 1
    Everything you said is incorrect. Two sockets CAN share the same *local* IP/Port as long as they are connected to a different *remote* IP/Port. A TCP connection (not a socket) is identified by a unique combination of Protocol, local IP/Port, and remote IP/Port. For instance, 2 clients can `bind()` to the same local IP/Port (using `SO_REUSEADDR`/`SO_REUSEPORT` if needed) and then `connect()` to different servers. – Remy Lebeau May 11 '23 at 20:42