In this week’s lab, you will:

  • Learn the system calls for network programming in Linux
  • Learn to use a networking API for performing client/server transactions
  • Hack an echo client-server application to gain practical experience with writing network applications
  • Set up and run and modify a tiny web server


Do an upstream pull as usual to get the latest files for this lab in your comp2310-labs repository.


We will look at two network application today that are based on the canonical client-server model. Recall from the lectures that clients and servers use the sockets API for establishing a connection. Once a connection is established they perform transactions by sending and receiving messages using a file descriptor.

The client and server both use the socket() system call. The client further uses the connect() system call for connection with the client. The server uses the bind(), listen(), and accept() system calls for listening to and accepting connections from clients. Refresh your knowledge of a typical client and server workflow in socket-based communication.

In this tutorial, we provide you with existing code for two network applications. These applications make use of wrappers on top of the systems calls for socket-based communication. We first want you to be comfortable with the API the application use.

Open the lab directory and investigate the code for open_clientfd() and open_listenfd() in csapp.c. Make sure you have a basic idea of what these functions are trying to accomplish and how to use them in a network application.

Echo Client/Server Application#

An echo client-server is an application that allows a client and a server to connect so a client can send a message to the server and the server can receive the message and send, or echo, it back to the client.

Open the relevant code files for the echo client and server and the echo function. Make sure you inspect the code thoroughly and have a good understanding of what the code is trying to accomplish. Start with the iterative loop that implements the echo server. Then try to match all the read/write function calls to understand the overall control flow of the application code.

Compile the echo client-server application by using the provided Makefile.

Testing the echo client/server application#

First, let’s make sure the echo client and server can communicate properly on your local machine.

  • Start the echoserveri in a terminal using any port that works for you. Avoid popular ports already taken (e.g., 25 or 80).
  • Start echoclient in a separate terminal or in the same terminal if you are running the server in the background. Make sure to pick any IP address (can you see from the code why this would work?) but the specific server’s port number (you used in the first step to start the server) to connect the client to the server.
  • Make sure (by observing the messages printed on the screen) that the client-server connection is established.
  • Type a message on the client side and make sure the message is echoed back by the server.

Use telnet instead of echoclient to communicate with the echo server.

Exercise 1#

This exercise checks your understanding of the echo client-server code. Answer the question without making any code modifications. Is it possible for the echo server to send client’s IP address and port number to the client before echoing the message? Identify the relevant code on the server side.

Exercise 2#

Change the echo client/server application in the following way. Before the server echoes the client’s message, it first returns meta-data about the message. The meta-data returned by the server consists of (1) length of the message and (2) number of unique words in the message.

Exercise 3#

Servers are designed to run for a long time without stopping. Therefore, they need to provide good service to all their clients regardless of client’s actions. Examine the client and server code and list anything you can think of that a client might do to cause the server to give poor service to other clients. Suggest improvements to fix the problems you identify.

Exercise 4#

Why does the socket interface use listening and connected sockets to serve client requests? What would be wrong with having a server create a socket, set it up using bind() and listen(), wait for a connection, send and receive through that socket, and then when it is finished, close it and repeat the process?

Exercise 5#

Modify the client and server so that the server talks first, sending a greeting message, and the client waits until it has received the greeting before sending anything. What needs to be agreed upon between the client and server?

Tiny Web Server#

Web clients and servers interact using an application-level protocol called HTTP or hypertext transfer protocol. HTTP operates on top of the TCP/IP stack. HTTP works as follows. A web client (browser) opens an internet connection to a server and requests content. The web server responds with the requested content and then closes the connection. The browser displays the content on the screen. Web content is written in a language called hypertext markup language or HTML. Note the distinction between the protocol (used for communication and to request content and respond to content) and the language for displaying content.

The lab code repository includes a tiny web server. Open the file and inspect the code. Make sure you have a full understanding of what the key functions in the tiny web server are trying to accomplish.

Compile the tiny web server application by using the provided Makefile. You need to be in the tiny server’s directory for the next exercises.

Testing the web server#

First, let’s make sure the web server works properly on your local machine.

  • Start tiny by running the executable and using a port number of your choice in a terminal.
  • From your web browser type localhost:port# to point the browser (client) to the webpage tiny (server) is serving.
  • If you do not see a striking image then check your port settings and get help from a tutor.
  • Inspect the output from tiny in the terminal and make sure a connection is established and a transaction took place.

Exercise 1#

Modify Tiny so that it echoes every request line and header.

Exercise 2#

Modify Tiny so that when it serves static content, it copies the requested file to the connected descriptor using malloc, rio_readn, and rio_writen, instead of mmap and rio_writen.

bars search times arrow-up