Systems Programming (XMUT): Assignment 4
“Socket Programming”
Resources and links:
To Submit
Do not rename these files.
In this assignment, you will implement a network server program, a program that waits for TCP connections from clients and responds to the messages sent by the client. Unlike the previous three assignments, you will be writing a complete C program with a
main()
function.
Sample skeleton codes and text files are provided under the files
directory in the archive that contains this file. Use the skeleton files to perform the tasks and testing.
You should provide appropriate comments to make your source code readable. If your code does not work and there are no comments, you may lose all marks.
Coding Style
Code quality refers to (i) the use of efficient coding techniques and (ii) use of consistent coding style or standard.
When writing your source code, strive for coding efficiency which covers the following aspects: (i) elimination of unessential operations and variables; (ii) creation of functions to contain blocks of code that are used repeatedly; (iii) minimization of loop iteration; and (iv) avoiding the use of global variables (i.e. variables that are declared outside any function.);(v) use built-in functions where appropriate.
In addition, you should follow a consistent coding style when writing your source code. Coding style (aka coding standard) refers to the use of appropriate indentation, proper placement of braces, proper formatting of control constructs, and many others. Following a particular coding style consistently will make your source code more readable. There are many coding standards available (search "C coding style"), but we suggest you consult the
lightweight Linux kernel coding style (see
coding-style). The relevant sections are Sections 1, 2, 3, 4, 6, and 8. Note that you do not have to follow every recommendation you can find in a coding style document, you just must apply that style consistently.
Server Program Specifications:
- The program should accept one command-line argument. Excluding the program name, the argument should specify the port number that the program will use. The program should immediately terminate with a return value of
-1
if the argument is not specified. The program should also immediately terminate with a return value of -1
if the specified port number is less than 1024
.
- Initiate the required socket operations to create and bind a socket.
- Listen for TCP clients at the port specified in the command line. (During testing, you may need to use a "random'' port number to avoid conflicts with other students running tests on the same server.)
- When a client successfully establishes a connection with the server, send a
HELLO
message back to the client.
- Wait for a message from the client.
- Perform the following based on the message received from the client:
- If the message has the contents
BYE
(case-insensitive), close the connection to the client and go back to step 3.
- If the message has the contents
GET
(case-insensitive) followed by a file name (example: GET file.txt
), open the file as a text file for reading. The file should be located in the same directory as the server program. If the opening is successful, send the following back to the client:
SERVER 200 OK\n
\n
(Contents of file)\n
\n
\n
You must follow this format strictly. Note that there is a single empty line (a newline) after SERVER 200 OK
and two empty lines (two newlines) after the contents of the file.
If the opening is not successful, send the following back to the client:
SERVER 404 Not Found\n
For any other error encountered (e.g., no file name is specified in the GET
message), send the following back to the client:
SERVER 500 Get Error\n
- If the message has the contents
PUT
(case-insensitive) followed by a file name (example: PUT file.txt
), open the file as a text file for writing (if the file exists, existing contents must be emptied). The file should be located in the same directory as the server program. Write every message received from the client to the file. Upon receipt of two consecutive empty lines (just newlines), close the file. The last two consecutive empty lines should also be written into the file. After successfully closing the file, send the following back to the client:
SERVER 201 Created\n
For any other error encountered (e.g., failure to open file), send the following back to the client:
SERVER 501 Put Error\n
For other messages, send the following back to the client:
SERVER 502 Command Error\n
Testing:
As you are using the Linux
socket()
system call, you will need to test your program in Linux or Mac machines. If you are a Windows user, you need to install a Linux shell on your windows. You will need to compile your program using
GCC
in the Linux shell. You can find how to Install and Use the Linux Bash Shell on
Windows 10 or
Windows 11
You do not need to write a client program to test your server program. You can use the Linux program
nc
to receive and send messages to your server program. To do this:
- Open a terminal. Compile and run your program.
- Open another terminal. Run
nc localhost portnum
(where portnum
is the port number that your server is using) to establish a connection with your server program. Once nc
is connected to the server program: whatever you type in this terminal will be sent to the server program, and whatever is sent by the server program will be shown in this terminal.
Core [45 Marks]:
Implement the server program specifications 1 -- 5 above inside the file
server.c
.
Completion [15 Marks]:
Implement the server program specifications 6(a) - 6(c) above inside the file
server.c
.
Challenge [10 Marks]:
One of the drawbacks of the server program specified in the
Program Specifications above is that when a client is connected to the server, no other client can connect to
the server.
Provide an enhancement of the server program by using the
fork()
system call as follows: At step 4 of the Program Specifications above, when a client successfully
establishes a connection, fork a child process. Upon successful fork, the parent process should go back to step 3, whereas, the child process should perform the following:
- Send a message to the client with contents
HELLO
.
- Wait for a message from the client.
- Perform the following based on the received message from the client:
- If the message has the contents
BYE
(case-insensitive), close the connection to the client and exit the process.
- If the message has the contents
GET
(case-insensitive) followed by a file name (example: GET file.txt
), open the file as a text file for reading. The file should be located in the same directory as the server program. Go back to Step 2. Request handling will be similar as defined above for a single client.
If the fork is not successful, the process should perform steps 4 and 5 (in the original Program Specifications).
Save the enhanced server program as
server2.c
.
Marking Criteria:
Criteria |
Weight |
Expectations for Full Marks |
Compilation |
5% |
Compiles without warnings |
Comments |
10% |
Sufficient and appropriate comments |
Code Quality |
15% |
Efficient code and use of consistent coding style |
Correctness |
70% |
Handles all test cases correctly (see marks distribution below) |
Total |
100% |
|
For the
Correctness criteria, the following table shows the marks distribution over the different task types: