PORTS

For example port 80 is the port for web services. When multiple clients access the port: Answer: The port number doesn't change: Implementation On POSIX systems a Socket is a file descriptor. The server creates a Socket using the Socket() system call (which returns a Socket file descriptor) and configures it with the bind() system call.

Then listen() tells the kernel to start accepting connections.

This Socket is configured with the local address and port number, but the remote address and port number are all zeros. (Actually the local address can be all zeros too, in which case the Socket listens on all interfaces.)

When a Server Process calls accept() to handle an incoming connection the kernel creates a new file descriptor (Socket) for the connection. Whereas the remote host/port is always all zeros on the listening Socket this will be filled in with the actual values for the remote host in the Socket returned by accept(). The local port will be the same as the listening Socket and the local address will be the actual address the incoming connection was addressed to. (If it was non-zero on the listening Socket then it will be the same here.)

The kernel really doesn't care whether the process forks or not. It's perfectly valid for there to be hundreds of Sockets in one process. (up to whatever limit the kernel places on the max number of file descriptors allowed per process)

The simplest way to write a Server is to call accept() and fork() but most real Servers don't actually do this. (Why? becasue creating/destroying processes is expensive, after all, there are context switches.)

Servers tend to create their listening Socket, then call poll() or select() or similar to wait for activity on all their file descriptors (including the Socket) and only call accept() when there's an incoming connection. Then depending on the way the server is structured and what kinds of requests it's handling it might fork off a process or pass the Socket off to a thread in the same process or just stick the file descriptor for the new Socket onto the list of file descriptors it's watching with poll()/select().

Finally, the table of interest in the kernel is the table of file descriptors. Most file descriptors will point at files on disk but some do other things, such as describing Sockets. The ones that describe Sockets will have a protocol (udp/tcp/whatever), an address family (normally inet (IPv4) or inet6 (IPv6)), the remote address, the remote port number, the local address, and local port number. (For TCP there will of course also be extra stuff like the window size, sequence number, and the connection state, e.g., LISTEN, ESTABLISHED, FIN_WAIT, etc.)

You can use netstat to look at all the Sockets on the system. (In the old days you could also look at the entire file descriptor table using lsof, but these days it only shows you the file descriptors that you own.)

For example, run

netstat -na | grep :443 
on our web server, kay.cs.hmc.edu. (You could use ":80" but most of the time there aren't many connections on port 80; everything uses https these days which is port 443.) You'll see:

one listening Socket (TCP state LISTEN) with local address ":::443" and remote address ":::*".

This is the Socket that Apache made with Socket(), configured with bind(), and called listen() on. It's configured to listen on all interfaces (represented by local address :: (IPv6 shorthand for 0000:0000:0000:0000:0000:0000:0000:0000) on port 443. The ":::*" for the remote address means there's nothing connected on this port because it's a listening Socket, not a Socket returned by accept().

You will also see a ton of entries in other states, e.g., ESTABLISHED or SYN_RECV or TIME_WAIT. These will have the local address filled in, usually 134.173.42.2, because most connections come in over IPv4, but some will be on Kay's various IPv6 addresses (although netstat will truncate IPv6 addresses unless you give it the -W flag). The local port number is still 443. The remote port number is chosen by the machine on the other end and is typically in the dynamic port range (49152-65535) but some versions of Windows use lower numbers.

They are all listed as "tcp6" because Apache is configured to listen only on IPv6, but it sets a Socket option that says "go ahead and accept IPv4 connections too" - those get mapped to a small chunk of the IPv6 address space that is reserved for representing IPv4 addresses. netstat recognizes those special addresses and displays them as the equivalent IPv4 address for convenience

Mike Erlinger

Last Modified Friday, 26-Oct-2018 10:30:43 PDT