• 心跳处理


    #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
    }
  • 相关阅读:
    win7 x64怎么枚举所有快捷键呢
    C/C++多种方法获取文件大小
    中缀表达式转后缀表达式(逆波兰表达式)
    检测文件存在的四种方法
    透明窗口与不规则窗口制作方法总结
    Struts 2命令执行漏洞
    Windows 8 无法安装
    从浏览器启动客户端程序
    tesseractocr训练方法
    Algorithm Gossip: 中序式轉後序式(前序式)
  • 原文地址:https://www.cnblogs.com/no7dw/p/2666766.html
Copyright © 2020-2023  润新知