Computer Networks CS 280: Project 2 Client Server Programming Fall, 2003

Download as pdf or txt
Download as pdf or txt
You are on page 1of 17

Computer Networks

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.

When a client wishes to connect to a server, it first sends a message containing


the desired service name (e.g., "daytime") to the oracle, and the oracle returns a
message with the appropriate transport address (e.g., XXX). The client then opens
a TCP connection to that service. Exact details for communicating with the oracle
are described below.

Project 2 6

3
THE BIG PICTURE
An Overview of How it works

SERVER CLIENT

Getservbyname  OPERATING  Getservbyname


SYSTEM

 Oracle port returned. Oracle port returned 

UDP ORACLE UDP

Register the server Ask the oracle for


port number using the number of the
the OM protocol server port.

 Client uses the server port to request result from server.

Server returns result to client 

Project 2 7

CLIENT AND SERVER User - Client


Interface
OPERATION
The client accepts the following set of commands from standard input:

list: Send a message to the oracle requesting a listing of all the services currently
available.

connect service [uid]: Open a connection to the server providing service


service. Service is the user-friendly service name registered with the oracle .
An optional argument uid is used to distinguish between services provided
by different users having the same name. That is, multiple users may
register services having the same name.

quit: terminate the client program.

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).

• Open a TCP connection to the server supplying the desired service.

• Copy standard input to the server, and copy all data sent by the server to
standard output.

• After receiving an end-of-file from either standard input or the TCP


connection, close the TCP connection. Note: if your client receives an end-
of-file from standard input, it should terminate the connection to the server,
but should continue reading additional commands from standard input
because the user may want to connect to another service (see clearerr(3)).
Project 2 9

CLIENT AND SERVER Server - Client


Connection
OPERATION
The server performs the following steps when making a service available:

• Create a TCP socket (similar to a UNIX file descriptor -- see socket(2)).

• 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

CLIENT AND SERVER Client - Server


OPERATION Interface
One of the requirements not mentioned previously is interoperability. This means for this
project that I expect that your client will operate with my servers and my client will
operate with your servers.

These extended rules are as follows:

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

CLIENT AND SERVER Client - Server


OPERATION Interface
A Server Requiring Client Interaction
CLIENT SERVER
---- ----
a service is selected by the human user
( “connect checksum” )
accept()
connect()
send( “HELP: A useful help message”)
recv()
while( recv( “request from client” ) )
if ( "Help:" seen )
{
{
do useful work with client request
read from standard in
send( “result back to client” )
while ( "quit" not seen )
}
{
send()
recv()
print out what server sent.
read from standard in
}
} Project 2 14

7
CLIENT AND SERVER Client - Server
OPERATION Interface

3. For servers requiring NO input from the client:

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

CLIENT AND SERVER Client - Server


OPERATION Interface

4. For servers requiring input from the client:

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.

5. Interoperability. Your client must operate on my interactive server. In addition, all of


your servers must operate from my client. I will make available an executable of my
client as well as my interactive server for your testing pleasure. I will be happy to
discuss with you individually situations where you believe you must have some network
functionality in a client that is not provided by the client I have prepared.

Project 2 17

INTERACTING WITH Oracle.h


ORACLE
Oracle resides on machine 140.232.101.121 ullman.clarku.edu at well-known
UDP port netoracle . All communication with oracle is through UDP messages
containing a structure called an om (for "oracle message", pronounced "ohhmm"),
whose definition can be found in the file oracle.h in
~jbreecher/public/networks/Project1/oracle.h. Thus the oracle, your client and your
server all communicate via the same mechanism. The file is reproduced in the
next few slides:

# define luid 16 /* Length of the username field


# define cchMaxServ 10
# define cchMaxDesc 40
# define verCur ‘C'

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 */
};

# define lom (sizeof (struct om))

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:

ver: Always verCur in all messages.

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

INTERACTING WITH Client - Oracle


Interaction
ORACLE
As a return to cmdGet, the oracle program fills in the fields of the om structure as follows:

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.

sa: The transport address at which the service resides.

ti: The time at which the service was registered.

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:

cmd: cmdPut, to register a service.

uid: The login id of the user registering the service (see getuid(2) and
getpwent(3) ).

sbServ: One word name of the service (e.g., "daytime").

sbDesc: A brief description of the service.

sa: The transport level address at which the server can be reached.

In response to a cmdPut message, oracle returns a message of type cmdAckPut


if the registration succeeds. In the case of errors, the oracle returns a
message of type cmdErr, and the sets the field sbDesc to contain a
short explanation of the error.
Project 2 23

INTERACTING WITH Server - Oracle


Interaction
ORACLE
Here are the steps to follow:

1. Create a UDP socket (see socket(2) ).

2. Get the Internet address and port number of the oracle (see
gethostbyname(3) and getservbyname(3) ).

3. Open a UDP connection to the oracle (see connect(2)).

4. Send an om message of the appropriate type to the oracle (see send(2) ).

5. Wait for an om reply from the oracle (see recv(2) ).

Project 2 24

12
INTERACTING WITH Server - Oracle
ORACLE Interaction
In a more schematic form, these steps look like this:

sock = ConnectUdp (hostOracle, portOracle);


send (sock, &om, lom, 0);
recv (sock, &om, lom, 0);

int ConnectUdp ( char *sbHost, char *sbPort)


It’s this variable that makes it UDP
{
fd = socket (AF_INET, SOCK_DGRAM, 0);
phe = gethostbyname (sbHost)); Used to convert machine
na = *( (struct in_addr *) (phe->h_addr)); name into ip address
sa.sin_family = AF_INET;
sa.sin_addr = na;
pse = getservbyname (sbPort, "udp");
Used to convert service
sa.sin_port = pse->s_port;
name into port number
connect (fd, (struct sockaddr *)&sa, lsa )
return( fd );
}

Project 2 25

TOOLS AVAILABLE TO YOU


In the course of doing this project, it would be nice to get all the help you can.
In the directory ~jbreecher/public/networks/projects are the following documents and
executables.
oracle.h – The include file that contains structures, etc. allowing you to communicate with the
oracle.
bclient – This is the Breecher Client. It behaves according to the functionality defined in this
document. So it’s kind of an implementation standard. This client should be able to talk to
your server.
checksum_server – This is a server that behaves according to the spec. Once you get your
client working, you should be able to talk to this server.
oracle_log – contains the history of transactions from the oracle’s point of view. So if you
send a request to the oracle, and you get back garbage, you can look in this log and see
what the oracle thought was happening.

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

GENERAL ADVICE The Steps To


Follow

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

By now you understand that your job is to create processes.

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.

But be careful; it is unethical to share code OR concrete implementation


details with anyone else, either a member of the class or otherwise.

Failure to follow these guidelines will result in severe action on my part.

Project 2 31

GENERAL ADVICE HOW YOU


WILL BE
EVALUATED
What follows is the sort of items I will be looking for when evaluating your Project
I results. Please don’t think that this is an complete list, or that all these items
will be there at the end. Having said that, it’s certainly a good starting point - you
would be wise to ensure that your project can accomplish all these items.

1. Client and servers build correctly.


2. Client and two servers start.
3. Student client works with student’s Server #1.
4. Student client works with student’s Server #2.
5. Student client works with my interactive server.
6. bclient works with student’s Server #1.
7. bclient works with student’s Server #2.
8. Relative complexity of student Server #1.
9. Relative complexity of student Server #2.

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.

Week 3: Final project Due.


How will this project be turned in?

Project 2 33

17

You might also like