Listening on an ephemeral TCP port

Nerd fun with BSD sockets

The classic TCP client/server interaction

When a TCP client calls connect(2), 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) to set the port that it will listen on.

Server socket() bind() listen() accept() recv() send() close() Client socket() connect() send() recv() close() Rendezvous get port ephemeral port range  determines  port here

Some less known fun facts

Servers that listen on random ports

While a server will usually bind(2) itself to a fixed port number, it can absolutely omit that, and then, when it calls listen(2), 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.)

Server socket() listen() accept() ... bind() not called

Clients that use a specific port number

If a client socket uses bind(2) before connect(2), the client can enforce using a specific port number for its own side.

Client socket() bind() connect() ...  binds the  client-side port

Reference

The best description I found of this is in ip(7):

An ephemeral port is allocated to a socket in the following circumstances:

So the behaviour of bind(2) 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

Comments