//------------------------------------------------------------------- // slowecho.cpp // // This is a TCP echo-server which sends back the characters it // receives from a client one-byte-at-a-time, but after a timed // delay between each transmission, for demonstration purposes. // (The user may terminate this server by hitting -C.) // // to compile: $ g++ slowecho.cpp -o slowecho // to execute: $ ./slowecho // // programmer: ALLAN CRUSE // written on: 27 FEB 2009 //------------------------------------------------------------------- #include // for printf(), perror() #include // for exit() #include // for read(), write(), close() #include // for socket(), bind(), listen(), #include // for nanosleep() #define DEMO_PORT 54321 int main( int argc, char **argv ) { //--------------------------------------------------------- // check for a user-specified time-delay (in microseconds) //--------------------------------------------------------- if ( argc == 1 ) { fprintf( stderr, "usage: ./slowecho \n" ); exit(1); } long microseconds = atol( argv[1] ); long nanoseconds = microseconds * 1000L; struct timespec myts; myts.tv_sec = nanoseconds / 1000000000L; myts.tv_nsec = nanoseconds % 1000000000L; //-------------------------------------------------- // create a socket-address structure for our socket //-------------------------------------------------- struct sockaddr_in haddr = { 0 }; socklen_t halen = sizeof( haddr ); haddr.sin_family = AF_INET; haddr.sin_port = htons( DEMO_PORT ); haddr.sin_addr.s_addr = htonl( INADDR_ANY ); //--------------------------------------------- // create the listening socket for this server //--------------------------------------------- int sock = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP ); if ( sock < 0 ) { perror( "socket" ); exit(1); } //----------------------------------------------------- // bind this listening socket to our fixed port-number //----------------------------------------------------- if ( bind( sock, (sockaddr*)&haddr, halen ) < 0 ) { perror( "bind" ); exit(1); } //----------------------------------------------------- // create a connection queue for this listening socket //----------------------------------------------------- if ( listen( sock, 5 ) < 0 ) { perror( "listen" ); exit(1); } //------------------------------------------------ // enter the main look to process client requests //------------------------------------------------ do { printf( "\nserver is listening on port %u \n", DEMO_PORT ); //-------------------------------------------------- // accept the next connection-request from a client //-------------------------------------------------- struct sockaddr_in paddr = { 0 }; socklen_t palen = sizeof( paddr ); int conn = accept( sock, (sockaddr*)&paddr, &palen ); if ( conn < 0 ) { perror( "accept" ); exit(1); } //-------------------------------------------------- // we can now receive characters sent by the client //-------------------------------------------------- int star = '*'; do { int inch = 0; int i = read( conn, &inch, 1 ); if ( i == 0 ) break; if ( i < 0 ) { perror( "read" ); exit(1); } if ( nanosleep( &myts, NULL ) < 0 ) { perror( "nanosleep" ); exit(1); } int j = write( conn, &inch, 1 ); if ( j < 0 ) { perror( "write" ); exit(1); } write( 1, &star, 1 ); } while ( 1 ); printf( "\n" ); //---------------------------------------------------- // flush the output buffers and close this connection //---------------------------------------------------- fflush( fdopen( conn, "rw" ) ); close( conn ); printf( "data was received, processed, and returned\n" ); } while( 1 ); }