## The classic TCP client/server interaction

When a TCP client calls [*connect*(2)](https://man.gnoack.org/2/connect), it usually gets assigned a port number from the *ephemeral port range* which is not used yet.

The server, on the other hand, usually calls [*bind*(2)](https://man.gnoack.org/2/bind)
to set the port that it will listen on.

```pikchr
lineht = lineht*0.4
boxht = boxht*0.4
boxwid = 0.9*boxwid
gap = 1.2*boxwid
down

            text "Server"
            arrow
            box "socket()"
            arrow
SBind:      box "bind()"
            arrow
            box "listen()"
            arrow
SAccept:    box "accept()"
            arrow
SRecv:      box "recv()"
            arrow
SSend:      box "send()"
            arrow
            box "close()"

move to boxwid+gap west of first text.n
            text "Client"
            arrow
            box "socket()"
            arrow down until even with SAccept.n
CConnect:   box "connect()"
            arrow down until even with SRecv.n
CSend:      box "send()"
            arrow
CRecv:      box "recv()"
            arrow
            box "close()"

arrow from CConnect.e to SAccept.w dashed <-> "Rendezvous" above
arrow from CSend.e to SRecv.w dashed
arrow from SSend.w to CRecv.e dashed

d = 0.5*lineht
box with sw at CRecv.sw - (d,d) ht 2*boxht+lineht+2*d wid 2*boxwid+gap+2*d dotted

move to CConnect.w
arrow left 120% <- dotted "get port" above color red
ellipse "ephemeral" "port range" dotted color red

text at SBind.e " determines" ljust italic " port here" ljust italic color red
```

## Some less known fun facts

### Servers that listen on random ports

While a server will usually [*bind*(2)](https://man.gnoack.org/2/bind) itself to a fixed port number, it can absolutely omit that, and then, when it calls [*listen*(2)](https://man.gnoack.org/2/listen), **the server will get an ephemeral port assigned by the kernel** which it will then listen on.
(This is similar to setting the bound port number to 0.)

```pikchr
lineht = lineht*0.4
boxht = boxht*0.4
boxwid = 0.9*boxwid

down
text "Server"
arrow
box "socket()"
A: arrow
box "listen()"
arrow
box "accept()"
arrow
text "..."
arrow from A.e right <- color red
text "bind() not called" color red
```

### Clients that use a specific port number

If a client socket uses [*bind*(2)](https://man.gnoack.org/2/bind) before [*connect*(2)](https://man.gnoack.org/2/connect), **the client can enforce using a specific port number for its own side**.

```pikchr
lineht = lineht*0.4
boxht = boxht*0.4
boxwid = 0.9*boxwid

down
text "Client"
arrow
box "socket()"
arrow
B: box "bind()" color red
arrow
box "connect()"
arrow
text "..."

text at B.e " binds the" ljust italic " client-side port" ljust italic color red
```

## Reference

The best description I found of this is in [*ip*(7)](https://man.gnoack.org/7/ip):

> An ephemeral port is allocated to a socket in the following circumstances:
>
> * the port number in a socket address is specified as 0 when calling bind(2);
> * listen(2) is called on a stream socket that was not previously bound;
> * connect(2) was called on a socket that was not previously bound;
> * sendto(2) is called on a datagram socket that was not previously bound.
{.def}

So the behaviour of [*bind*(2)](https://man.gnoack.org/2/bind) actually works the same on both client and server sockets.  It's just in daily use where it only gets used for server sockets.

[Previous discussion on the kernel mailing lists](https://lore.kernel.org/linux-security-module/ZoKB7bl41ZOiiXmF@google.com/)