//------------------------------------------------------------------- // tcpclient2.cpp // // This is a 'cut-and-paste' rearrangement of the code from our // previous 'tcpclient.cpp' application, which will allow us to // demonstrate a design-deficiency with 'iterative' servers for // most connection-oriented client/server applications, and the // advantage of adopting a 'concurrent' server-design paradigm. // Specifically this client now establishes the connection with // its server before it obtains keyboard-input typed by a user. // // to compile: $ g++ tcpclient2.cpp -o tcpclient2 // to execute: $ ./tcpclient2 // // programmer: ALLAN CRUSE // written on: 08 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 this 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; //--------------------------------------------------- // 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); } //--------------------------------------------------------------- // prompt the user for the input-message and accept the response //--------------------------------------------------------------- printf( "\nPlease type a short sentence on the line below: \n" ); char msg[ 80 ] = { 0 }; int n = read( STDIN_FILENO, msg, sizeof( msg ) ); //------------------------------------------------------- // write the message-characters to the socket one-by-one //------------------------------------------------------- for (int i = 0; i < n; 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 }; int len = sizeof( buf ); 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 ); }