/* client1udp.c - a client program that uses the socket interface to udp */ /* THIS PROGRAM IS ADAPTED FROM HANDOUT OF CS820 OS PROGRAMMING * THE ORIGINAL AUTHOR SHOULD BE PROF. BOB RUSSELL * MODIFIED BY LIN @OCT,2001 */ #include #include #ifdef __linux__ #ifndef __USE_BSD #define __USE_BSD #endif #endif #include #include #include #include #include #include #include #include #ifdef __osf__ /* on DECUNIX no standard header file containns a prototype for this function * however, the function is in the standard c library (libc.a ) */ extern void herror( char * name ); #endif /* on solaris this program must be linked with -lnsl and -lsocket to load the * routines defined in the socket library. * also on Solaris contains a prototype for herror(), but it is * NOT defined in the standard c library. therefore, the separate file herror. * c must be compiled and linked too */ #include "client.h" #include "timer.h" #define ITERATIONS 100 #define AMOUNT 1 #define MAXAMOUNT 10000000 char data[MAXAMOUNT]; void client( int server_port, char * server_name, int argc, char * argv[] ) { int n, fd; int count, iterations=0, amount=0; struct sockaddr_in address; struct hostent *node_ptr; char local_node[ MAXHOSTNAMELEN ] ; struct tms tmsstart, tmsstop; clock_t start, stop; if( argc > 0 ) iterations = atoi(argv[0]); if( iterations <= 0 ) iterations = ITERATIONS; if( argc > 1 ) amount = atoi(argv[1]); if( amount <= 0 ) amount = AMOUNT; if( amount > MAXAMOUNT ) amount = MAXAMOUNT; data[ MAXAMOUNT - 1 ] = '\0'; fprintf(stderr, "udpclient: %d iterations, %d bytes each\n", iterations, amount); /* set up the name of the remote host interface for the server */ if ( server_name == NULL ) { /* default to name of local_node */ if ( gethostname( local_node, MAXHOSTNAMELEN ) < 0 ) { perror( "client1udp gethostname" ); exit( EXIT_FAILURE ); } server_name = local_node; }/* end of if */ /* get structure for remote host interface on which server is listening */ if ( ( node_ptr = gethostbyname( server_name ) ) == NULL ) { herror( server_name ); exit( EXIT_FAILURE ); } /* set up Internet address structure for the server */ memset( &address, 0, sizeof( struct sockaddr_in ) ) ; address.sin_family = node_ptr->h_addrtype; /* should be AF_INET */ address.sin_port = htons( server_port ); memcpy( &address.sin_addr, node_ptr->h_addr, node_ptr->h_length ); fprintf(stderr, "udpclient:will send to server at port %d on node %s, \n", server_port, node_ptr->h_name ); fprintf(stderr, " internet address %s\n", inet_ntoa( address.sin_addr) ); /* open an internet udp socket */ if ( ( fd = socket( PF_INET, SOCK_DGRAM, 0 ) ) < 0 ) { perror( "client1udp socket" ); exit( EXIT_FAILURE ); } /* send special packet to anounce begin of this transmission */ sprintf( data, "-2 %d ",iterations ); data[ 20 ] = '\0'; sendto(fd, data, 21, 0, (struct sockaddr* )&address, sizeof( address ) ); if( (start = times(&tmsstart)) < 0 ) exit(EXIT_FAILURE); /* now transmit data messages to server */ /* a UDP sequence number is added on the beginning of each packet */ /* this sequence will be used by server to count the packet loss*/ for( count = 0; count < iterations; count++ ) { sprintf( data, "%d ", count ); if( ( n = sendto(fd, data, amount, 0, (struct sockaddr* )&address, sizeof( address ) ) )!=amount ) { if ( n < 0 ) { perror( "udpclient sendto"); break; } else { fprintf( stderr, "udpclient: really sent %d bytes, attempted %d\n", n, amount ); break; } } }/* end of for */ if( (stop = times(&tmsstop)) < 0 ) exit(EXIT_FAILURE); /* send special packet to anounce end of this transmission */ sprintf( data, "-1 %d ",iterations ); data[ 20 ] = '\0'; sendto(fd, data, 21, 0, (struct sockaddr* )&address, sizeof( address ) ); fprintf(stderr, "udpclient: finished %d iterations of %d bytes each\n", count, amount); pr_times(stderr, stop-start, &tmsstart, &tmsstop); /* close the udp socket */ if ( close( fd ) < 0 ) { perror( "client1udp close " ); exit( EXIT_FAILURE ); } fprintf(stderr, "\n" ); }/* end of client */