CS 111 – Project 4 – Spring 2005

Web Server

Relevant paper

"Flash: An efficient and portable Web server" by Vivek S. Pai, Peter Druschel and Willy Zwaenepoel.

Due date

Friday 6/17/2005 by 12:00 PM PST (noon).

Web Server preliminaries

An HTTP (Web) server serves web clients with files. HTTP clients use the TCP transport protocol to contact Web servers and request content. The client opens a TCP connection to the server, and transmits a HTTP request header that specifies the requested content. The Web server reads the request, locates the file requested by the client on the local file system and responds to the client with the requested file.

Networking

Server Applications

A system offers a service by having an application running that is listening at the service port and is willing to accept a connection from a client. A server creates and binds the "server socket" and then listens and accepts for client connections:

/* create an INET, STREAMing socket */
int sockfd, client_sockfd;
sockfd = socket(AF_INET, SOCK_STREAM, 0);

/* bind the socket on a well-known port*/
struct sockaddr_in sin, client_addr;
sin.sin_family=AF_INET;
sin.sin_port=80;
sin.sin_addr.s_addr=htonl(INADDR_ANY);
bind(s, &sin, sizeof(sin);

/* listen on the socket*/
listen(sockfd, 2);

/* accept connections from client*/
client_sockfd = accept(sockfd, &client_addr, &len);

/* read client request */
read(sockfd, buf, SIZE);

/* respond with content */

A couple things to notice: INADDR_ANY means all interfaces. A second thing to note: we use the port usually reserved for the HTTP "well known" services i.e port 80. Finally, the argument to listen tells the socket library that we want it to queue up as many as 2 connect requests.

Client

Clients merely create and connect the "client socket" to the server:

int sockfd;
struct sockaddr_in serv_addr;

/* create an INET, STREAMing socket */
sockfd = socket(AF_INET,SOCK_STREAM, 0);

/* bind the socket on a well-known port*/
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(SERVER_ADDR);
serv_addr.sin_port = 80;
connect(sockfd,serv_addr, sizeof(serv_addr));

/* send requests and receive responses */

Project Description

The given code will implement a single web-server that blocks on reads and writes and will be able to handle one client connection at a time. The project is to implement a "single-process event-driven" (SPED) architecture as described in the paper. Implement a non-blocking approach such that a single process can handle multiple requests. The process does not block on read()/writes() or accepts(). You are expected to handle at least MAX_CONN number of parallel requests.

Using Select

You will use system call: select() to do non-blocking I/O. select() works by blocking on a number of file descriptors (files,sockets) and returns when there is a change in status for a file descriptor. This could be incoming data on a socket or a being able to read/write to a file descriptor since a disk operation completed.

Useful macros include: FD_CLR, FD_ISSET, FD_SET, FD_ZERO

Select-based operations are performed in the following manner:

Challenge problems (optional):