For client/server transactions to take place, a client process on machine A needs a way to contact its corresponding server process on machine B.
The machine's IP address
is insufficient, because many server processes may be running on machine B.
Thus, the transport layer
(TCP and UDP) provides an additional level of addressing, called port numbers
TCP and UDP both have a 16-bit range of port numbers (so that, for example, TCP port 50 and UDP port 50 are different).
- IP address: Server or Host address. Usually represented in dotted decimal notation, eg., 255.255.0.0.
- Transport layer: Provides communication sessions between computers.
Each end of a network connection using TCP or UDP has an associated port number. TCP/IP rules say that a connection between machine A and machine B is uniquely identified by four numbers together:
- Machine A's IP address
- The port number used on machine A
- Machine B's IP address
- The port number used on machine B
Two connections are considered different if any ONE of these four numbers differ. For example, many connections may use port 23 on machine B
and port 23 on other machines, because the IP addresses of those other machines will be different from that of machine B.
A server program has to provide its identity to the client programs by way of listening on a specific port. Port is a unique number that identifies a connection or specific services on a given host. When we say identifying specific connection on specific port it means that the server application needs to register its service with the kernel by way of port number. When we request a kernel to register our service, a unique port number is provided by server application to the kernel to associate its services with this number. This port number should be known to the client application so that it can send its request to the host machine running this service. Let us see what all interfaces are providing to hook its services with specific port number and register its service with the kernel.
We want to start service using TCP transport protocol. The first step is to make a socket() system call .
The socket is a framework to communicate with the network protocol within the kernel.
This call opens a socket in the kernel. The arguments to the socket call are AF_INET and SOCK_STREAM.
This means that we want to open an internet family socket of type STREAM referring to TCP.
The socket initializes INET socket and TCP protocol specific data structures and a set of operations.
It links the socket with the VFS, which is then associated with the file descriptor and returned to the application.
Now using this file descriptor, the server can request to kernel any operation on the socket.
The next step is to bind the socket with a specific port number by making the bind() system call .
This is the way we are requesting a kernel to allocate a specific port number to its service. Here comes the concept of socket address whose C equivalent is sockaddr_in .
This has two fields:
- port number and
- IP address.
If the host machine has more than one interface, an application can request a kernel to bind the socket with a given interface or with all the available interfaces. This means that application may want to accept connection requests from only one interface or from all the available interfaces. In the former case, the sin_addr field of the socket address is initialized to the specific IP address and the same field needs to be initialized to INADDR_ANY in the latter case.
Since this is INET address family, the sin_family field of the socket address is initialized to AF_INET.
The port number to which we want to glue the services is initialized.
The socket address is now ready for registration as object sockaddr_in .
The socket address is passed to bind() call. If the return value is less than zero, the socket could not be bound to the given port number because there may be any reason, including the fact that a port number may already be allocated to some other services. Otherwise, we got the port number that was requested.