The usual note:
Please see FAQ.
You will write two C/C++ programs using BSD sockets (using AF_INET and SOCK_STREAM) to implement a client and a server which follow a protocol (called Oracle) to exchange message and perform some functions on server. There will be only one client and one server for this assignment.
- After connection between client and server is established, client sends a "Hello" to server.
- Server responses with an "OK" and a random session id (client will use this session id to communicate with server).
- Then client sends the user name, and server responses with "HI username".
- Client sends a question to server and server responses with an answer. The sample questions are "server name", "date/time", "user name", "add 1 2", "subtract 4 2", etc.
- At the end of message exchange, client sends "Bye" to server and server responses with "Bye username". And then connection is closed.
- If client sends another "Hello", server issues another random session ID. And continue as (3).
- Server keeps track of client's hostname, current user's name and session ID. If client's session ID doesn't match current session ID at server, server sends an error message and terminates the connection.
- Each message includes a unique ID (4 bytes, first 2 letters of your last name + first letter of your first name + last digit of your SSN). Client and server has a copy of this unique ID. If server receives a message with different unique ID, server responses a error message and closes the connection.
- If any command received by server is out-of-order (for example, server receives "ASK" command as the first massage from client), server responses an error message and terminate the connection.
Message format
Each message has 42 bytes which are consisted of 4 parts.
- Unique ID (4 bytes, characters): Unique ID is used as an identification between client and server, so client communicates with intended server. Unique ID is constructed by first two letters of your last name + first letter of your first name + last digit of your SSN.
- Session ID (2 bytes, an unsigned integer): Session ID is randomly generated (greater than 0) and assigned by server. When client connects to server with a "HELO" command, server will return a session ID. Session ID "0" is used only for client sending "HELO" command.
- Code (2 bytes, an unsigned integer): The code is used to identify the actions between client and server.
- Message (34 bytes, characters): The message part contains the actions or information to be exchanged. All commands are in upper case and words in the messages are separated by space.
Messages exchanged between client and server
The messages exchanged between client and server are listed (but not limited to) in the following table. You can add extra error messages to cover out-of-order commands.
Sent from Code Message Explanation Client 100 HELO from clienthost send client's hostname (clienthost) to server 110 USER username send client's current user name (username) 300 ASK SRVR request server's hostname ASK SNID request current session IDASK CLNT request client's hostnameASK USER request current user's name ASK DATE request date and time on the server ASK ADD numbr1 numbr2 request the result of (numbr1 + numbr2) ASK SUB numbr1 numbr2 request the result of (numbr1 - numbr2) 500BYE notify the end of connection Server 200OK SNID reply with session ID (SNID) 210HI username acknowledge current user (username) 400ANSW result reply with the result requested by ASK command 600BYE usrname from clnthost acknowledge the termination to current user (usrname) at client (clnthost) 800ERR unknown command server receives an unknown command 810ERR incorrect UNIQ ID server receives mismatched unique ID 820ERR incorrect SNID server receives mismatched session ID ......... ...... The state diagram of messages exchanged between client and server is described in the following feature.
There were some confusions regarding the state diagram above. So I drew another state diagram to make the transition between different states easier to understand. Start, C2, C3, and End are on the client; S1, S2, S3, and S4 are on the server. "Error" state indicates server receives a message containing error(s) and labels on the edges reaching "Error" state indicate the messages sent to client.
- The client and server program will use command line parameters to input server name (servername) and port number (port_no). The commands would look like this. [Hint: you can use getopt().]
client -h servername -p port_no or client servername port_no server -p port_no or server port_no- Users (you or TA) will type a message from client program (with code, and message) and send it to server. Your program should provide a debugging mode, so TA can type "unique ID" and "session ID" (plus code and message) to test your error detecting mechanism. You can add an option in the command line parameter, like "client -d -h servername -p port_no" or "client servername port_no y" to activate the debugging mode.
- You should print out entire message block of all messages exchanged with proper prefixes to identify the message is sent or received (or from client or server). The "session ID" and "Code" should be converted into integral numbers. [Hint: there are lots of string related functions which will significantly shorten the time you spend on this assignment.]
- You can assume that integral numbers used in "ADD" and "SUB" commands are positive. Also, when checking for unknown command, you can check if you can identify the code and the first word in the message (except "ASK" command which you have to check next word). [Hint: you can use strtok() to retrieve tokens.]
- If you plan to use Java (instead of C/C++), you should get instructor's approval and make a arrangement with TA (on which machine to run your program and maybe a domestication.)
- When client receives message from server, client finds the unique ID from server is different from client's (somehow another server hijacks the connection and uses different unique ID.) Should client close the connection right away, or sent a message to server before close the connection? Which way is better? Why?
- Why does this protocol provide persistent connections?
- When server receives an out-of-order command, it would be better to tolerate the error and continue the execution (instead of terminate the connection). Give an example (or sequence) that server receives an out-of-order command and continues execution and still preserve the authentication sequence ("HELO" and then "USER"). You may add extra message to achieve fault-tolerance.
Last modified: October 12, 2000. Submit your assignment: (updated)
~xjiang/submit assignment# file1 file2 ...
where assignment# is which assignment you want to submit
(in this case it's "2"), and file1, file2, ... are the files
you want to submit. Here is an example for submitting 4 files for
Assignment #2.
~xjiang/submit 2 Makefile server.c client.c readme.txt
Reference:
tihuang at cs . uh . edu