心跳处理

#include        <sys/types.h>    /*  basic system data types  */
#include        <sys/socket.h>   /*  basic socket definitions  */
#if TIME_WITH_SYS_TIME
#include        <sys/time.h>     /*  timeval{} for select()  */
#include        <time.h>                 /*  timespec{} for pselect()  */
#else
#if HAVE_SYS_TIME_H
#include        <sys/time.h>     /*  includes <time.h> unsafely  */
#else
#include        <time.h>                 /*  old system?  */
#endif
#endif
#include        <netinet/ in.h>   /*  sockaddr_in{} and other Internet defns  */
#include        <arpa/inet.h>    /*  inet(3) functions  */
#include        <errno.h>
#include        <fcntl.h>                /*  for nonblocking  */
#include        <netdb.h>
#include        <signal.h>
#include        <stdio.h>
#include        <stdlib.h>
#include        < string.h>
#include        <sys/stat.h>     /*  for S_xxx file mode constants  */
#include        <sys/uio.h>              /*  for iovec{} and readv/writev  */
#include        <unistd.h>
#include        <sys/wait.h>

#define SERV_PORT 9877
#define LISTENQ 100
#define MAXLINE 512

static  int servfd;
static  int nsec;
static  int maxnalarms;
static  int nprobes;
static  void sig_urg( int),sig_alrm( int);

void heartbeat_serv( int servfd_arg,  int nsec_arg,  int maxnalarms_arg)
{
    servfd = servfd_arg;
     if((nsec = nsec_arg) <  1)
        nsec =  1;
     if((maxnalarms = maxnalarms_arg) < nsec)
        maxnalarms = nsec;
    
    signal(SIGURG, sig_urg); // SIGURG ---- 当out-of-band data接收的时候可能发送
    fcntl(servfd, F_SETOWN, getpid());
    
    signal(SIGALRM, sig_alrm); // SIGALRM ----- 用alarm函数设置的timer超时或setitimer函数设置的interval timer超时
    alarm(nsec);
}
void err_sys( const  char *error_string)
{
    printf( " %s\n ", error_string);    
}
static  void sig_urg( int signo)
{
     int n;
     char c;
     if(( n = recv(servfd, &c,  1, MSG_OOB)) <  0 )
    {
         if(errno != EWOULDBLOCK)
            err_sys( " recv error ");
    }
    send(servfd, &c,  1, MSG_OOB);
    nprobes =  0;
     return;
}

static  void sig_alrm ( int signo)
{
     if(++nprobes > maxnalarms)
    {
        printf( " no probs from client\n ");
        exit( 0);
    }
    alarm(nsec);
     return;
}
void str_echo( int sockfd)
{
    ssize_t n;
     char line[MAXLINE];
    heartbeat_serv(sockfd,  1 ,  5);
    
     for(;;)
    {

         if(( n = read(sockfd, line, MAXLINE)) ==  0)
        {
             return; // connection closed by other end
        }
        write(sockfd, line, n);
    }
}
void sig_chld( int signo)
{
    pid_t pid;
     int stat;
     while( (pid = waitpid(- 1, &stat, WNOHANG)) >  0 )
    {
        printf( " child %d terminated \n ", pid);
    }
     return;
}

#define SA struct sockaddr

int main( int argc,  char **argv)
{
     int listenfd, connfd;
    pid_t childpid;
    socklen_t clilen;
     struct sockaddr_in cliaddr, servaddr;
     void sig_chld( int);
    listenfd = socket(AF_INET, SOCK_STREAM,  0);
    bzero(&servaddr,  sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port = htons(SERV_PORT);
    
    bind(listenfd, (SA*)&servaddr,  sizeof(servaddr));
    listen(listenfd, LISTENQ);
    signal(SIGCHLD, sig_chld);
    
     for(;;)
    {
        clilen =  sizeof(cliaddr);
         if((connfd = accept(listenfd, (SA*)&cliaddr, &clilen )) <  0)
        {
             if(errno == EINTR)
                 continue;
             else
                err_sys( " accept error ");
        }
         if((childpid = fork() ) ==  0)
        {
            close(listenfd);
            str_echo(connfd);
            exit( 0);
        }
        close(connfd);
    } // for
}

你可能感兴趣的:(处理)