/* server1udp.c - a server program that uses the socket interface to udp */ #include #include #ifdef __linux__ #ifndef __USE_BSD #define __USE_BSD #endif #endif #include #include #include #include #include #include #include #include "server.h" #ifdef __osf__ /* on DECUNIX no standard header file contains a prototype for herror() */ /* 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 Solaric * 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 link * too */ #define BUFSIZE 65535 #define MAXAMOUNT 10000000 char data[MAXAMOUNT]; void server( int server_port, char * interface_name, int argc, char * argv[] ) { int iterations, packSeq, n , len, fd; int lastSeq = -1; int packetLoss = 0; struct sockaddr_in address, client; struct hostent * node_ptr; char local_node[ MAXHOSTNAMELEN ]; char * host_name; /****** int silence = 0; if ( strcmp( argv[ argc - 1 ] , "-s" ) == 0 ) silence = 1; ******/ if ( interface_name == NULL ) { /* default to name of local host node */ if ( gethostname( local_node, MAXHOSTNAMELEN ) < 0 ) { perror( "server1udp gethostname" ); exit( EXIT_FAILURE ); } host_name = local_node; }/* end of if */ else host_name = interface_name; /* get structure for host or local interface that server wants to use */ if ( ( node_ptr = gethostbyname( host_name ) ) == NULL ) { herror( host_name ); exit( EXIT_FAILURE ); }/* end of if */ /* 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 ); if ( interface_name == NULL ) address.sin_addr.s_addr = htonl( INADDR_ANY ); /* use any interface */ else memcpy( &address.sin_addr, node_ptr->h_addr, node_ptr->h_length ); /* open an internet udp socket */ if ( ( fd = socket( PF_INET, SOCK_DGRAM, 0 ) ) < 0 ) { perror( "server1udp socket" ); exit( EXIT_FAILURE ); } /* bind this socket to the server's Internet address */ if ( bind(fd, (struct sockaddr *)&address, sizeof(struct sockaddr_in)) < 0 ) { perror( "server1udp bind" ); exit( EXIT_FAILURE ); } /* now find out what local port number was assigned to this server */ len = sizeof( struct sockaddr_in ); if ( getsockname( fd, ( struct sockaddr* )&address, (void*)&len) < 0 ) { perror( "server1udp getsockname" ); exit( EXIT_FAILURE ); } /* we are now successfully established as a udp server */ fprintf(stderr,"server1udp: at port %d on node %s, internet address %s\n\n", ntohs( address.sin_port), node_ptr->h_name, inet_ntoa( address.sin_addr ) ); /* repeatedly read a message from a client, reverse it, then write it to * standard output along with the client's id */ for( ; ; ) { len = sizeof( client ); if ( ( n = recvfrom( fd, data, MAXAMOUNT, 0, ( struct sockaddr * ) &client, (void*) &len) )>0 ) { data[ n ] = '\0'; /* make data to a C-string */ sscanf( data, "%d", &packSeq ); /* begin packet of new transmision */ if ( packSeq == -2 ) { lastSeq = -1; packetLoss = 0; }else /* end packet of this transmission */ if ( packSeq == -1 ) { sscanf( data, "%d%d", &packSeq, &iterations ); if ( iterations != lastSeq + 1 ) { packetLoss += iterations - lastSeq - 1; fprintf(stderr," %d packets lost here\n",iterations - lastSeq - 1 ); } fprintf(stderr,"Expected to receive %d UDP packet. Lost %d packets \n", iterations, packetLoss ); lastSeq = -1; packetLoss = 0; } else{ /*** if ( !silence ) fprintf(stderr,"udpserver: from address %s, port %d packet seq#: %d\n", inet_ntoa( client.sin_addr), ntohs( client.sin_port), packSeq); ***/ /* report packet loss */ if ( packSeq != lastSeq + 1 ) { if ( packSeq < lastSeq ) { fprintf(stderr,"UDP packet %d is out of order, should arrive before\n", packSeq ); packetLoss --; }else { packetLoss += packSeq - lastSeq - 1; fprintf(stderr,"UDP packet %d is out of order. %d packets lost here\n", packSeq, packSeq - lastSeq - 1 ); } } lastSeq = packSeq; }/* end of else */ }/* end of if */ else if ( n < 0 ) { perror( "udpserver recvfrom" ); exit( EXIT_FAILURE ); }/* end of else if */ }/* end of for */ /* close the socket over which server read messages */ if ( close(fd) < 0 ) { perror( "server1udp close"); exit( EXIT_FAILURE ); } }/* end of server */