V22.0480-005 Lab 1: Simple TCP client

Due date: Thursday Jan. 29, 11:59pm.

Reading:

Introduction

In this lab assignment you will write a simple network client. Your client will send text specified on the command line to a remote server, and output the text received back from the server.

You'll be writing this simple client to learn about how to use the socket abstraction and its associated system calls. These calls are useful in order to build networking applications. Your later labs will build heavily upon these few system calls, so it is important that you feel very comfortable with their use.

In this lab, we use client to mean an application program that establishes connections for the purpose of sending data. You use such programs in everyday life, e.g., your web browser. We use server to mean an application program that accepts connections in order to service requests by sending back responses, e.g., the Apache web server.

For this lab, all network communication will occur over TCP -- the transmission control protocol. We will learn about TCP later in the course; from the application writer's point-of-view, once a TCP connection is established between a client and server, if one party writes a stream of data into its socket, the other party reliably receives the same stream of data out from its socket.

For more information about sockets and the various system calls we will use throughout the lab, please see the IPC Tutorial, as well as following man pages:

% man tcp
% man connect
% man send
% man recv

Design Requirements

Your client will create a blocking TCP socket, connect to a specified server address, and send text as specified on the command line. The client will read the data returned from the server, and output it to stdout.

By blocking, we mean that your client does not need to handle asynchronous events -- i.e., after you write to the server, you can just wait until you receive data back from the server. Most full-fledged client-server applications handle non-blocking operations -- i.e., the client continually polls whether it can send out data or has received data, and interleaves such accesses. We'll write such applications later in the term.

Your simple client application should be run in the following way:

 
% ./sc [hostname|ipaddr] [port] [string]

where the first argument can be a hostname (e.g., scs.cs.nyu.edu) or an IP address (e.g., 216.165.108.70) on which the server runs, the second argument is the port on which the server listens on its host, and the third argument is the string that the client should send to the server.

Your simple client application should output to stdout any data received back from the server.

Getting Started

We have provided a skeleton sc project directory. It is available in ~class/src/sc.tar.gz. Start by unpacking the source code in your home directory. On the class machines, you can do so with the following commands:

% tar xzf ~class/src/sc.tar.gz
% cd sc
% setenv AUTOCONF_VERSION 2.13
% sh ./setup
automake: configure.in: installing `./install-sh'
automake: configure.in: installing `./mkinstalldirs'
automake: configure.in: installing `./missing'
configure.in: 22: required file `./ltconfig' not found
automake: Makefile.am: installing `./INSTALL'
automake: Makefile.am: installing `./COPYING'
+ autoconf
+ set +x
% 

The skeleton source tree contains source file sc.c, where you need to implement your simple client.

Next, you must configure the software and generate a Makefile--a set of instructions for how to compile the software. For this class, we will use the GNU autoconf and automake tools to generate Makefiles. On the class machines, generate the Makefile with the following commands:
% setenv DEBUG -g
% ./configure
creating cache ./config.cache
checking for a BSD compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking whether make sets ${MAKE}... yes
checking for working aclocal... found
checking for working autoconf... found
checking for working automake... found
checking for working autoheader... found
...
updating cache ./config.cache
creating ./config.status
creating Makefile
creating config.h
% 

Once the software is configured, you can build sc by running gmake. (Note that this is gmake with a g, and not make.)

% gmake
gcc -DHAVE_CONFIG_H -I. -I. -I.     -g -O2 -c sc.c
/bin/sh ./libtool --mode=link gcc  -g -O2 -static -o sc  sc.o  
mkdir .libs
gcc -g -O2 -o sc sc.o 
% 
That's it! You've now built sc.

You might wish to test your client using the following commands. Following the cmd-line arguments are the expected output you should receive.

% ./sc ludlow.scs.cs.nyu.edu 79 mfreed
Login: mfreed                           Name: Michael J. Freedman
Directory: /home/u1/mfreed              Shell: /usr/local/bin/tcsh
On since Tue Jan 13 18:06 (EST) on ttyp1, idle 0:23, from w70.scs.cs.nyu.edu
On since Tue Jan 13 16:43 (EST) on ttyp2, idle 0:17, (message 2B       s off)
    from w70.scs.cs.nyu.edu
No Mail.
No Plan.

The finger displays information about the system users. The fingerd server runs on port 79. Compare that with running the finger command yourself.

% finger user@ludlow.scs.cs.nyu.edu
where user is mfreed or dm

In order to translate a hostname like ludlow.scs.cs.nyu.edu to an in_addr, you can use the system call gethostbyname. See its man pages or the text for more information.

Try a simple HTTP GET request, much like a web browser sends:

% ./sc 216.165.108.9 80 "GET /"
You should receive back a HTML page.

Requirements

You should make sure your client satisfies these requirements: The necessary CRLF is equivalent to pressing "return" in interactive mode. For example, try typing "telnet www.scs.cs.nyu.edu 80", then typing "GET \" and hitting return. Or, try "telnet ludlow.scs.cs.nyu.edu 79", then typing "mfreed" and hitting return.

Collaboration policy

You must write all the code you hand in for the programming assignments, except for code that we give you as part of the assigment. You are not allowed to look at anyone else's solution (and you're not allowed to look at solutions from previous years). You may discuss the assignments with other students, but you may not look at or copy each others' code.

How/What to hand in

You must submit two files: To build a software distribution, run the command:
% gmake distcheck
rm -rf sc-0.0
mkdir sc-0.0
chmod 777 sc-0.0
here=`cd . && pwd`; \
top_distdir=`cd sc-0.0 && pwd`; \
distdir=`cd sc-0.0 && pwd`; \
cd /home/c/dm/sc \
  && automake-1.4 --include-deps --build-dir=$here --srcdir-name=/home/c/dm/sc --output-dir=$top_distdir --gnu Makefile
chmod -R a+r sc-0.0
...
gmake[1]: Leaving directory `/disk/c3/scratch/dm/sc-0.0/=build'
rm -rf sc-0.0
==============================================
sc-0.0.tar.gz is ready for distribution
==============================================
% 
To turn in your distribution, copy it to the directory ~class/handin/lab1/username where username is your username:
% cp sc-0.0.tar.gz ~class/handin/lab1/`logname`/
% 
To create a script file, use the script command. When you run script, everything you type gets saved in a file called typescript. Press CTRL-D to finish the script. The typescript should be copied to the same directory as the software distribution. For example:
% script
Script started, output file is typescript
% ./testsc ./sc
Connection to invalid IP address: passed
Finger to valid hostname: passed
HTTP to valid hostname: passed
Connection to valid IP address: passed
Connection to invalid port: passed
Connection with long input string: passed
Finished test...0 failed
% ^D Script done, output file is typescript
% cp typescript ~class/handin/lab1/`logname`/
% 
If you have any problems about submission, please contact the TA or instructor.