//------------------------------------------------------------------- // tcpstress.cpp // // This modification of our earlier 'tcpclient.cpp' establishes // a rapid succession of connections and data-exchanges with an // echo-server, in order to reveal design-flaws in the server's // responsiveness or in its disposition of any child-processes. // // to compile: $ g++ tcpstress.cpp -o tcpstress // to execute: $ ./tcpstress // // programmer: ALLAN CRUSE // written on: 11 MAR 2009 //------------------------------------------------------------------- #include // for gethostbyname(), socket() #include // for printf(), perror() #include // for exit() #include // for read(), write(), close() #include // for strncpy() #define DEMO_PORT 54321 int main( int argc, char **argv ) { //------------------------------------------------- // get the server's hostname from the command-line //------------------------------------------------- if ( argc == 1 ) { fprintf( stderr, "must specify server\n" ); exit(1); } char peername[ 64 ] = { 0 }; strncpy( peername, argv[ 1 ], 63 ); //-------------------------------------- // obtain the IP-address for the server //-------------------------------------- struct hostent *pp = gethostbyname( peername ); if ( !pp ) { herror( "gethostbyname" ); exit(1); } //-------------------------------------------- // construct a socket-address for that server //-------------------------------------------- struct sockaddr_in paddr = { 0 }; socklen_t palen = sizeof( paddr ); paddr.sin_family = AF_INET; paddr.sin_port = htons( DEMO_PORT ); paddr.sin_addr.s_addr = *(int32_t*)pp->h_addr; //----------------------------------- // initialize our connection counter //----------------------------------- int count = 0; //----------------------------------------------------------- // main loop to initiate a rapid succession of many separate // server connections, exchanges-of-data, and disconnections // in order to stress-test that server's adequacy under load //----------------------------------------------------------- while ( ++count < 10000 ) { //------------------------------------------------ // construct the message to be sent to our server //------------------------------------------------ char msg[ 80 ] = { 0 }; int len = sprintf( msg, "This is message number " ); len += sprintf( msg+len, "%d \n", count ); //--------------------------------------------------- // create a socket for communication with the server //--------------------------------------------------- int sock = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP ); if ( sock < 0 ) { perror( "socket" ); exit(1); } //---------------------------------------- // establish a connection with the server //---------------------------------------- if ( connect( sock, (sockaddr*)&paddr, palen ) < 0 ) { perror( "connect" ); exit(1); } //------------------------------------------------------- // write the message-characters to the socket one-by-one //------------------------------------------------------- for (int i = 0; i < len; i++) if ( write( sock, msg+i, 1 ) < 0 ) { perror( "write" ); break; } //---------------------------------------------- // shut down the writing end of this connection //----------------------------------------------- fflush( fdopen( sock, "rw" ) ); if ( shutdown( sock, SHUT_WR ) < 0 ) perror( "shutdown" ); //----------------------------------------- // receive all the replies from the server //----------------------------------------- char buf[ 128 ] = { 0 }; for (int i = 0; i < len; i++) { int rx = read( sock, buf+i, 1 ); if ( rx < 0 ) { perror( "read" ); break; } if ( rx == 0 ) break; } //-------------------------------------------------- // close the socket and release its file descriptor //-------------------------------------------------- if ( close( sock ) < 0 ) perror( "close" ); //------------------------------------------------- // display the characters received from the server //------------------------------------------------- puts( buf ); } printf( "\n" ); }