//tcp client
// can work on unix or windows machines
// this program tests the time it takes to transfer a fixed file size by varying the packet size
#define WIN
//#define BSD
//i/o stuff
#include < stdio.h > //printf
#include < iostream.h > //cout
#include < fstream.h >
//misc
#include < time.h > //clock_t, clock()
#ifdef WIN
#include < windows.h >
#include < malloc.h >
#else //BSD
#include < sys/types.h >
#include < sys/socket.h >
#include < netinet/in.h >
#include < arpa/inet.h >
#include < netdb.h >
#endif
#define MESS_SIZE 1000000 /* file size equal 1,000,000 bytes */
#define PORTNUM 18000 /* the port # the server is listening to */
#define REPEAT 2
#define MAX_PACKET_SIZE 65507 //65495 //ie. 2^16 - 1 - 20 - 20
//set time out for lost datagram
void setTimeout( int ) ;
void crunch( int socketid ) ;//crunch out numbers
/* Main ============================================================ */
void main(int argc, char *argv[] )
{
int port = PORTNUM; /* the port number agrred upon server & writer */
int server_len; /* length for sockaddr for the server */
int socketid; /* the socket ID */
int status; /* error status holder */
/* --- socket address in the Internet --- */
struct sockaddr_in serverINETaddress;
struct hostent *myhostent;
#ifdef WIN
WORD wVersionRequested = MAKEWORD( 1, 1 ) ;
WSADATA wsaData ;
WSAStartup( wVersionRequested, &wsaData ) ;
#endif
cout << "clocks per sec = " << CLOCKS_PER_SEC << endl;
/* --- Get Internet address --- */
myhostent = gethostbyname("131.247.2.16");
server_len = sizeof(serverINETaddress);
#ifdef WIN
memset( (char *)&serverINETaddress, 0, server_len ) ;
memcpy( (char *)&serverINETaddress.sin_addr,
(char *)myhostent->h_addr,
myhostent->h_length ) ;
#else
bzero((char *)&serverINETaddress, server_len);
bcopy((char *)myhostent->h_addr,
(char *)&serverINETaddress.sin_addr,
myhostent->h_length);
#endif
serverINETaddress.sin_family = AF_INET;
serverINETaddress.sin_port = htons(port);
/* end getting address */
/* --- Create a socket --- */
socketid = socket( AF_INET, SOCK_STREAM, 0 ) ;
if( socketid < 0 )
{
printf("Error in creating a socket.\n") ;
exit(-1) ;
}
/* --- Connecting the socket --- */
status = connect(socketid,
(struct sockaddr *)&serverINETaddress,
server_len);
if( status < 0 )
{
printf("Error in connecting.\n");
exit(-1);
}
//set timed out to 5 seconds
setTimeout( socketid ) ;
/* do it all */
crunch( socketid ) ;//ie. crunch out numbers
//all done
#ifdef WIN
closesocket( socketid ) ;
WSACleanup() ;
#else
close(socketid);
#endif
}
void setTimeout( int my_s )
{
struct timeval tv ;
tv.tv_sec = 10000 ;//2 seconds
tv.tv_usec = 0 ;
#ifdef WIN
setsockopt( my_s,
SOL_SOCKET,
SO_RCVTIMEO,
(char FAR *)&tv,
sizeof( tv ) );
#else //BSD
setsockopt( my_s,
SOL_SOCKET,
SO_RCVTIMEO,
(char *)&tv,
sizeof( tv ) ) ;
#endif
}
void crunch( int socketid )
{
int i, //loop variable
packet_size, //another loop variable
changeable_packet,
buffer_left,
lost_packets = 0 ;//count of
long int n ;
long double clock_diff,
total_clock1,
total_clock2 ;
char *sendline = new char[ MESS_SIZE ]; // Buffer for output data
char *recvline = new char[ MESS_SIZE + 1 ]; // Buffer for output data
clock_t clock1, clock2;
fstream outfile ;
cout << "size of long int = " << sizeof( long int ) << endl ;
cout << "just checking\n" << endl;
//open file
outfile.open( "outfile_tcp.dat", ios::out ) ;
//file header
outfile << "packet_size" << " " << "time( sec )\n\n" ;
//the loop
for( packet_size=3600; packet_size<=MAX_PACKET_SIZE; packet_size+=10 )
{ //actually, packetsize = 20 ip_header + 20 tcp_header + packet_size
clock_diff = 0 ; //reset clocks
for( i=0; i< REPEAT; i++ )//statistically do 5 times
{
total_clock1 = 0;//reset total to zero
total_clock2 = 0;
changeable_packet = packet_size ;
buffer_left = MESS_SIZE ;//will decrease buffer size in do loop
do
{
clock1 = clock() ;//start timer
send( socketid, //in sendto, 28, ie 20 + 8, more bytes will be added
sendline,
changeable_packet,
0 ) ;
n = recv( socketid, //receive acknowledgement
recvline,
changeable_packet + 1,
0 ) ;
//cout << "n = " << n << endl ;
clock2 = clock() ;//end timer
if( n<0 )//timed out, resend packet
{
cout << "timeout" << endl;
cout << "resending packet " << packet_size << endl;
//for fun, count number of lost packets
lost_packets++ ;
//go back to beginning of do loop
continue ;
}
total_clock1 += (double)clock1 ;
total_clock2 += (double)clock2 ;
buffer_left -= packet_size ;//decrease buffer size
if( buffer_left < packet_size )//update packet
changeable_packet = buffer_left ;
}while( buffer_left > 0 ) ;
//add up 5 times then divide by 5 to get average
clock_diff = clock_diff +( total_clock2 - total_clock1 );
}//end sampling five times
//output to screen
cout << endl
<< "packet_size = " << packet_size
<< " diff in clocks in secs = " << clock_diff / (REPEAT*CLOCKS_PER_SEC)
<< " packets returned = " << n
<< endl ;
//output to file
outfile << packet_size << " "
<< clock_diff/(REPEAT*CLOCKS_PER_SEC) << "\n" ;
}//end for loop
cout << "total lost packets... " << lost_packets << endl ;
outfile.close() ;
delete [] sendline ;
delete [] recvline ;
}