Lab 10:

Concurrency and Client/Server

If you are not a returning student, you do not have to take the quiz for this lab. In addition, you only have to submit the homework problems about concurrency, i.e. the questions from SICP. We recommend that you do the rest of the lab anyway, but you will not be tested on client/server (even on the final). However, we may test you on concurrency.

We've seen the power of computational objects with local state as tools for modeling. Yet, as section 3.1.3 warned, this power extracts a price: the loss of referential transparency, giving rise to a thicket of questions about sameness and change, and the need to abandon the substitution model of evaluation in favor of the more intricate environment model.

The central issue lurking beneath the complexity of state, sameness, and change is that by introducing assignment we are forced to admit time into our computational models. Before we introduced assignment, all our programs were timeless, in the sense that any expression that has a value always has the same value. In contrast, recall the example of modeling withdrawals from a bank account and returning the resulting balance, introduced at the beginning of section 3.1.1:

(withdraw 25)
(withdraw 25)

Here successive evaluations of the same expression yield different values. This behavior arises from the fact that the execution of assignment statements (in this case, assignments to the variable balance) delineates moments in time when values change. The result of evaluating an expression depends not only on the expression itself, but also on whether the evaluation occurs before or after these moments. Building models in terms of computational objects with local state forces us to confront time as an essential concept in programming.

We can go further in structuring computational models to match our perception of the physical world. Objects in the world do not change one at a time in sequence. Rather we perceive them as acting concurrently - all at once. So it is often natural to model systems as collections of computational processes that execute concurrently. Just as we can make our programs modular by organizing models in terms of objects with separate local state, it is often appropriate to divide computational models into parts that evolve separately and concurrently. Even if the programs are to be executed on a sequential computer, the practice of writing programs as if they were to be executed concurrently forces the programmer to avoid inessential timing constraints and thus makes programs more modular.

In addition to making programs more modular, concurrent computation can provide a speed advantage over sequential computation. Sequential computers execute only one operation at a time, so the amount of time it takes to perform a task is proportional to the total number of operations performed. However, if it is possible to decompose a problem into pieces that are relatively independent and need to communicate only rarely, it may be possible to allocate pieces to separate computing processors, producing a speed advantage proportional to the number of processors available.

Unfortunately, the complexities introduced by assignment become even more problematic in the presence of concurrency. The fact of concurrent execution, either because the world operates in parallel or because our computers do, entails additional complexity in our understanding of time.


finish this during section

Exercise 1.

For this lab you'll need three people, each on a separate workstation. One person should choose to be the server, and should do this:

> (load "~cs61as/lib/im-server.scm")
> (im-server-start)

Make a note of the IP address and port number that this prints! The other people will be clients. They should do this:

> (load "~cs61as/lib/im-client.scm")
> (im-enroll "" 6543) ; use actual numbers from server!

but using the server's IP address instead of and the server's port number instead of 6543. (Note that the IP address must be enclosed in quotation marks.)

The clients can then send each other messages:

> (im 'cs61as-xy "Hi there, how are you?")

The messages can't include more than one line.

A client can leave the IM system by running

> (im-exit)

The server can quit (which disconnects all the clients) with

> (im-server-close)


This lab is short so that you can start on the homework early. It'll be easier to test your work with several people. Also, the homework is slightly longer than usual.


do this in section if possible; finish the rest at home

Client/Server Questions:

These exercises use the Instant Message program, found in the following files:


Exercise 2.

Invent the capability to send a message to a list of clients as well as to a single client. Do this entirely in the client program, so what actually goes to the server is multiple requests.

Exercise 3.

Invent the capability to broadcast a message to every client. Do this by inventing a broadcast command that the server understands.

Exercise 4.

Could #2 have been done with the server doing part of the work? Could #3 have been done entirely in the client code? Compare the virtues of the two approaches.

Exercise 5.

Invent the capability of refusing messages from specific people. The sender of a refused message should be notified of the refusal. Decide whether to do it entirely in the client or with the server's cooperation, and explain why.

Exercise 6.

Why is the 3-way handshake necessary when connecting to the server?

Concurrency Questions

To work with the ideas in this section you should first

(load "~cs61as/lib/concurrency.scm")

Exercise 7.

Exercise 3.38, 3.39, 3.40, 3.41, 3.42, 3.44, 3.46, 3.48, of Abelson & Sussman

Exercise 8.

Do the following reading:

Extra for Experts

Do this if you want to. This is NOT for credit.

Exercise 9.

Using the Instant Message program as a starting point, write a mail server and client. The mail server should maintain a database of messages for all users. (This can just be a list; don't worry about efficient lookup.) The client should be able to do the following:

(mail username message)

Get-mail should return a list of messages, which should be deleted from the server.

If you want, you can improve this in several ways: Make deletion from the server be explicitly requested by the client, invent a subject header (another argument to mail) and have the client show just headers in get-mail and provide another command to read thetext of a specific message, and so on.

Exercise 10.

Read Section 3.3.5 and do exercises 3.33 - 3.37.