home *** CD-ROM | disk | FTP | other *** search
- /*
- ** UDP client program
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <errno.h>
- #include <netdb.h>
- #include <sys/types.h>
- #include <sys/time.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <proto/socket.h>
-
- #define DEFAULT_PORT 54321
- #define MAX_RETRIES 10
- #define TIMEOUT_SECS 1
- #define TERMINATOR "quit\n"
-
- main ( argc, argv )
- int argc;
- char *argv[];
- {
- int s, retcode, done, retry, match, timeout;
- long fromlen;
- char recvbuffer[256], sendbuffer[256];
- struct sockaddr_in addr, from;
- struct servent * sp;
- struct hostent * hp;
- struct timeval timer;
- fd_set rfds;
-
- if ( argc != 2 ) {
- fprintf ( stderr, "Usage:\t %s host \n", argv[0]);
- exit (1);
- }
-
- /*
- ** Users may specify hosts in 2 different formats:
- ** hostnames or IP addresses (aka dotted quads).
- ** First try looking up the host as a hostname, and
- ** if that fails try as an IP address.
- */
-
- memset(&addr, 0, sizeof(struct sockaddr_in) );
- hp = gethostbyname( argv[1] );
- if ( hp != NULL ) {
- addr.sin_family = hp->h_addrtype ;
- addr.sin_addr.s_addr = *((int *) hp ->h_addr);
- } else {
- addr.sin_family = AF_INET;
- addr.sin_addr.s_addr = inet_addr( argv[1] );
- if (addr.sin_addr.s_addr == -1) {
- fprintf(stderr,"Can't lookup host %s\n",argv[1]);
- exit(1);
- }
- }
-
- /*
- ** Applications should get the service number from the services file.
- ** Try the services file first, and upon failure, use a default port
- ** number. This allows the example to run without modifying the
- ** system environment.
- */
- sp = getservbyname( "example", "udp" );
- if( sp != NULL ) {
- addr.sin_port = sp->s_port;
- } else {
- addr.sin_port = DEFAULT_PORT;
- }
-
- /*
- ** Create a socket.
- */
- s = socket ( AF_INET, SOCK_DGRAM, 0 );
- if ( s == -1 ) {
- perror("socket");
- exit(1);
- }
-
- /*
- ** Client main loop - read data from stdin, send to server.
- ** Server echos back data, client reads data and prints on stdout.
- ** User may type quit or EOF to terminate program.
- ** Since data may get lost, the program must be prepared to
- ** deal with a lost message. This simple client uses select
- ** to wait for the incoming packet or a timeout. After a
- ** timeout it will retransmit the packet up to MAX_RETRIES
- ** times before giving up. If the program receives a packet
- ** that doesn't contain the expected data it is dropped.
- */
-
- printf("Type a message, then type EOF character or quit to quit\n");
- done = 0;
- while (!done) { /* Main Client Loop */
-
- if( fgets(sendbuffer, sizeof(sendbuffer), stdin) == NULL ){
- if (feof(stdin)) {
- strcpy(sendbuffer, "quit\n");
- fprintf(stderr,"EOF - terminating server\n");
- }
- else {
- perror("fgets");
- exit(1);
- }
- }
- if (!strncmp(sendbuffer, TERMINATOR, strlen(TERMINATOR))) {
- done = 1;
- }
-
- retry = MAX_RETRIES+1;
- match = 0;
- while(!match && retry) { /* Transmit Loop */
- retcode = sendto(s, sendbuffer, strlen(sendbuffer),
- 0, (struct sockaddr *)&addr, sizeof(addr));
- if(retcode < 0 ) {
- perror("sendto");
- exit(1);
- }
-
- timeout = 0;
- while(!match && !timeout) { /* Timeout Loop */
- FD_ZERO(&rfds);
- FD_SET(s, &rfds);
- timer.tv_sec = TIMEOUT_SECS;
- timer.tv_usec = 0;
- retcode = select(s+1, &rfds, NULL, NULL, &timer);
- if (retcode < 0) {
- perror("select");
- exit(1);
- }
- else if ( retcode == 0 ) { /* Timeout */
- if (--retry) {
- fprintf(stderr,"Client Timeout, retransmitting data\n");
- timeout = 1;
- }
- else {
- fprintf(stderr,"Client Timeout - giving up\n");
- exit(1);
- }
- }
- else { /* Get Packet */
- fromlen = sizeof(from);
- retcode = recvfrom(s, recvbuffer, sizeof(recvbuffer),
- 0, (struct sockaddr*)&from, &fromlen);
- if ( retcode < 0 ){
- perror("recvfrom");
- exit(1);
- }
- recvbuffer[retcode] = 0;
- fprintf(stdout,
- "Response from %s, port %d, length %3d, data %s",
- inet_ntoa(from.sin_addr),from.sin_port, retcode, recvbuffer);
-
- if (!strcmp( sendbuffer, recvbuffer )) {/* Check Packet */
- fputs(recvbuffer, stdout);
- match=1;
- }
- }
- }
- }
- }
- exit(0);
- }
-