%font declarations
%
\font\normalfont=cmr12
\font\bold=cmbx12
\font\ital=cmsl12
\font\copyrightfont=cmfib8      %
\font\headfont=cmcsc10          %used for page headers
\font\headnumbfont=cmbx12       %used for numbers in page headers
\font\footfont=cmr8             %
\font\referencefont=cmti12      %used for book and journal titles in footnotes
\font\chaptitlefont=cmss17      %
\font\afont=cmr12               %
\font\bfont=cmbx12              %
\font\cfont=cmbx12              %
\font\programfont=cmtt12        %
\font\pf=cmtt12                 %
\font\problemfont=cmbx12        %
\font\mathfont=cmmi12
\global\textfont0=\normalfont
\global\textfont1=\mathfont

\def\uncatcodespecials{\def\do##1{\catcode`##1=12 }\dospecials}
\def\setupverbatim{\programfont
        \def\par{\leavevmode\endgraf} %\catcode`\`=\active
        \obeylines
        \uncatcodespecials
        \obeyspaces
}   
{\obeyspaces\global\let =\ }   

        
%\input /users/walker/setup.standard
\def\inputprogram#1{
        \bigskip
        \hrule width5.5truein
        \bigskip
        \hsize=7.0truein
        \leftskip=-0.5truein

        \begingroup\setupverbatim
        \input #1 
        \endgroup

        \leftskip=0.0truein
        \hsize = 6.5truein
        \bigskip
        \hrule width5.5truein
        \bigskip}

% This defines the date.
%
\def\today{\ifcase\month\or
  January\or February\or March\or April\or May\or June\or
  July\or August\or September\or October\or November\or December\fi
  \space\number\day, \number\year}
%\def\today{March 7, 1999}

% Program Macros
%
\newcount\programcounter
\programcounter=0

\newcount\firstprogrampage
\firstprogrampage=1     %0 = not first page of program
                        %1 = new sample program starts on current page
\def\programname {}

%  Definition of program
\def\newprogram#1#2{

%  #1 = program/file name
%  #2 = initial commentary

\global\firstprogrampage = 1

\vfill\eject

\advance \programcounter by 1
\noindent
{\bold Program \number\programcounter:  #1}
\gdef\programname{#1}
\global\firstprogrampage = 0

\noindent
#2

{\parskip = 0pt

\inputprogram{#1}

}
}

%  Definition of code segment
\def\newcode#1#2{

%  #1 = program/file name
%  #2 = initial commentary

\global\firstprogrampage = 1

\vfill\eject

\advance \programcounter by 1
\noindent
{\bold Code Segment \number\programcounter:  #1}
\gdef\programname{#1}
\global\firstprogrampage = 0

\noindent
#2

{\parskip = 0pt

\inputprogram{#1}

}
}

%  Annotation Header
\def\ann{

\noindent
{\ital Annotations for {\programfont \programname}:}

}

\def\i{\item{$\bullet$}}
\def\ii#1{{\parskip = 0pt
\itemitem{$\S$} #1

}}

%  Sample run
\def\samplerun#1{

\goodbreak
\noindent
{\ital Sample Run of {\programfont \programname}:}

{\parskip = 0pt

\inputprogram {#1}

}}


%Header Declaration
%
\headline = {\ifnum\programcounter>0 
      \ifnum\firstprogrampage=1
           \rm Sample Program \number\programcounter: 
                 \programname, continued \hfil
      \else\hfil\fi
\else\hfil\fi}

% Footer Declaration
%
\footline = {{\hsize=6.5truein \leftskip = 0pt \rightskip = 0pt
\footfont Sockets in C \hfil
                \today \hfil
                Page \number\pageno}}

%----------------------------------------------------------------------------
\parindent = 20pt
\parskip = 6pt
\normalfont
%Define Page Parameters
%
\raggedbottom
\interlinepenalty=1000
\hsize=6.5truein        %use 7.0truein for fuller page
\vsize=9.5truein
\voffset = 0.0truein

\ 

\vfill
\centerline {\chaptitlefont An Introduction to Sockets in C}
\bigskip
\centerline {\chaptitlefont Through Annotated Examples}
\bigskip
\bigskip
\centerline {\bold by}
\medskip
\centerline {\bold Peter M. Broadwell}
\medskip
\centerline {\bold Grinnell College, Grinnell, IA}
\vfill

\centerline {With minor adjustments for Linux compatibility}
\medskip
\centerline {made November 29, 2000 by Henry M. Walker}

\vfill
\centerline {\rm \copyright 1999, 2000 by Peter M. Broadwell}


\noindent
{\rm
Permission to make digital or hard copies of all or part of this work for
personal or classroom use is granted without fee provided that copies are
not made or distributed for profit or commercial advantage and that copies
bear this notice.

\noindent
Use of all or part of this work for other purposes is prohibited.

}

%-----------------------------------------------------------------------------

\bigskip
\bigskip
\bigskip
\bigskip
\bigskip
\bigskip
\bigskip
\bigskip
\bigskip
\bigskip
\bigskip
\bigskip
\bigskip
\bigskip
\bigskip
\bigskip
\bigskip
\bigskip
\bigskip
\bigskip
\bigskip
\bigskip
\bigskip
\bigskip
\bigskip
\bigskip
\bigskip
\bigskip
\bigskip
\bigskip
\bigskip
\bigskip
\bigskip
\bigskip
\bigskip
\bigskip
\bigskip
\bigskip
\bigskip
\bigskip
\bigskip
\bigskip
\bigskip

{\bold An Overview of Sockets in C:}

\i A socket is a type of application programming interface. As such, a socket
is a software device that allows processes to communicate with one another
over the Internet, within local area networks, or even on single computers.
Sockets provide the programmer with a flexible communications interface
that allows the reliable transfer of large amounts of data between processes.
It is because sockets possess these important capabilities that they are in
wide use as software communications tools today.

\i The aim of this pamphlet is to provide an introduction to the use of
sockets in the C programming language. Because programmers currently use
sockets in a wide variety of capacities, several volumes would be necessary to
catalog and explain all of the capabilities of sockets. This pamphlet seeks
to introduce the basic properties and concepts behind the most
commonly-used varieties of sockets. It does this by presenting a series of
example programs, each highlighting an application of sockets, and then
providing detailed annotations on the manner in which these programs
function.

\i Because the primary purpose of sockets is to promote data transfer, the
introductory sample programs all deal with the computing scenario known as
the readers-writers problem. In this problem, one or more writer processes
write data to a central buffer in such a way that one or more reader
processes may then access this buffer and retrieve the writers' data from
it. As the sample programs will demonstrate, a socket functions as an ideal
read-write buffer. As the sample programs will also show, the varied
capabilities and communications protocols supported by sockets naturally
lead to certain insightful alterations of the readers-writers problem.

\i In socket terminology, one of the communicating processes is called the
{\bold server} and the other the {\bold client}. The server has greater control
over the communications process because it is the process that initially
creates the socket. Because of this, numerous clients may communicate
through the same socket, but only one server may be associated with a
particular socket.

\i Whle examining the sample problems to come, one must make a couple of
distinctions regarding the properties of sockets. One such distinction is
that of the socket {\bold family}. In general, the family to which a socket
belongs determines the hardware environments in which it is used. Of the two
families in the upcoming examples, sockets of the family {\pf AF\_UNIX} exist
as files in a directory of a local host computer, and only provide
data transfer between processes on that machine. For this reason, they are
referred to as UNIX domain sockets.

\i Sockets of the second family presented in this text, {\pf AF\_INET}, are
less efficient than UNIX domain sockets, but allow communication between
processes on remote machines that are connected by a local network or by
the Internet. As such, they are called Internet sockets.

\i The other distinction one must make inolves the socket's {\bold
type}. The type of a socket describes the communications protocol it uses
to send data. The first socket type to be used in the examples is the
{\pf SOCK\_STREAM} (streaming socket) type. Processes that communicate through
sockets of this type must connect explicity to a socket, and the data
transfer from the client to the server (or vice versa) takes place through
a reliable byte stream. This type of data transfer is called TCP 
(Transmission Control Protocol).

\i The second type of socket is a {\pf SOCK\_DGRAM} (datagram) socket. These
sockets allow data to be transferred in finite packages, called datagrams.
Because of this, processes do not have to be connected explicitly to the
socket in order to send and receive data through it. As later examples
will demonstrate, the simplicity of this type of data transfer (called UDP, 
for User Datagram Protocol) carries with it a degree of unreliability.

\i The following examples introduce these varied concepts in a
sequential, logical progression, from basic applications to more complicated 
procedures. Streaming UNIX domain sockets are presented in the first
examples ({\pf streaming1.c} and {\pf streaming2.c}) because their
declaration proves insightful and because communicating through them is
fairly straightforward, . The next two programs, {\pf netserv.c} and {\pf
netclient.c}, form a single example. In this scenario, the instructions
for the client and server processes have been broken up into two separate
programs in order to illustrate the capability of Internet sockets to allow 
processes on separate machines to communicate with one another.

\i The second group of examples involves datagram sockets. Unlike streaming
sockets, which can belong to either the UNIX domain or Internet family,
sockets of the type {\pf SOCK\_DGRAM} must always be Internet sockets. {\pf
datagram1.c} and {\pf datagram3.c} illustrate, respectively, simple and
complex applications of this protocol. {\pf datagram2} uses a script file to 
execute one server process locally and several client processes remotely to 
demonstrate an application of sockets to parallel computing.

%-----------------------------------------------------------------------------

\newprogram {streaming1.c}
{This first example program demonstrates the connection and data transfer
protocols associated with streaming sockets.}

\ann

\i In this example, the {\pf fork} function creates the client
process. Both the client (child) and server (parent) processes set up the
socket file and address descriptors they will need to communicate through a
streaming UNIX domain socket. While these structures could be
defined globally, in practice the client and server processes are
usually completely separate programs. Thus, each must set up the
appropriate communications structures on its own.

\i The client and the server communicate with each other through a UNIX
domain socket in much the same way that two processes may communicate
with each other through the use of the {\programfont pipe} function. As in
all socket interactions, the server creates the communication socket.
Following the streaming socket protocol, the client then connects
to this socket. Once the server has accepted this connection, the two
processes can send messages to each other through the socket.

\i Sockets of the family used in this program (AF\_UNIX), exist as files
in a user-defined path of the file system. With the line
\hfil\break
{\programfont ~~~~~\#define SOCKET-NAME "Com1"}
\hfil\break
the constant {\programfont SOCKET\_NAME} is set as the name of the file
{\pf Com1}. Once the server process creates the socket, it exists in the local
directory as this file. At the end of the program, this file is deleted.
If one were to use the {\pf ls} command to check the contents of the
directory containing {\pf read-write1} during its execution, a file with the
name {\pf Com1} would be visible. By typing {\pf netstat} at the command
prompt, one can also see under the section heading "Active UNIX domain
sockets" all of the AF\_UNIX sockets running on the current host machine
(including {\pf Com1}, if {\pf read-write1} is currently executing.)

\i Examining the {\pf main} function, one sees that the first action of
both the server and client processes is to define the socket file
descriptor and address structure. The {\pf socket} function creates a file
descriptor (named {\pf sock}), of the type {\pf SOCK\_STREAM}. Both the
client and the server use this file descriptor to refer to the socket in
the following functions.

\i The second half of the socket initialization procedure involves setting
the socket's physical address. This is stored in the {\pf cli\_name} and {\pf
serv\_name} data structures for the client and server, respectively. The
{\pf bzero} function initializes this data structure (of the type {\pf
sockaddr\_un}, for UNIX socket address) to all 0's. The next two functions
set the family of the socket ({\pf AF\_UNIX}, in this case) and the address
of the socket in the file system ({\pf Com1} in the local directory).

\i The client's next action is crucial. It invokes the {\pf sleep} function 
in order to ensure that the server has created the socket before it
attempts to connect to it. In most applications, the server process is
running all of the time, so this is not necessary. Here, though, it's
important, so that that the client process does not receive an error when
it attempts to connect to the server.

\i While the client sleeps, the server creates the socket. Up to this
point, the socket has existed only as data structures maintained by the
client and server. With the {\pf bind} function, the server binds the file
descriptor, {\pf sock}, for the socket to the defined socket address
structure, {\pf serv\_name}. Essentially, this call requires the kernel to
assign an address to the socket described by {\pf sock} and {\pf
serv\_name}. Once this has happened, both the server and the client can
access the socket, since they both know its file descriptor and address.

\i Once the server has created the socket, the client may connect to
it. With streaming sockets, this connection is accomplished through a
{\ital three-way handshake}. This handshake begins when the server invokes 
the {\pf listen} function to detect when the client attempts to connect to
{\pf sock}. The integer parameter of this function indicates the number of
connections the server is expecting (in this case, only 1). When it calls the 
{\pf listen} function, the server then sleeps until it detects such a
connection. With the {\pf connect} function, the client attempts to connect
to the socket. At this point, the server wakes up and invokes the the
{\pf accept} function. As its name implies, this function accepts the client's
connection requests, completing the handshake.

\i For the client, the following communication takes place through the
usual {\pf sock} file descriptor. For the server, though, the {\pf listen}
function has changed {\pf sock} into a {\ital listening socket}. The {\pf
accept} function creates a new socket file descriptor, {\pf
connect\_sock}. For the server, this is a {\ital connected socket}; that
is, a socket through which the server may communicate with a client. Thus,
the server completes the following communications through this descriptor.

\i Transferring data to and from sockets of this type (SOCK\_STREAM) is
accomplished through the use of simple {\pf read} and {\pf write}
functions. The server uses the {\pf read} function to send integers to
the socket, and the client uses the {\pf read} functions to receive these 
integers from the socket when they arrive.

\i After the processes have communicated with one another, the client
closes its socket descriptor and exits. After the client terminates, the
server closes its connected socket descriptor and then calls the 
{\pf clean\_up} function. This function closes the server's {\pf sock} file 
descriptor and then removes the actual socket file {\pf (Com1)} from the
local directory before exiting.

\i A sample run of {\pf streaming1.c} Note that like {\pf listen}, {\pf
connect}, and {\pf accept}, {\pf read} is a blocking system call. Unless
an external timeout value is declared, the client may wait indefinitely
for data to arrive at the socket if the programmer does not coordinate the
data transfer between the processes correctly.

\samplerun {streaming1.out}

%-----------------------------------------------------------------------------
\newprogram {streaming2.c}
{This is a simulation of the next level of complexity of the
readers-writers problem. In this program, multiple readers (clients)
communicate with the writer (server). This program illustrates an important 
property of server using streaming sockets: the explicit connection that is 
required between the server and the client makes it possible for the server 
to fork child processes to handle each of the connection requests recursively.}

\ann

\i This program introduces an important concept of streaming socket
servers, but little new syntax. Each process (the server and all of the 
clients) once again sets up a socket file descriptor {\pf sock} and its
corresponding address structure, {\pf serv\_name} or {\pf cli\_name}. The
server then creates the actual socket file, {\pf "Com2"} this time, with
the {\pf bind} function.

\i Each client is a child process created with the {\pf fork} function.
The extra code at the beginning of the client section allows the client
determine randomly the number of integers it wants to read from the
server. This is accomlished by seeding the random number generator with the 
current system time, and then generating a random integer between 1 and 10.
The communications setup for each client is the same as in the
previous example. In terms of actual data transfer, the only difference is
that the client first sends to the server the number of integers it expects 
to read (not an uncommon situation in client-server interactions) and then
reads this number of integers from the socket.

\i The major conceptual difference in this program involves the server
operation. If a server utilizes streaming sockets, it is necessary for the
server to connect explicitly (through the {\pf listen} and {\pf accept} 
commands) to each of its clients. The most common and most efficient way of
doing this is for the server to fork a child process to handle each connection
request. In this manner, each server child {\pf accept}s a connection
request from a client and writes the requested data to it.

\i Note that each server child process, after creating a connected socket
descriptor with {\pf accept}, immediately closes {\pf sock}. This is
because the {\pf listen} command has changed {\pf sock} into a listening
socket for the server, and only the parent server process needs to listen
for more connections. Other than this, the data transfer for the server
child process is relatively straightforward.

\i One may also note that if in some other situation it is important for
the server to deal with the clients on an individual basis, it may 
communicate with them iteratively (one at a time). One may accomplish this
by removing the {\pf fork} functions from the server's {\pf for} loop and
establishing an array of connected socket descriptors, one for each client
(for example, {\pf connect\_sock[0]}, {\pf connect\_sock[1]}, etc.).

\i This scenario is something of a departure from the standard
readers-writers problem. In this case, what first appears to be a single 
writer quickly becomes multiple writers, and each writer communicates
explicitly with one reader. This makes the simulation a somewhat more
conversation-oriented scenario of the readers-writers problem than usual.
The upcoming examples of datagram socket communications will produce a
multiple readers-multiple writers situation that is closer to the
traditional setup.

\i A sample run of {\pf streaming2.c}. Note that due to the
nondeterministic nature of process execution order in UNIX, a different
output order will likely result from each run of the program. Also, because 
of similar issues involving the display buffer, it is common for the
output to report that a client has read data before the server has sent
it. This is not actually what has happened, of course, but it does
illustrate the unpredictable nature of output order when multiple process
interact with one another.

\samplerun {streaming2.out}

%----------------------------------------------------------------------------

\newprogram {netserv.c}
{This is the first (server) program in a set of two separate programs that
can be run on different machines to demonstrate the capabilities of streaming
Internet (AF\_INET) sockets.}

\ann

\i The family of sockets that we have studied until now, AF\_UNIX,
is used to provide high-speed full-duplex communication between processes
on a single host computer. However, these sockets are not designed
to function as API's when the client and server are on separate hosts.
Internet sockets (sockets in the family AF\_INET) are used to facilitate
this type of communication. While slower than UNIX domain sockets, AF\_INET
sockets are used extensively as the communications protocol of the Internet.

\i As can be observed from this program, much of the communications syntax
for Internet sockets is similar to that of UNIX domain sockets. A few
differences exist, though. Note that {\pf serv\_addr} is declared as a
{\pf sockaddr\_in} instead of a {\pf sockaddr\_un} data structure. Also note
the change in the socket family setting ({\pf AF\_INET} instead of {\pf
AF\_UNIX}) in the definition of the {\pf sock} descriptor.

\i The most important difference to note is within the setup of the
{\pf serv\_name} data structure. The first two lines are fairly
self-explanatory. Understanding the final line, however, requires some
background knowledge of Internet communications protocols.

\i In order for a process to communicate with a process on another machine, it 
must know the Internet Protocol (IP) address of the host machine (such as
132.161.33.155). In addition, both processes must reocrd the numeric port
number on which the process that will act as the server expects
connections. The final line of the definition of {\pf serv\_name}
establishes this. Port addresses below 1024 are reserved for superuser
activites, so any value from 1024 to 49151 is acceptible. In most
applications, an Internet server will have a {\ital well-known port}, a
default port value to which client processes try to connect first.

\i Also note that {\pf netserv.c} does not deal at all with the server's IP 
address, since it is the server and must only wait for the remote client to 
contact it.

\i Once {\pf serv\_name} is declared, the rest of the program runs
identically to the earlier examples using {\pf AF\_UNIX} sockets.

\samplerun {netserv.out}

\newprogram {netclient.c}
{This is the client portion of the internet socket demonstration.}

\ann

\i This program also functions quite similarly to its UNIX domain socket
counterpart. Once again, the only major difference is within the definition 
of the socket address structure (which is {\pf cli\_name}, this time).

\i The first two lines of the definition of {\pf cli\_name} are again
self-explanatory. The third line is the line at which the client records
the IP address of the intended server (the dotted decimal string). The
client MUST know this address ahead of time. On the HP network, the
easiest method of finding the address of the intended host machine is to
use the {\pf traceroute} command. Simply type {\pf traceroute (name of host
computer)} at a command prompt. This displays the network name of the host
with its IP address in parentheses.
The final line of {\pf cli\_name}'s declaration sets the port address of the
remote host at which it will connect to the server process. This must also
be idential to the setting for the server.

\i Note that {\pf netserv.c} is not being run on the same host machine as
{\pf netclient.c}. Due to the nature of Internet sockets, the two processes 
could be run on the same machine (in which case it would not be necessary
for the client to define the server's IP address), two different machines
on the same local area network (as in this example) or even on two machines 
on opposite sides of the world, assuming they are both connected to the
Internet.

\i By now, one has undoubtedly noticed the large amount of syntax that some 
socket functions require. In particular, nearly every socket function
requires that it be given the size of the socket address structure. {\pf
accept}, for example, requires that it be passed a pointer to the size of 
the socket address structure, and thus the size variable {\pf len} must be
declared ahead of time. In many cases, it is sufficient to give the
function a null pointer to the socket address structure, which takes the form
{\pf (struct sockaddr *)\&serv\_name}.

\i Following a run of {\pf netserv.c} and {\pf netclient.c}, typing {\pf
netstat} at the comand prompt of either machine (the client or server) will 
reveal one or two socket entries under "Active Internet connections"
with the server's port number at the end of the "Local address" or
"Foreign Address" field. The state of these sockets will be listed at
{\pf TIME\_WAIT}. The socket exists in this state for approximately 30
seconds after it has been closed by the server in case a data packet that
encountered network difficulty is late in arriving at the client. For this
reason, it is also not possible to run {\pf netserv.c} again until this
socket has expired, because the port is technically still in use.

\samplerun {netclient.out}

%----------------------------------------------------------------------------

\newprogram {datagram1.c}
{This program is the first program in a series that demonstrates the
capabilities of datagram ({\pf SOCK\_DGRAM}) sockets and the protocol that
accompanies their use. In this initial example, one notes that a client
does not have to connect explicitly to the server through a socket in order 
to read from the socket, but that it must first have a greeting read
from the datagram socket before it may commence reading.}

\ann

\i The declaration of datagram sockets is almost identical to that of
streaming Internet sockets, with the only difference existing in the setup
of {\pf sock}. The transfer protocol for datagram sockets, however, is
quite different from that of streaming sockets.

\i As before, the client must sleep while the server binds the socket. Once 
this is done, though, the client may immediately send data to the socket,
without conducting any sort of three-way handshake. Because the socket is
in an unconnected state, though, the client must use the {\pf sendto}
function instead of the {\pf write} function to do this. In addition to the 
socket file descriptor, a pointer to the message to be sent and the message 
length, {\pf sendto} also requires that it be sent any applicable flags
(there are none in this case, so the value is 0), a null pointer to the
socket address structure, and the size of the socket address structure.

\i In this example, the client sends a greeting string to the
server. Before the client may read any data from the socket, the server
must read this greeting from the socket. The next example will show that
this requirement becomes very important when a server must deal with multiple
client (reader) processes. For now, it suffices to say that until the
server reads this initial greeting string, the client has no way of knowing
that the socket to which it has just written actually exists.

\i When reading and writing to the socket, the server must also use
different functions than before. To read the client's greeting string, it
uses the {\pf recvfrom} function. This function is similar to the {\pf
sendto} function, except that it requires a pointer to the size of the
socket address structure instead of the actual size. Also, one may find the 
{\pf MSG\_PEEK} flag useful in many applications, because it allows the
calling process to read the next item in the socket without removing it
from the queue.

\i Once the server has read the client's greeting, the integer transfer
occurs as it has in earlier applications, with {\pf sendto} replacing {\pf
write} and {\pf recvfrom} replacing {\pf read}.

\samplerun {datagram1.out}

%----------------------------------------------------------------------------

\newprogram {dgserv.c}
{This is the server portion of a demonstration that uses a shell script to
execute an iterative datagram server process locally and multiple client
processes remotely.}

\ann

\i The difference to note in the processing of this datagram server is 
the manner in which it deals with multiple clients. Unlike a streaming
socket server, this datagram server does not fork itself and deal
recursively with each client process. Because clients do no explicitly
connect to servers through datagram sockets, the server instead deals
iteratively with each client.

\i In the previous example, one noted that a client must have a greeting mesage
read by the server in order to receive data from the socket. In this
scenario, the server uses this requirement to coordinate its interactions
with the client processes. It deals with each client one at a time by
reading a single client's greeting and then writing the requisite number of
integers to the socket. Because only one client is able to read from the
socket (the client whose greeting the server has just read), it will read
these integers and then exit, allowing the server to deal with the next
client in line (that is, the next client with a greeting in the socket.)

\newprogram {dgclient.c}
{This is the client portion of a demonstration that uses a shell script to
execute an iterative datagram server process locally and multiple client
processes remotely.}

\ann

\i The communications processing for this client is nearly identical to the
actions of the client process in {\pf datagram1.c}. That segment of code
code has simply been isolated into its own program so that it may be run on
several remote machines by a shell script. The only notable differnce
between this client and the previous one is that this program takes the IP
address of the intended server as a command-line argument.

\i One should note that although the unreliability of the datagram protocol 
has not shown itself in this or the previous examples, it nonetheless
exists. In streaming socket communications, a continuous byte stream runs
back and forth between the client and the server, confirming the success or 
failure of each {\pf read} or {\pf write} operation. The extremely reliable 
nature of this communication has made TCP the standard communications
protocol of many Internet applications, including SMTP (e-mail), FTP, and
HTTP. The User Datagram Protocol layer, on the other hand, sends data in
fixed-size datagrams, without any full-duplex byte stream to confirm
whether or not the datagram reached its destination. If a datagram fails to 
reach its destination (due to network blockage or interference), the
receiving application will often fail to notice this if it is in the midst of
receiveing a large amount of data. This lack of {\ital flow control}
makes datagram sockets unsuitable for some communications applications.

\i The inherent flexibility of datagram sockets that we have seen and will
see even more in the next example makes them ideal for other
applications, however. UDP is the standard transport layer for SNMP
(network management) and other applications that require communication
through sockets that are not explicitly connected.

\newprogram {datagram2}
{This is the shell script that executes a datagram server locally and then 
executes multiple client processes on remote machines.}

\ann

\i The command line syntax for executing processes on other machines is
simple. One needs only to include the name of the remote machine before
the name of the program to be run in order to do this. Note that the
clients are all given the IP address of the server computer as a
command-line argument. As mentioned before, most clients by default try
the well-known port of an Internet server first, so it is not necessary
that the port number also be included as a command-line parameter. This
value still must be specified within the code for the client, though.

\i The ampersand after each procedure call signifies that the procedure in
question will be run as an {\ital attached job} on the remote host. This 
means that the remote computer will take over all execution of the process, 
allowing it to be run in true parallel with the jobs called on other
machines.

\i Since the output for the remotely-run clients must return to the server
computer to be expressed at the terminal window, large disrepancies may
occasionally arise in the order of the output.

\samplerun {datagram2.out}
 
%----------------------------------------------------------------------------

\newprogram {datagram3.c}
{This third datagram sockets example program simulates a true multiple
readers-multiple writers problem. The overall server process creates two
sockets, one into which the writer clients write and one from which the
reader clients read. Due to this setup, the server acts as the manager of
the central buffer, transfering data from the write socket to the read socket.}

\ann

\i From the structure of this program, one can observe that while it is
possible for several processes to write to a socket at the same time, it is 
not possible for several proesses to read from a socket at once. The
overall server process in this simulation thus creates two sockets, one to
which all of the writer client processes will write, and one from which the 
reader processes will read.

\i It is possible for the server to read from the write socket while the
writers are writing to it, and that is exactly what it does. The server
reads the written integers from the write socket one at a time, alters them
slightly (as is often the case in client-client data transfer) and then
deposits them in the read socket.

\i The server deals with the reader processes iteratively, as in the
previous example. It reads a reader client's greeting from the read socket, 
and then writes the required number of integers to this socket. The reader
in question immediately reads these integers and then exits, at which point 
the server repeats the procedure.

\i Note that this sort of flexibility, especially in allowing the writers
to write to their socket at once while the server reads from it, would be
difficult to accomplish with streaming sockets. This problem thus
illustrates an advantage of datagram sockets.

\samplerun {datagram3.out}

\end


