Programming Assignment 1: Socket Programming

Back to CS 641 home page


Goal of the project

In this assignment, we will build a simple client-server system, where you use the client to chat with a dummy "math" server. The protocol between the client and server is as follows.

You are provided with the client (source code). You will write three versions of the server:

At the very minimum, all your servers should be able to handle addition, multiplication, subtraction, and division operations on two integer operands. You may also assume that the two operands are separated by a space. So, some sample test cases are:

Note that the actual test cases we will use may be different from the ones shown above: your servers should correctly work with any numbers, not just the ones shown above, as long as they confirm to this format. Handling non-integer operands, other arithmatic operations, or operations with more than 2 operands (e.g., "1 + 2 + 3") is purely optional.

Several good tutorials and useful documentation on socket programming and designing servers for concurrent clients (using both fork and select) are available online. Please make use of these resources to learn the intricacies of socket programming on your own during this assignment.

Please write your code for this assignment in C/C++. Please talk to me if you have a compelling reason to use any other language.


The client

Here is a copy of the client source code. Below is a sample run of the client. For this example, the client code is first compiled. Then a server is run on port 5000 in another terminal. The client program is then given the server IP (localhost 127.0.0.1 in this case) and port (5000) as commandline inputs.
$ gcc client.c -o client
$ ./client 127.0.0.1 5000
Connected to server
Please enter the message to the server: 22 + 44
Server replied: 66
Please enter the message to the server: 3 * 4
Server replied: 12
...
...

In parallel, here is how the output at the server looks like this (you may choose to print more or less debug information). Note that the server's output shown below is only for illustration, and we will not grade you based on your server's debug output. We will primarily grade you based on whether your server returns correct responses to the clients or not.

$ gcc server1.c -o server1
$ ./server1 5000
Connected with client socket number 4
Client socket 4 sent message: 22 + 44
Sending reply: 66
Client socket 4 sent message: 3 * 4
Sending reply: 12
...
...

The servers

Part1: Single process server

First, you will write a simple server in a file called "server1.c". The server1 program should take the port number from the commandline, and start a listening socket on that commandline. Whenever a client request arrives on that socket, the server should accept the connection, read the client's request, and return the result. After replying to one message, the server should then wait to read the next message from the client, as long as the client wishes to chat. Once the client is terminated (socket read fails), the server should go back to waiting for another client. The server should terminate on Ctrl+C.

Your simple server1 should NOT handle multiple client concurrently (only one after the other). That is, when server1 is engaged with a client, another client that tries to chat with the same server must see an error message. However, the second client should succed if the first client has terminated.

Part2: Multi-process server

Note: For parts 2 and 3 below, your server should behave like any real server. It should be able to handle several clients concurrently. It should work fine as clients come and go. Your server should always keep running (until terminated with Ctrl+C), and should not quit for any other reason. If you are in doubt about any functionality of the server, think of what a real server would do, and use that as a guide for your implementation.

For part 2, you will write server2.c to be able to handle multiple clients simulatenously by forking a separate process for each client. You should be able to reuse most of the code from server1.c, but your server2.c should compile and run independent of your code in Part 1.

Part 3: Concurrent server with "select"

Now you will write server3.c to handle multiple calls using the "select" system call. The difference from part 2 is that you will not do a fork() to create a new process for every client, but you will handle all the client sockets in a single process. The behavior of the server with respect to handling multiple clients correctly is the same as the specification in part 2 above.

Submission instructions

You must do the project in groups of one or two. If you work with another student, both of you should contribute equally to the assignment (i.e., do not leave one person to write the code alone).

To submit your PA, create a submission folder, where the name is a concatenation of the roll numbers of your team members, separated by underscore ("_"). For example, your folder name could be "15000001_15000002". Place all your files in this folder, then create a tar gzipped file that has all roll numbers in the filename (e.g., "15000001_15000002.tgz") and submit on Moodle. For example, go to the directory with your submission folder, and do "tar -zcvf 15000001_15000002.tgz 15000001_15000002".

Your submission folder must contain the following files.

Note:Please document your code properly. Since we will read through your code while grading, a cleanly-written and well-documented code will fetch you more marks, in addition to making the grader's job easy.

Testing

We will run the following tests to grade your assignment. It is strongly encouraged that you perform similar tests on your servers as well before submission. Please list which of these testcases you have successfully tested in your testcases.txt submission. In addition, please list any additional tests you may have come up with on your own.

Grading

Below is the grading scheme for this assignment. This assignment carries 25 points (scaled to 10% of grade). Note that the grade of the code submission and written test are not independent. For example, if you do badly in the written test, marks allocated for your code will also be penalized, as it is will be assumed that you did not solve the assignment yourself.

Good luck!

Back to CS 641 home page