Computer Networks CS 280: Project 2 Client Server Programming Fall, 2003
Computer Networks CS 280: Project 2 Client Server Programming Fall, 2003
Computer Networks CS 280: Project 2 Client Server Programming Fall, 2003
CS 280
Project 2
Client Server Programming
Fall, 2003
Project 2 1
TABLE OF CONTENTS
Executive Summary Interacting With Oracle
How It Works oracle.h
The “Big Picture” Client - Oracle Interaction
Client and Server Operation Server - Oracle Interaction
User - Client Interface Tools Available To You
Client - Server Connection General Advice
Server - Client Connection The Steps To Follow
Client - Server Interface Good Citizenship
Plagiarism
How You Will Be Evaluated
Project 2 2
1
EXECUTIVE SUMMARY
This assignment serves as an introduction to client-server programming
using the TCP/IP protocols. This is valuable in that you will gain some
actual experience in system programming using standard communications
protocols. You will write code that allows several processes to
communicate with each other, and demonstrate that this communication
actually occurs.
Project 2 3
HOW IT WORKS
In this assignment, you will write both a client and a server. Your client and server
will communicate using TCP, and your server may implement any service
you choose. The ground rules are simple:
A) The server reads and writes data to and from the TCP connection.
B) The server may prompt the client for input, or simply print a random
message.
C) Once you have debugged the server, it executes in background (even after
you log out) waiting for service requests from a client.
To access a service, the client opens a TCP connection to the server, sends and
receives data, and then closes the connection. Conceptually, the client acts
as a pipe between your terminal and the server, copying data sent by the
server to standard output and sending data read from standard input to the
server. The client terminates the connection with the server when it
receives an end-of-file from either the server or standard input.
Project 2 4
2
HOW IT WORKS
The above scenario omits a key aspect of client-server programming:
How does the client find out where the server is? What transport-level address
(Internet address and port number) should the client connect to?
One solution is to use a name server that dynamically maps service names into
their transport-level addresses. We will supply you with a such a server, called
oracle, allowing you to register the service you provide and advertise it to other
students in the class.
The oracle is like the white pages in your phone book. A server registers the name
and transport address of its service in the phone book, and clients use the phone
book to map service names to transport addresses.
Project 2 5
HOW IT WORKS
When your server starts, the operating system could assign it an unused port
number (e.g., XXX) on which that server can wait for incoming connection
requests. (Alternatively, and the way we’ll do it, is to use fixed ports. You will
each have several ports that you “own” for the semester and that you can use for
your servers.)
The server then advertises the availability of its service by sending a short
message to the oracle containing the name of the service (e.g., "daytime")
together with the transport address (host number and port XXX). The oracle server
records the name-to-address mapping in its local database.
Project 2 6
3
THE BIG PICTURE
An Overview of How it works
SERVER CLIENT
Project 2 7
list: Send a message to the oracle requesting a listing of all the services currently
available.
Project 2 8
4
CLIENT AND SERVER Client - Server
Connection
OPERATION
When the client wishes to connect to a server, it performs the following steps:
• Contact the oracle to find the transport-level address (host name and port
number) of the service you are trying to locate (details below).
• Copy standard input to the server, and copy all data sent by the server to
standard output.
• Bind the socket to a sockaddr_in structure with family AF_INET, port number X,
and address INADDR_ANY. This directs the kernel to accept TCP connection
requests from any machine (INADDR_ANY) in the Internet, and specifying a port
number of X directs the kernel to allocate the port number you request. (see
bind(2) ). (The port numbers X available to you are in the range 22340 - 23400.
We will assign these in class/lab.)
• Extract the port number allocated in the previous step (see getsockname(2) ),
and fetch the Internet address of the host on which your server resides (see
gethostname(2) and gethostbyname(3). Fill in the appropriate fields in the om
structure (described below) and register the service with oracle.
Project 2 10
5
CLIENT AND SERVER Server - Client
OPERATION Connection
Server
The server performs the following steps when making a service available:
• Specify the backlog of incoming connection requests you are willing to tolerate
(see listen(2)).
• Finally, wait for a connection request and service it. When you have serviced
the request, repeat the process by waiting for the next connection attempt (see
accept(2), and close(2) ).
Project 2 11
1. You will provide at least two services. These can be either servers that require no input
from the client or ones that do require input.
2. You must provide each of these services in a separate program. Each server program,
upon initialization, will register its service with the Oracle.
Project 2 12
6
CLIENT AND SERVER Client - Server
OPERATION Interface
A Server Requiring NO Client Interaction
CLIENT
---- SERVER
a service is selected by the human user ----
( “connect daytime” )
connect() accept()
recv() send( Result of service - daytime”)
close() close();
Project 2 13
7
CLIENT AND SERVER Client - Server
OPERATION Interface
a) Upon completing the accept, this type server has all the information about the client that
it's ever going to get. No further input will come from the client, but the server has
enough addressing information so that it knows how to respond to the client.
b) The server sends back a string containing the result of its service to the client. This
string has the following properties:
I. It is less than or equal to 1000 bytes ( strlen(string) <= 1000 ).
II. It is terminated with the <NULL> Character.
III. The server closes the connection with this client and prepares for an accept
with the next client requester.
Project 2 15
a) Upon completing the accept, this type server has all the information about the client that
it needs in order to respond to that client. The client will later send further information.
b) The server sends back a string containing a help message. This message can be used
in guiding the client as to what is required in order to obtain the service. This string has
the following properties:
I. The help message begins with the 5-character ASCII string "Help:". This is
an indication to the client that it should go into "interactive mode", following
a sequence of recv/send messages.
II. The string is less than or equal to 1000 bytes ( strlen(string) <= 1000 ).
III. It is terminated with the one-character sequence <NULL>.
c) The server waits for a request from the client. The client string provides content as
requested by the server. The format of this string is the same as in 4bII) and 4bIII).
Project 2 16
8
CLIENT AND SERVER Client - Server
OPERATION Interface
d) The server and client communicate back and forth as necessary to provide the service.
When the server has completed its service, it closes its connection. The client must be
able to deal with this closed connection and also close the connection from its side.
e) The user of the client can stop sending to the server by typing "quit". This causes the
client to close the connection - thus the server must be able to handle a closed
connection from the client.
Project 2 17
Project 2 18
9
INTERACTING WITH
Oracle.h
ORACLE
enum cmd {
cmdErr, /* An error occurred. See sbDesc for details */
cmdGet, /* Get the address of a service */
cmdAckGet, /* ACK for cmdGet message */
cmdEnd, /* Last response to a cmdGet message */
cmdPut, /* Register a new service */
cmdAckPut, /* ACK for cmdPut message */
cmdClr, /* Unregister a service */
cmdAckClr /* ACK for cmdClr message */
};
Project 2 19
INTERACTING WITH
Oracle.h
ORACLE
struct om { /* oracle message */
char ver; /* version number of this structure */
enum cmd cmd; /* command/reply code */
char sbDesc[cchMaxDesc]; /* desc. of service (or error) */
char uid[luid]; /* id of requester/provider */
char sbServ[cchMaxServ]; /* name of service requested */
struct sockaddr_in sa; /* socket where service is available */
unsigned long ti; /* time of registration */
};
Project 2 20
10
INTERACTING WITH Client - Oracle
ORACLE Interaction
To find a service, your client program fills in the fields of the om structure as follows:
cmd: cmdGet .
uid : The user id of the user offering the service - user who started the server process.
If the client doesn't care which uid to use, it sets this field to the NULL string
(NULL character in first byte).
sbServ: The name of the service being searched for (filled in by the client). To get a listing
of all available) services, set sbServ to the NULL string (NULL character in first
byte). In response to a cmdGet message, oracle returns two or more messages.
Response messages have a cmd type of cmdAckGet, and the end of cmdAckGet
responses is signaled by a cmdEnd message. CmdEnd messages do not contain
the name of a service; they simply signal the end the last response. If only one
service matches the client's request, the server will return two messages: a
cmdAckGet, followed by a cmdEnd . Each cmdAck message contains the
following fields:
Project 2 21
sbDesc: A sentence describing the service. Your server uses this field when registering a
service, and the oracle returns it in response to cmdGet queries. When locating a
service, the field should contain all zeros.
Project 2 22
11
INTERACTING WITH Server - Oracle
ORACLE Interaction
When your server wishes to register a service with the oracle, it sends an om
message with the following fields:
uid: The login id of the user registering the service (see getuid(2) and
getpwent(3) ).
sa: The transport level address at which the server can be reached.
2. Get the Internet address and port number of the oracle (see
gethostbyname(3) and getservbyname(3) ).
Project 2 24
12
INTERACTING WITH Server - Oracle
ORACLE Interaction
In a more schematic form, these steps look like this:
Project 2 25
The processes you see running on ullman (using ps aux|grep jbreecher) are started up with a
script with path ~jbreecher/start_oracle. You may find this of interest.
Project 2 26
13
GENERAL ADVICE The Steps To
Follow
1. Start small. Write a procedure that sends a datagram to the oracle, and
receives a datagram response from the oracle. If you made a mistake, the
oracle will return an om with cmd set to cmdErr, and sbDesc will contain a
brief description of the problem.
2. Write a client that connects to a server registered with the oracle. I will
register a few simple commands "daytime" and "finger" seem to be staples
that you can use to test your client.
3. Once you have the client working, begin work on the server.
4. Nearly all system calls and library routines return some form of error code if
the operation was not successful. You must check the return value from
every routine for an error code.
Project 2 27
5. As an aid to debugging, as well as to trace use of your server, you should print
trace output when connections are made. For example, you might print the
host name and port number of every user that connects to your server, along
with the time of the connection.
6. Requests to the oracle are actually a bit more general than we've described
so far. Regular expressions can be used as service names or users ids to
effect a kind of "wild-search" for services. For example, specifying a service
name of ".*" matches all services. Specifying a user name of "..." matches all
services provided by users with three-character ids. The format of regular
expressions is the same as that of ed(1).
Project 2 28
14
The Steps To
GENERAL ADVICE Follow
7. Use your imagination and creativity in designing server programs. You will
earn extra credit by implementing a "neat" server.
The following library procedures and system calls will be helpful: clearerr(3),
gethostname(2), listen(2), close(2), getpwent(3), getuid(2), send(2), recv(2),
getservbyname(3), gethostbyname(3), gethostbyaddr(3), getsockname(2),
bind(2), socket(2), connect(2), accept(2), listen(2) and select(2).
For more information on how the networking related calls, use the recommended
text for the course.
Project 2 29
Good
GENERAL ADVICE Citizenship
Problems will occur however when the whole class is creating new processes,
not terminating erroneous processes, and not cleaning up after themselves.
What happens is that the machine grinds to a halt.
The net effect is to use up the maximum number of processes available on the
machine, and to slow down the machine dramatically. Eventually the system
Gods must intervene and reboot the machine.
Please get in the habit of cleaning up before you log off; the easiest way to do
that is “ps -aux | grep <your_user_id>”
This will produce a list of process numbers and you can then go through these
and utter “kill <process number>”.
Project 2 30
15
GENERAL ADVICE Plagiarism
Feel free to discuss high level aspects of this project with other class
members.
Project 2 31
Project 2 32
16
GENERAL ADVICE HOW YOU
WILL BE
EVALUATED
Checkoffs: Human nature being what it is, procrastination is avoided by having
weekly check-ins. The schedule for this project looks like this:
Week 1: Check-in. Your client can talk to the oracle. It correctly can list the
servers available via the oracle, and it can connect and obtain information from
the sample servers available to you.
Week 2: You have written a server that registers with the oracle. That server
can receive a simple message from your client.
Project 2 33
17