⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 samples13.tr

📁 unix/linux 编程实践一书的所有源代码
💻 TR
📖 第 1 页 / 共 2 页
字号:
.de NP.in -0.8i@l'6.5i''bp.sp 0.36i.ps 10.ft B.tl ''lecture udp samples'page %'.ft R@l'6.5i'.ft C.ps 8.vs 9p.in +0.8i.nf...ec @.nf.sp 0.5i.ft B.tl ''lecture udp samples'page %'.ft R@l'6.5i'.ft C.ps 8.vs 9p.in +0.8i/**************************************************************************** * srv.c * License server server program */#include <stdio.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <netdb.h>#include <signal.h>#include <sys/errno.h>#define SERVER_PORTNUM  2020            /* Our server's port number */#define MSGLEN          128             /* Size of our datagrams */#define TICKET_AVAIL    -1              /* Slot is available for use */#define EXPIRE_INTERVAL 60              /* Expire every 60 seconds */#define MAXUSERS        3               /* Only 3 users for us */#define REPORT_PREFIX   "\t\t\tSRV:"    /* makes narration easier to read */#define	SYSERROR(x)	{ perror(x); exit(-1); }/**************************************************************************** * Important variables */static int ticket_array[MAXUSERS];      /* Our ticket array */static int sd = -1;                     /* Our socket */static int num_tickets_out = 0;         /* Number of tickets outstanding */extern int errno;/**************************************************************************** * shut_down * Shut down cleanly when we get a signal. * Results: NEVER RETURNS */void shut_down(){        /* Close socket and exit */        (void) shutdown(sd, 2);        (void) close(sd);        exit(0);} /* shut_down *//**************************************************************************** * ticket_expire * go through all tickets and get rid of any dead ones * Results: none */void ticket_expire(){        int x;        /* Go through the array and look for tickets that belong to          * processes that are dead.         */        for(x = 0; x < MAXUSERS; x++) {                if((ticket_array[x] != TICKET_AVAIL) &&                   (kill(ticket_array[x], 0) == -1) && (errno == ESRCH)) {                        /* Process is gone - free up slot */                        fprintf(stderr,                                 "%s Process %d gone - freeing ticket\n",                                        REPORT_PREFIX, ticket_array[x]);                        ticket_array[x] = TICKET_AVAIL;                        num_tickets_out--;                }        }        /* Now reset the alarm clock */        (void) alarm(EXPIRE_INTERVAL);        return;} /* ticket_expire */.NP/**************************************************************************** * do_hello * Give out a ticket if any are available * IN  msg_p                    message received from client * Results: ptr to response * NOTE: return is in static buffer overwritten by each call. */static char *do_hello(msg_p)char *msg_p;{        int x;        static char replybuf[MSGLEN];        /* Got a ticket request - see if we can give out a ticket. */        if(num_tickets_out >= MAXUSERS) {                /* No tickets available */                return("FAIL no tickets available");        } else {                /* Give out a ticket */                for(x = 0; x < MAXUSERS; x++)                         if(ticket_array[x] == TICKET_AVAIL)                                 break;                /* Just a sanity check - should never happen */                if(x == MAXUSERS) {                        fprintf(stderr, "%s database corrupt\n", REPORT_PREFIX);                        return("FAIL database corrupt");                } else {                        /* Got it OK! We'll make a ticket for this process                         * and keep track of the PID (their "name") and                         * the slot it's in (the "dongle number").                         *                         * Thus, our ticket string looks like:                         *      pid.slot                         */                        ticket_array[x] = atoi(msg_p + 5); /* get pid in msg */                        sprintf(replybuf, "TICK %d.%d", ticket_array[x], x);                        num_tickets_out++;                }        }        /* Return our response */        return(replybuf);} /* do_hello *//**************************************************************************** * do_goodbye * Take back ticket client is returning * IN  msg_p                    message received from client * Results: ptr to response * NOTE: return is in static buffer overwritten by each call. */static char *do_goodbye(msg_p)char *msg_p;{        int pid, slot;                    /* ticket components */        /* The user's giving us back a ticket.  First we need to get         * the ticket out of the message, which looks like:         *         *      GBYE pid.slot         */        if((sscanf((msg_p + 5), "%d.%d", &pid, &slot) != 2) ||           (ticket_array[slot] != pid)) {                fprintf(stderr, "%s Bogus ticket \"%s\"\n", msg_p + 5,                                REPORT_PREFIX);                return("FAIL invalid ticket");        }        /* The ticket is valid.  Release it. */        ticket_array[slot] = TICKET_AVAIL;        num_tickets_out--;        /* Return response */        return("TATA See ya!");} /* do_goodbye */.NP/**************************************************************************** * do_validate * Validate client's ticket * IN  msg_p                    message received from client * Results: ptr to response * NOTE: return is in static buffer overwritten by each call. */static char *do_validate(msg_p)char *msg_p;{        int pid, slot;              /* components of ticket */        /* The user's giving us a ticket to validate.  First we need to get         * the ticket out of the message, which looks like:         *         *      VALD pid.slot         */        if((sscanf((msg_p + 5), "%d.%d", &pid, &slot) != 2) ||           (ticket_array[slot] != pid)) {                fprintf(stderr, "%s Bogus ticket \"%s\"\n",                                 REPORT_PREFIX, msg_p + 5);                return("FAIL invalid ticket");        }        /* If we got here the ticket's good */        return("GOOD Valid ticket");} /* do_validate *//**************************************************************************** * main * main processing loop for server program * Results: none */main(){        int pid;        char buf[MSGLEN];        int secs_left = EXPIRE_INTERVAL;        struct sockaddr_in server_addr;        struct sockaddr_in client_addr;        int addrlen;        char *resp_p;        int x;        char *inet_ntoa();        struct  sockaddr_in   saddr;   /* build our address here */        struct  hostent         *hp;   /* this is part of our    */        char    hostname[256];         /* address                */        int     slen,sock_id,sock_fd;  /* line id, file desc     */        FILE    *sock_fp;              /* use socket as stream   */        char    *ctime();              /* convert secs to string */        long    time(), thetime;       /* time and the val       */         gethostname( hostname );                /* where am I ?         */        hp = gethostbyname( hostname );         /* get info about host  */        bzero( &saddr, sizeof(saddr) );         /* zero struct          */                                                /* fill in hostaddr     */        bcopy( hp->h_addr, &saddr.sin_addr, hp->h_length);        saddr.sin_family = AF_INET ;            /* fill in socket type  */        saddr.sin_port = htons(SERVER_PORTNUM); /* fill in socket port  */       /*        *      step 2: ask kernel for a socket, then bind address        */        sd = socket( AF_INET, SOCK_DGRAM, 0 );    /* get a socket */        if ( sd == -1 )                 SYSERROR("SERVER: socket");        if ( bind(sd, &saddr, sizeof(saddr)) != 0 )/* bind it to   */                SYSERROR("SERVER: bind");.NP        /* Set up signal handler to clean up on exit */        (void) signal(SIGINT, shut_down);        (void) signal(SIGTERM, shut_down);#ifdef EXPIRE_TICKETS        /* Set up the alarm clock */        (void) signal(SIGALRM, ticket_expire);        alarm(EXPIRE_INTERVAL);#endif /* EXPIRE_TICKETS */        /* Initialize ticket database */        for(x = 0; x < MAXUSERS; x++)                ticket_array[x] = TICKET_AVAIL;        /* Set up a loop, listening to client requests forever */        while(1) {                /* Get a request */                addrlen = sizeof(client_addr);                if(recvfrom(sd, buf, MSGLEN, 0, &client_addr, &addrlen) == -1) {                        /* If we get an error we'll acknowledge it, but we                         * must continue so that we can help other clients.                         *                          * We ignore EINTR; that's just the alarm handler                         */                        if(errno != EINTR)                                perror("SERVER: recvfrom");                        continue;                }                fprintf(stderr, "%s Got \"%s\" from %s,%d\n",                         REPORT_PREFIX, buf, 			inet_ntoa(client_addr.sin_addr), client_addr.sin_port);#ifdef EXPIRE_TICKETS                /* Turn off the alarm clock so we're not interrupted in                 * the middle of things.                 */                secs_left = alarm(0);#endif /* EXPIRE_TICKETS */                /* Is this a request we know how to deal with?  If so,                 * do so.  If not, send a failure message back.                 * We recognize the following:                 *      HELO client-id-string                 *      GBYE ticket-id-string                 *      VALD ticket-id-string                 */                if(strncmp(buf, "HELO", 4) == 0)                         resp_p = do_hello(buf);                else if(strncmp(buf, "GBYE", 4) == 0)                        resp_p = do_goodbye(buf);                else if(strncmp(buf, "VALD", 4) == 0)                        resp_p = do_validate(buf);                else                        resp_p = "FAIL Invalid Request";                /* Now send the response */                fprintf(stderr, "%s sending response \"%s\"\n",                                REPORT_PREFIX, resp_p);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -