CSS 432
Program 1: Basic TCP Communication
Professor: Munehiro Fukuda
Due date: See the syllabus
1. Purpose
This assignment exercises basic TCP communication and evaluates its
performance over 1Gbps networks. You are to observe how RTT (round
trip time) grows as increasing the size of data to send over 1Gbps
point-to-point communication.
2. Client-Server Model
In all your programming assignments through to the final project, your
program will use the client-server model where a client process
establishes a connection to a server, sends data or requests, and
close the connection while the server sends back responses or
acknowledgments to the client.
3. TCP Communication
HW1 focuses on basic TCP communication between a client and a server
process. To establish such communication, those processes should
perform the following sequence of operations:
Client
- Use argv[0] as the C string that stores a server IP name.
- Retrieve a hostent structure corresponding to this IP name
by calling gethostname( ).
struct hostent* host = gethostbyname( argv[1] );
- Declare a sockaddr_in structure, zero-initialize it by
calling bzero, and set its data members as follows:
int port = YOUR_ID; // the last 5 digits of your student id
sockaddr_in sendSockAddr;
bzero( (char*)&sendSockAddr, sizeof( sendSockAddr ) );
sendSockAddr.sin_family = AF_INET; // Address Family Internet
sendSockAddr.sin_addr.s_addr =
inet_addr( inet_ntoa( *(struct in_addr*)*host->h_addr_list ) );
sendSockAddr.sin_port = htons( port );
- Open a stream-oriented socket with the Internet address family.
int clientSd = socket( AF_INET, SOCK_STREAM, 0 );
- Set the NODELAY option. (Note this option is necessary to
observe the TCP's segmentation behavior clearly in HW1. Don't use this
option in the other assignments.)
const int on = 1;
setsockopt( clientSd, IPPROTO_TCP, TCP_NODELAY, (char *)&on, sizeof( int ) );
- Connect this socket to the server by calling connect as
passing the following arguments: the socket descriptor, the
sockaddr_in structure defined above, and its data size
(obtained from the sizeof function).
connect( clientSd, ( sockaddr* )&sendSockAddr, sizeof( sendSockAddr ) );
- Use the write system call to send data.
- Use the read system call to receive a response from the
server.
- Close the socket by calling close.
close( clientSd );
Server
- Declare a sockaddr_in structure, zero-initialize it by
calling bzero, and set its data members as follows:
int port = YOUR_ID; // the last 5 digits of your student id
sockaddr_in acceptSockAddr;
bzero( (char*)&acceptSockAddr, sizeof( acceptSockAddr ) );
acceptSockAddr.sin_family = AF_INET; // Address Family Internet
acceptSockAddr.sin_addr.s_addr = htonl( INADDR_ANY );
acceptSockAddr.sin_port = htons( port );
- Open a stream-oriented socket with the Internet address family.
int serverSd = socket( AF_INET, SOCK_STREAM, 0 );
- Set the NODELAY option. (Note this option is necessary to
observe the TCP's segmentation behavior clearly in HW1. Don't use this
option in the other assignments.)
const int on = 1;
setsockopt( serverSd, IPPROTO_TCP, TCP_NODELAY, (char *)&on, sizeof( int ) );
- Bind this socket to its local address by calling bind as
passing the following arguments: the socket descriptor, the
sockaddr_in structure defined above, and its data size.
bind( serverSd, ( sockaddr* )&acceptSockAddr, sizeof( acceptSockAddr ) );
- Instructs the operating system to listen to up to five connection
requests from clients at a time by calling listen.
listen( serverSd, 5 );
- Receive a request from a client by calling accept that will
return a new socket specific to this connection request.
sockaddr_in newSockAddr;
socklen_t newSockAddrSize = sizeof( newSockAddr );
int newSd = accept( serverSd, ( sockaddr *)&newSockAddr, &newSockAddrSize );
- Use the read system call to receive data from the
client. (Use newSd but not serverSd in the above code example.)
- Use the write system call to send back a response to the
client. (Use newSd but not serverSd in the above code example.)
- Close the socket by calling close.
close( newSd );
You need to include the following header files so as to call these OS functions
#include <sys/types.h> // socket, bind
#include <sys/socket.h> // socket, bind, listen, inet_ntoa
#include <netinet/in.h> // htonl, htons, inet_ntoa
#include <arpa/inet.h> // inet_ntoa
#include <netdb.h> // gethostbyname
#include <unistd.h> // read, write, close
#include <string.h> // bzero
#include <netinet/tcp.h> // TCP_NODELAY
Socket.h and Socket.cpp
If you would like to take an easy-going option, you may use
Socket.h and Socket.cpp that the professor has
implemented in ~css432/hw1/. In this case, you don't need to
include the header files listed above. However, there are few comments
in these files. At least, you have to learn how to use this class. :-)
4. Statement of Work
Write a program that establishes a TCP connection from a client to a
server, sends data from the client to the server as incrementing the
data size, and sends back an acknowledgment from the server to the
client. Your program must repeat the following iteration as changing
data size from 100 bytes to 20,000 bytes by 100 bytes. For each
iteration:
Client
- Open a new socket and establish a connection to a server.
- Start a timer by calling gettimeofday.
- Send a given size of data to the server.
- Receive a one-byte acknowledgment from the server.
- Stop the timer by calling gettimeofday.
- Prints out the data size, a space " ", and elapsed time in usec
to the standard output.
- Close the socket.
- Increment the data size by 100 bytes and go back to the top.
Server
- Accept a new connection. (The very first socket should be
opened and bound before this iteration.)
- Read data from the client. Note that the read system
call may return without reading the entire data if it is
unavailable to read. You may have to repeat calling read
like:
for ( int nRead = 0; ( nRead += read( sd, buf, size - nRead ) ) == size; );
Check the manual page for read carefully.
- Write a one-byte acknowledgment to the client.
- Close this connection.
- Go back to the top.
You should write only one program that should identify with
argc if it is a client or a server. Your program invocation
should be:
Server Side:
$ a.out
Client Side:
$ a.out serverIpName > result
where result stores all standard output messages from your
a.out program. Make sure that you must start your server first.
You must conduct performance evaluation over 1Gbps network. The linux
machines of uw1-320-00 ~ uw1-320-15 are connected to
100Mbps Ethernet, while uw1-320-16 ~
uw1-320-31 are connected to 1Gbps Ethernet. Thus, what you have
to do is
- Login any two of 1Gbps-connected machines and evaluate the 1Gbps
performance. Store your result in the 1gbps.dat file.
Client Side:
$ a.out serverIpName > 1gbps.dat
- Print out those results using gnuplot. Copy the
~css432/hw1/tcp.plt file to the same directory where your
result files exist, and run gnuplot tcp.plt which generates
tcp.ps
cp ~css43/hw1/tcp.plt .
gnuplot tcp.plt
- Convert an obtained ps file in a pdf file and view it with
evince. Specifically, type as follows:
ps2pdf tcp.ps
evince tcp.pdf
- You may have to repeat this evaluation several times until you
obtain a very clear graph.
5. What to Turn in
The homework is due at the beginning of class on the due date. You
have to turn in the following materials in hard copy. No email
submission is accepted.
Criteria |
Percentage |
Documentation of your algorithm
including explanations and illustrations in one or two pages |
2pts(10%) |
Source code that adheres good
modularization, coding style, and an appropriate amount of
comments. The source code is graded in terms of (1) Correct tcp socket
establishments, (2) correct data/ack transfers, (3) Use of gettimeday,
(4) performance evaluating code, and (5) comments, etc. |
5pts(25%) |
Execution output such as a snapshot
of your display/windows. Type import -window root X.jpeg;
lpr -Puw1-320-p1 X.jpeg on a uw1-320 linux machine. Or,
submit partial contents of standard output redirected to a file. You
don't have to print out all data. Just one page evidence is
enough. |
1pts(5%) |
Performance evaluation that prints
out the tcp.ps (or tcp.pdf) file. (NOTE! NOTE! NOTE! your elapsed
time should grow in steps rather than linearly)
| 6pts(30%) |
Discussions should be given for
1Gbps performance in terms of MSS (1448bytes), MTU (1500bytes), socket
buffers (16384bytes), the Linux page size (4096bytes), and advertized
window size (the multiplicaiton of MSS). |
6pts(30%) |
Total |
20pts(100%) |
6. FAQ
This FAQ page may answer your quetions.
Click here