Implementing Network Applications with Sockets

Due date

Monday, February 20, 2012

Introduction

In this lab, you will experiment with the C socket interface. Optionally, you may implement a simple multi-user chat application.

Acknowledgments

Parts of this assignment are adapted from exercises 1.34 - 1.36 in Peterson & Davie, Computer Networks: A Systems Approach (Morgan Kaufmann, 4th ed., 2007).

Goals

Logistics

Because this assignment involves programming in C and learning new APIs, I strongly encourage you to work with a partner. You have one week to complete this assignment.

You may complete this lab on any MathLAN workstation.

Preparation

Review P&D 1.4, "Implementing network software."

Obtain the source code for the example client and server from this reading: simplex-talk.c and simplex-talk-server.c. Verify that you can build these programs using gcc.

Obtain a copy of Chapter 6 of Stevens, UNIX Network Programming, Volume 1, to be distributed in class. You will need this for part C.

References

Assignment

Part A: Experiments with TCP sockets

  1. Open two terminals; run the server in one and the client in the other. Verify that you are able to send messages from the client to the server. Leave both the server and the client running.

  2. Open a third terminal. Create a small file with a few lines of content. While the first client is running, start nine other clients; these other clients should be started in the background with their input redirected from a file. For example,

    ./simplex-talk localhost < smallfile &

    What happens to these ten clients? Do their connect()s fail, or time out, or succeed?

  3. Wait a bit, then make the first client exit. What happens?

  4. Change the server constant MAX_PENDING to 1, recompile, and repeat steps 1-3. What happens?

  5. Investigate the messages sent by the client and server.

    1. Run the Wireshark packet capture and analysis program with the command sudo wireshark. You will be prompted for your password.
    2. Under the Capture menu, choose Options. In the text field labeled Capture filter, type "tcp port 7701" (no quotes), directing Wireshark to capture only packets sent by our application. Then click the "Start" button.
    3. ssh to another MathLAN machine and start the server there. (If you're in the lab, you can log on at a second computer instead.)
    4. On the first computer, start the client. Type several messages.  Type one very long message (at least 4  lines) without hitting Enter. (Hint: Cut and paste is your friend.)
    5. Quit the client and stop the capture.
    6. Verify that the trace includes only packets from your application. How many are there? What is the correspondence between messages and packets? What do you think is happening?
  6. Obtain the file a200, which contains 200 copies of the letter a, each on its own line. Transmit this file to the server:

    ./simplex-talk server_hostname < a200 &

    How many copies of the letter a appear on the server? Formulate a hypothesis as to why this is happening. To inform your hypothesis, you may wish to use Wireshark, as above, to determine how many packets are sent. After you've thought about it, check this hint.

    In your lab notebook, explain the problem and include a code snippet that shows how you fixed it. You should modify only the loop for receiving and displaying data from the socket.

  7. Implement echo behavior: Modify the client and server so that each time the client sends a line to the server, the server sends the line back to the client. The client (and server) will now have to make alternating calls to recv() and send(). Verify that this new version behaves as expected.

Part B: Experiments with UDP sockets

Make a new version of the simplex-talk client and server that use UDP as the transport protocol, rather than TCP.

  1. Make copies of the source files named udp-talk.c and udp-talk-server.c.

  2. In both client and server, change SOCK_STREAM to SOCK_DGRAM.

  3. In the client, remove the call to connect(). Rather than using the send() syscall, use the sendto() syscall, which requires you to provide the destination address with each buffer that you send. (This better matches UDP's connectionless datagram model.)
  4. In the server, remove the calls to listen() and accept(), and replace the two nested loops at the end with a single loop that calls recvfrom() with the socket s. (Using recvfrom() allows the server to learn who has sent each packet, even though there is not a connection.)

  5. Compile and test your client and server.

  6. See what happens when multiple such UDP clients simultaneously connect to the same UDP server. Compare this to the TCP behavior.

Part C: A multi-client chat application

Based on the code from part A, implement a simple, multi-client chat application. Review the feature list, then follow the implementation plan below.

Client features:

Server features:

Implementation plan:

You will implement this behavior in a new client and server. Rather than using multiple processes or multi-threading, you will use the select() syscall to multiplex a set of file descriptors.

  1. Skim Stevens, chapter 6, focusing his explanation and uses of the select() syscall. Pay particular attention to Figure 6.9 (p. 157) and Figures 6.21 and 22 (p. 165-166). You need not read about poll(), although I included it for completeness

  2. Create a server that can handle multiple simultaneous clients.

  3. Create a client that can handle user input or messages from the server at any time.

  4. Modify the server so that it echoes messages to all clients, not only the client that sent the message. This means that each user can see the messages sent by all the other users.

  5. Add handling of usernames.

Assessment

To earn a B, complete parts A and B along with the discussion questions.

To earn an A, complete parts A, B, and C, along with the discussion questions. Save copies of your work; I will give partial credit for a partially complete part C.

Advice

This assignment involves programming, so start early and ask for help if you run into trouble. Keep me posted on how it is going.

Stevens and the manpages are your friends.

Lab Notebook

In the lab notebook, include your observations and answers from parts A and B, and your answers to the discussion questions.

Attach your final programs from exercise A.7, part B, and part C (if you did that part). 

In your writeup, copy and paste a small amount of output from the terminal showing that these programs work correctly. Mark this up using <verbatim></verbatim> tags.

Discussion Questions

  1. In exercise A.5, I told you to to run the server on a different machine from the client, because otherwise Wireshark would not have captured any packets. Why not?
  2. Think back to exercise A.6. What did Peterson & Davie implictly assume about the relationship between TCP packets and messages typed by users? Why is this assumption false?
  3. What are the relative merits (pros and cons) of using TCP versus UDP for a multi-client chat room application?
  4. How much time did you spend on each of the three parts of this lab? Do you think future students should be required to learn about select()?

Hint on the a200 problem

Carefully read the manpage for fputs, which is used in the server code. What is required of the input string? Does the data contained in the buf variable necessarily meet this requirement?

Also have a look at the client and what it is doing. It is causing part of the problem as well by sending a little bit more data than it really should.

If you are stuck, please write this in your lab book and go on!


Janet Davis (davisjan@cs.grinnell.edu)

Created February 7, 2009
Last revised February 15, 2012