
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.
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 #).
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).
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.
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.
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.
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.
These system calls are similar to the standard read and write system calls, but additional arguments are required.
The normal Unix close system call is also used to close a socket.
![]()