Client-Server

Client-server programming is a nifty little paradigm you use every day: to browse the web, to send e-mails, to connect to the inst machines, and to play online games. The idea is that a number of client machines connect to a server, and ask the server for various things (send this e-mail for me, get the contents of this web page). One common use of the server is to interact with other clients (IM this person, start a StarCraft game with that person).

We're going to use the IM client and server from lecture and lab as an example program for this discussion.

Terminology

Let's pause to go over some buzzwords terminology here. These are the big ideas of our short demo of client-server programming.

It's worth noting that callbacks are used all over the place, not just in client-server programming.

Network Communication

Using the IM application is pretty easy. You just im-enroll with the server you want, and im the people you want to talk to. When you're done, im-exit lets you disconnect cleanly from the server. Open up the source files, though, and there's a lot more going on…

im‑enroll
  1. Client sends a hello request to the server
  2. Server checks to see if the client's name is in use
  3. Server sends a welcome request to the client
  4. Client sends a thanks request to the server
  5. Server updates its list of clients.
  6. Server broadcasts a client-list message to all clients (data: new list of clients)
im
  1. Client sends a send-msg request to the server
  2. Server checks if the destination client exists (is logged on)
  3. If the destination client exists, the server sends a receive-msg request to it.
  4. If the destination doesn't exist, the server sends a receive-msg request to the source client.
  5. The receiving client displays "Message from sender: " and the message.
im‑exit
  1. Client sends a logout request to the server.
  2. Server sends a goodbye request to the client.
  3. Client closes its connection and cleans up.
  4. Server updates its list of clients.
  5. Server broadcasts a client-list request to all clients (data: new list of clients)

Even this leaves out a bunch of error-handling (and logging) that's going on in the code. For instance, the im procedure looks like this:

(define (im who message)
  ;;;Send message to who.
  (if (not
       (send-request (make-request whoiam who 'send-msg message) 
                     port-to-server))
      (close-connection)))

This takes advantage of the fact that the send-request procedure is set up to return #f if there's a problem in sending the request. If there was a problem, we should clean up after ourselves.

If send-request returns #t, does that mean the server got the message? Not necessarily! The request could still get lost on AirBears, or blocked by the server's firewall, or any number of problems. With networking, there's no way to tell if your message failed, or if it's just taking a long time.

As for how the request is actually sent, it's broken down into fixed-sized chunks called packets, which are tagged with the source and destination addresses (those strings like 128.32.42.27, eventually to be replaced by a longer ID like 0:0:ffff:0:0:8020:2a1b), the source and destination port numbers (which identify sockets, remember), and a few other things, like a connection ID. These packets are then fired across the network from computer to router to ISP, across the Internet, and down to a computer again—or just computer to router to computer on the same network, and just within the computer when you have two programs on star.cs talking to each other. You'll learn more about this if you take CS 162 Operating Systems.

Peer-to-peer Systems

What's the difference between client and server? They both have sockets and ports. They both send and receive requests. They seem pretty similar.

Indeed, the only difference between clients and servers is one of responsibility. That is, they do different things. In the IM program, it's the server's responsibility to keep track of all clients, and to match client names up with the correct connections. This way, the clients don't have to keep track of this stuff. (Notice that clients never send requests to each other, only to the server.)

This isn't fixed, however. You can have a networked system in which everyone behaves equally, rather than communicating with a central source. In this case, every "client" functions as a peer; this is what "peer-to-peer" file-sharing means.

Often, there's still a central "server" that keeps track of everyone who's online. But when one peer wants to talk to another, they just do so directly, rather than having the server forward all messages to their final destinations.

Back to Jordy's home page | Course home page