Tommy's loading dock analogy is an excellent one.
A service can listen at only one port (and yes, listen(2) is the name of the system call where a service binds to a port), and a port can have at most one service listening at it. If you want to listen on two ports (say running an HTTP server on ports 80 and 8080), then you have to start up two processes, one for each port.
Port numbers aren't reserved in any sense -- you're allowed to have a mail server listening on port 80 and a web server on port 25, but it'd be pretty confusing for everyone. But ports are associated with services in two ways:
- There are 'well-known numbers' for services (and the list is looked after by the Internet Assigned Numbers Authority). These aren't reservations as such, but they're effective 'keep-clear' markers. These numbers can also be found in the file
/etc/services on unix machines.
- A protocol such as HTTP or SMTP will typically, in its RFC, declare a default port for the protocol – for HTTP this is port 80, and for SMTP port 25. All this means is that an HTTP client, for example, will try connecting to port 80 on a remote machine, unless it's told otherwise.
At least on Unix, port numbers below 1024 are privileged, in that only processes running as root can bind to them. This isn't a restriction imposed by TCP, but a unix-specific thing (it was originally intended as a very lightweight security measure).
The upshot of all this is that if, for example, you wanted to have several web servers on a machine (or of any other service), you can, as long as you start them up whilst telling them to listen on different ports. You might do that with a command-line option when you start the service, or an entry in a configuration file.
You might have a web service on port 80 (root would have to start that), plus some other HTTP-based services on port 8080, or 9000. The first would be addressable as http://example.org/, the other as http://example.org:8080/. Because port 80 is the documented default for HTTP, your web browser (or whatever client you were using) would automatically pick port 80 in the first case.
There's no significance to those numbers 8080 and 9000, by the way – they're merely the 'traditional' unprivileged port numbers to use for alternate web services; because they're unprivileged, any non-root user can start up a service listening there, as long as there's no service there already.