In this lab, you will experiment with the C socket interface. Optionally, you may implement a simple multi-user chat application.
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). The assignment also draws upon my long experience with undergraduate networking assignments.
select() I/O multiplexing API and implement a simple, but real, network application.You may work individually or in pairs. You have one week to complete this assignment.
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.
Stevens, UNIX Network Programming, Volume 1, Chapter 6
man 2 socket and other related manpages from section 2:
listen, accept, connect, send, recvsendto, recvfromOpen 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.
Open a third terminal. Create a small file with a few lines of content. While the first client is running, start the 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?
Wait a bit, then make the first client exit. What happens?
Change the server constant MAX_PENDING to 1, recompile, and repeat steps 1-3. What happens?
Investigate the messages sent by the client and server.
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.)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 localhost < 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.
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.
Make a new version of the simplex-talk client and server that use UDP as the transport protocol, rather than TCP.
Make copies of the source files named udp-talk.c and udp-talk-server.c.
In both client and server, change SOCK_STREAM to SOCK_DGRAM.
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.)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.)
Compile and test your client and server.
See what happens when multiple such UDP clients simultaneously connect to the same UDP server. Compare this to the TCP behavior.
Based on the code from part A, implement a simple, multi-client chat application. Review the feature list, then follow the implementation plan below.
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.
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.
Create a server that can handle multiple simultaneous clients.
simplex-talk-server.c to chat-server.c.select() to make the server wait until either there is a new client to accept or until some existing client socket is ready to read. As
client sockets are accepted, add them to the file descriptor set and to
an array of client socket file descriptor numbers. When the client
sockets are closed, remove them. When there is data to read, read
it and echo it back on the same socket. The example code does just
about everything you need to do.simplex-talk clients at the same time. The server should be able to accept connections from multiple clients and echo their messages back.signal() syscall to make the server ignore the SIGPIPE signal.Create a client that can handle user input or messages from the server at any time.
simplex-talk.c to chat.c.stdin or the socket at any time. Text from stdin should be sent over the socket; data from the socket should be displayed to the screen.stdin is defined as STDIN_FILENO in <unistd.h>.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.
Add handling of usernames.
strncopy(), strncat(), and/or snprintf() useful.)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.
This assignment involves programming, so start early and ask for help if you run into trouble. Keep me posted on how it is going. I may be willing to give an extension if I learn by next Wednesday or so that more time is needed.
Stevens and the manpages are your friends.
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.
select()?Janet Davis (davisjan@cs.grinnell.edu)
Created February 7, 2009