Computer Networks I - Undergraduate

Client-Server Model

A server is a process that is waiting to be contacted by a client process so that the server can do something for the client. A typical (but not mandatory) scenario is as follows:

We can further divide the server processes into two types.

  1. When a client request can be handled by the server in a known, short amount of time, the server process handles the request itself. We call these iterative servers. A time-of-day service is typically handled in an iterative fashion by the server.
  2. When the amount of time to service a rquest depends on the request itself (so that the server doesn't know ahead of time how much effort it takes to handle each request), the server typically handles it in a consurrent fashion. These are called concurrent servers. A concurrent server invokes another process to handle each client request, so that the original server process can go back to sleep, waiting for the next client request. Naturally, this type of server requires an operating system that allows multiple processes to run at the same time.

Connections and Associations

We use the term connection to define the communication link between two processes. The term association is used for the 5-tuple that completely specifies the two processes that make up a connection:

{protocol, local-address, local-process, remote-address, remote-process}

The local-address and the remote-address specify the network and host IP addresses. The local-process and foreign-process identify the specific processes on each system that are involved in the connection. In TCP/IP, an example could be:

{tcp, 192.43.65.160, 1250, 192.61.66.25, 23}

Here, the protocol is TCP, the local IP address is 192.43.65.160, the local-process is 1500 (port #), the remote IP address is 192.61.66.25 and the remote-process is 23 (port #).

Elementary Socket System Calls

socket System Call

To do network I/O, a process must first call the socket system call, specifying the type of communication protocol desired (TCP, UDP). The socket system call returns a small integer value, similar to a file descriptor. This is the socket descriptor. In the 5-tuple association described above, the socket system call just specifies the first element, the protocol. Before the socket descriptor is of any real use, the remaining four elements of the association must be specified. What the process would do next depends on whether the server is connection-oriented (uses TCP at the transport-layer) or connectionless (uses UDP at the transport-layer).

bind System Call

The bind system call assigns a name to an unnamed socket. Basically, bind fills in the local-address and local-process elements of the 5-tuple association. There are three uses of bind.

  1. Servers register their well-known address with the system. It tells the system "this is my address and any messages received for this address are to be given to me". Both connection-oriented and connectionless servers need to do this before accepting client requests.
  2. A client can register a specific address for itself.
  3. A connectionless client needs to assure that the system assigns it some unique address, so that the other end (the server) has a valid return address to send its responses to. This corresponds to making certain an envelope has a valid return address, if we expect to get a reply from the person we send the letter to.

connect System Call

A client process connects a socket descriptor following the socket system call to establish a connection.

For most connection-oriented protocols (TCP being one example), the connect system call results in the actual establishment of a connection between the local system and the foreign system. Messages are typically exchanged between the two systems and specific parameters relating to the conversation might be agreed on (buffer sizes, amount of data to exchange between acknowledgements, etc.). In these cases the connect system call does not return until the connection is established, or an error is returned to the process.

The client does not have to bind a local address before calling connect. The connection typically causes these four elements of the association 5-tuple to be assigned: local address, local-process, remote-address, remote-process.

listen System Call

This system call is used by a connection-oriented server to indicate that it is willing to received connections. listen is executed after both socket and bind system calls.

accept System Call

After a connection-oriented server executes the listen system call, an actual connection from some client process is waited for by having the server execute the accept system call. accept takes the first connection request on the queue and creates another socket with the same properties as the initial socket. If there are no connection requests pending, this call blocks the caller until one arrives. The typical scenario is as follows:

int sockfd, newsockfd;
if ((sockfd = socket(...)) < 0)
	error_handle("socket error");
if (bind(sockfd, ...) < 0)
	error_handle("bind error");
if (listen(sockfd, ...) < 0)
	error_handle("listen error);
for ( ; ; ) {
	newsockfd=accept(sockfd, ...);	/* blocks */
	if (newsockfd < 0)
		error_handle("accept error");
	if (fork() == 0) {
		close(sockfd);		/* child */
		doit(newsockfd);	/* process the request */
		exit(0);
	}
	close(newsockfd);		/* parent */
}

When a connection request is received and accepted, the process forks, with the child process serving the connection and the parent waiting for another connection request. All five elements of the 5-tuple associated with newsockfd have been filled in on return from accept.

send, recv System Calls

These system calls are similar to the standard read and write system calls, but additional arguments are required.

close System Call

The normal Unix close system call is also used to close a socket.