In this project, you will implement a Transmission Control Protocol (TCP) client and server that does a
three-way handshake, a well-known protocol sequence used in communication networks. This project has
three parts:
1. The client and single-threaded server. In this part, you should implement the client and the server,
and your server is implemented as a single-threaded program.
● The client will be reused for part B and C.
2. Multi-threaded server. In this part, you should improve your server implementation by making it
concurrent with multithreading.
3. Event-driven server. In this part, you should implement a single-threaded but concurrent server
using event-driven techniques.
In this project, you will learn and implement synchronous (3a, 3b) and asynchronous (3c) communication
between the server and clients. Please make good use of TA hours, Open Office Hours, and Recitations.
They are excellent supplements to the lectures and have many practical system programming tips to
improve your project. It is highly recommended that you read the homework first, participate in our
recitations and start early. There will be 2 recitations: the first will focus on part A and part B, and the
second will focus on part C.
Please be aware that the example code provided for each part of this project only provides examples of
certain features, and is NOT a starter template for each part of the project. Features demonstrated by the
example code can be seen below
Based on our past experience, asynchronous communication can be unintuitive and students need to have
a different mindset to organize communication logic. This will be the main focus of the second recitation.
Moreover, you are highly encouraged to utilize Piazza to discuss the project with classmates and TAs.
Before asking the question, please search in Piazza to see if there are any similar questions asked before.
If it is about a bug you are facing, it is likely that it is discussed in the Common Mistakes document.
Please check all suggestions listed there. If you plan to ask about your code/implementation on Piazza,
please consider filling in the following template to make the communication efficient:
● GitHub URL:
● Description of Question:
● Expected Behavior:
● Observed Behavior:
Note that the example code and the Common Mistakes document can be found under the resources section
in Coursera.
You will implement two files in this part: the client (tcpclient.c) and the server (tcpserver.c). The client
takes 3 arguments as input: the server address, server port number, and an initial sequence number. The
server takes in a server port argument, and should be started and be listening on the specified server port.
You will implement a three-way handshake communication using TCP as follows:
● Step 1: The client sends “HELLO X” to the server, where X is an initial sequence number.
● Step 2: The server receives and prints the “HELLO X” message from the client, and sends
“HELLO Y” to the client, where Y is X+1.
● Step 3: The client receives “HELLO Y” message from the server, prints the message to screen,
and does either one of the following:
o If Y = X+1, the client sends “HELLO Z” to the server, where Z=Y+1, and closes the
connection.
o If Y != X+1, the client prints an “ERROR” message, and closes the connection.
● Step 4: If the server receives the “HELLO Z” message from the client, and prints the message to
screen. In addition, if Z != Y+1, prints an “ERROR”. The server then closes the connection.
For simplicity, you can assume that the client and the server do not crash during the communication. You
must also ensure that the format of all messages (e.g. “HELLO X”) is correct.
For printing to screen (stdout), make sure that you do “fflush(stdout)” right after you do the print.
You could use printf, fputs, or other ways to print, but fflush must be used after that. This is because
printing in Linux is buffered and may happen asynchronously. If a process does not exit gracefully, your
intended prints may be lost. fflush ensures that your print executes immediately. In our autograder, we
terminate the server process using SIGKILL but it evaluates your server output.
Compilation: You should use the gcc command to compile tcpclient.c (gcc –o tcpclient
tcpclient.c ) and tcpserver.c (gcc –o tcpserver tcpserver.c). Please always make sure
that all compile warnings are fixed, as the autograder might fail to compile otherwise.
Your implementation has to work in the Vagrant VM that you used in the previous assignments. You can
run multiple clients and the server on the same machine. The server listens on its port, and when a client
connects, a temporary port is assigned to the client-server communication.
Generally, the server and a client in your implementation should work on any two hosts in the network.
That being said, since you are running all within one virtual machine, you can assume the server is
listening on a port of your choice, and clients and the server all run on the same machine with the same IP.
You can use the loopback address 127.0.0.1 as the default IP address for the server and all clients.