STORE_MANAGER is invoked first from the command line on a computer. It creates a datagram socket and binds it to a port chosen by the system. It then writes on the screen the port number associated with its socket. The client program RAND_PROC is invoked after STORE_MANAGER displays the port number assigned to its socket. Each client program is invoked from the command line with arguments specifying the host name of the computer that STORE_MANAGER is running on, the port number displayed by STORE_MANAGER, and the seed for the random number generator. Each client program may be invoked on the host running STORE_MANAGER or on a different computer.
Given this set up, the programs may be organized into two files - store_manager.c and rand_proc.c (additional header files may be used to group together data structures and operations needed in each program). Thus STORE_MANAGER may be run, say on snowhite server, by invoking
store_manager
at the command line at snowhite server. Thereafter RAND_PROC may be run, say on thunder, by invoking
rand_proc hostname portnumber seed
at the command line on thunder, where
are the arguments to the program in rand_proc.c. Other copies of RAND_PROC may be run on snowhite, thunder, or any other machine of your choice by invoking rand_proc as shown above with the appropriate arguments from the command line on that computer. The files store_manager and rand_proc contain the executable code for store_manager.c and rand_proc.c respectively.hostname : host name of the computer that STORE_MANAGER is running on, in this example, snowhite.cis.temple.edu, portnumber : the port number displayed on the screen by STORE_MANAGER, seed : seed for the random number generator
STORE_MANAGER first creates an Internet domain datagram socket. It then binds a local address to the socket, getting the system to pick a port number for it. It queries the system for the port number assigned to the socket and writes the port number on the screen. Recall that the host name of the computer that STORE_MANAGER is invoked on and the port number displayed by STORE_MANAGER are made available to RAND_PROC through command line arguments. This enables them to construct the address associated with the socket created by STORE_MANAGER. The following is an outline of the steps carried out by STORE_MANAGER in establishing a socket.
Algorithm SetUpSocketInStoreManager
begin
1. Create a datagram socket by invoking socket() as
s := socket(AF_INET,SOCK_DGRAM,0);
2. Bind local address to socket as follows :
{ sm_socket_address is assumed to be declared as a variable of type
struct sockaddr_in }
sm_socket_address.sin_family := AF_INET;
sm_socket_address.sin_addr.s_addr := INADDR_ANY;
{ The wildcard INADDR_ANY matches all valid network addresses of
the computer. }
sm_socket_address.sin_port := 0; { Let system pick port number }
Now invoke bind() as
bind(s,&sm_socket_address,sizeof(sm_socket_address));
3. Find the port number assigned by the system by invoking
getsockname() as
getsockname(s,&sm_socket_address,&length_of_address);
4. Print the host's representation of the port number,
ntohs(sm_socket_address.sin_port;
end SetUpSocketInStoreManager
Each client program also creates a datagram socket and binds an
address to it, having the system select a port number for the socket.
STORE_MANAGER gets the address of the socket in a client when
it receives a message (containing a request for a read or update
operation) from the client, and sends its response to the socket
associated with that address. The client program constructs the
address of the socket in STORE_MANAGER from the host name and the port
number arguments, and sends its messages requesting read and update
operations to this address. Algorithm SetUpSocketInRandProc
details the steps outlined above.
Algorithm SetUpSocketInRandProc
begin
1. Create a datagram socket by invoking socket() as
s := socket(AF_INET,SOCK_DGRAM,0);
2. Bind local address to socket as follows :
{ rp_socket_address is assumed to be declared as a variable of type
struct sockaddr_in }
rp_socket_address.sin_family := AF_INET;
rp_socket_address.sin_addr.s_addr := INADDR_ANY;
{ The wildcard INADDR_ANY matches all valid network addresses of
the computer. }
rp_socket_address.sin_port := 0; { Let system pick port number }
Now invoke bind() as
bind(s,&rp_socket_address,sizeof(socket_address));
4. Construct the address of the socket created by STORE_MANAGER by
assigning the appropriate values to the components of
sm_socket_address. sm_socket_address is assumed to be declared
as a variable of type struct sockaddr_in.
sm_socket_address.sin_family := AF_INET;
Get the IP address of the computer running STORE_MANAGER from the
the first command line argument :
{ assumes the declaration
struct hostent *host_info;
}
host_info := gethostbyname(argv[1]);
Assign the IP address by copying individual bytes, invoking bcopy as
bcopy(host_info->h_addr,&sm_socket_address.sin_addr,
host_info->h_length);
Assign the network representation of the port number from the
second command line argument :
sm_socket_address.sin_port := htons(atoi(argv[2]));
{ Now sm_socket_address contains the address of the socket created
by STORE_MANAGER. }
end SetUpSocketInRandProc
Following this scheme, RAND_PROC invokes the function sendto() to send a message to STORE_MANAGER, and STORE_MANAGER invokes recvfrom() to receive messages from the clients. The function recvfrom() returns to STORE_MANAGER the address of the socket associated with the sender (through one of its parameters) and STORE_MANAGER sends its response to the request specifying this address for the destination. The functions sendto() and recvfrom() may be used in the transmission of messages from STORE_MANAGER to the clients as well.
The details of sending and receiving messages should be hidden in the functions SSTORE_READ() and SSTORE_UPDATE() invoked by the client programs. The intent is to avoid burdening the user with the details of the implementation and present an interface that specifies only the semantics of the operation.
The above discussion applies to messages originating from STORE_MANAGER as well. Response messages for all cases except that of an invalid read operation have the same length, but the latter requires fewer characters. All cases may, however, be handled in a uniform manner by getting STORE_MANAGER to put in some padding in the messages containing the response to invalid read operations.