• (OK) C/S—心跳检测—heartbeat


    /root/桌面/server-client-pthread-c

    heartbeat-server.c


    
        // gcc heartbeat-server.c -o heartbeat-server
        // indent -npro -kr -i8 -ts8 -sob -l280 -ss -ncs -cp1 *
        /* heartbeat-server.c
         *
         * improved by ztguang, 2015.12.20
         *
         * Copyright (c) 2000 Sean Walton and Macmillan Publishers. Use may be in
         * whole or in part in accordance to the General Public License (GPL).
         *
         * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
         * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
         * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
         * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
         * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
         * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
         * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
         * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
         * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
         * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
         * SUCH DAMAGE.
        */
        /*****************************************************************************/
        /*** heartbeat-server.c ***/
        /*** ***/
        /*** Demonstrates how to keep track of the server using a "heartbeat". If ***/
        /*** the heartbeat is lost, the connection can be reestablished and the ***/
        /*** session resumed. ***/
        /*****************************************************************************/
        #include <stdio.h>
        #include <stdlib.h>
        #include <unistd.h>
        #include <strings.h>
        #include <errno.h>
        #include <fcntl.h>
        #include <resolv.h>
        #include <signal.h>
        #include <sys/wait.h>
        #include <netinet/in.h>
        #include <arpa/inet.h>
        #include <sys/socket.h>
    
        #define BUF_SIZE 1024            //默认缓冲区
        #define SERVER_PORT 11111        //监听端口
        #define SERVER_HOST "127.0.0.1"    //服务器IP地址
        #define LISTEN_SIZE 10            //监听队列长度
    
        //两个有用的宏定义:检查和赋值并且检测
        #define CHK(eval) if(eval < 0){perror("eval"); exit(-1);}
        #define CHK2(res, eval) if((res = eval) < 0){perror("eval"); exit(-1);}
    
        int client;
        struct sigaction act;
        /*---------------------------------------------------------------------
            sig_handler - catch and send heartbeat.
         ---------------------------------------------------------------------*/
        void sig_handler(int signum)
        {
            if (signum == SIGURG) {
                char c;
                recv(client, &c, sizeof(c), MSG_OOB);
                if (c == '?')
                    /* Are you alive? */
                    send(client, "Y", 1, MSG_OOB);    /* */
            } else if (signum == SIGCHLD)
                wait(0);
        }
    
        /*---------------------------------------------------------------------
            servlet - process requests
         ---------------------------------------------------------------------*/
        void servlet(void)
        {
            int bytes;
            char buffer[BUF_SIZE];
            bzero(&act, sizeof(act));
            act.sa_handler = sig_handler;
            act.sa_flags = SA_RESTART;
            sigaction(SIGURG, &act, 0);    /* connect SIGURG signal */
            if (fcntl(client, F_SETOWN, getpid()) != 0)
                perror("Can't claim SIGIO and SIGURG");
            do {
                bzero(buffer, BUF_SIZE);
                bytes = recv(client, buffer, sizeof(buffer), 0);
                printf("recieve [%s] from client-%d
    ", buffer, client);
                if (bytes > 0)
                    send(client, buffer, bytes, 0);
            } while (bytes > 0);
    
            printf("end while
    ");
    
            close(client);
            exit(0);
        }
    
        /*---------------------------------------------------------------------
            main - set up client and begin the heartbeat.
         ---------------------------------------------------------------------*/
        int main(int count, char *strings[])
        {
            bzero(&act, sizeof(act));
            act.sa_handler = sig_handler;
            act.sa_flags = SA_NOCLDSTOP | SA_RESTART;
            if (sigaction(SIGCHLD, &act, 0) != 0)
                perror("sigaction()");
    
            int listener;        //监听socket
            struct sockaddr_in addr, peer;
            addr.sin_family = PF_INET;
            addr.sin_port = htons(SERVER_PORT);
            addr.sin_addr.s_addr = inet_addr(SERVER_HOST);
            socklen_t socklen;
            socklen = sizeof(struct sockaddr_in);
            CHK2(listener, socket(PF_INET, SOCK_STREAM, 0));    //初始化监听socket
    
            // 设置套接字选项避免地址使用错误
            int on = 1;
            if ((setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on))) < 0) {
                perror("server: setsockopt failed");
                exit(EXIT_FAILURE);
            }
    
            CHK(bind(listener, (struct sockaddr *)&addr, sizeof(addr)));    //绑定监听socket
    
            //printf("listen
    ");
            CHK(listen(listener, LISTEN_SIZE));    //设置监听
            printf("server: listening
    ");
    
            while (1) {
                client = accept(listener, (struct sockaddr *)&peer, &socklen);
                printf("accept client-%d
    ", client);
                if (client > 0) {
                    if (fork() == 0) {
                        close(listener);
                        servlet();
                    } else
                        close(client);
                } else
                    perror("accept()");
            }
            close(client);
            return 0;
        }
    
    

    heartbeat-client.c

    
        // gcc heartbeat-client.c -o heartbeat-client
        // indent -npro -kr -i8 -ts8 -sob -l280 -ss -ncs -cp1 *
        /* heartbeat-client.c
         *
         * improved by ztguang, 2015.12.20
         *
         * Copyright (c) 2000 Sean Walton and Macmillan Publishers. Use may be in
         * whole or in part in accordance to the General Public License (GPL).
         *
         * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
         * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
         * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
         * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
         * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
         * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
         * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
         * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
         * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
         * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
         * SUCH DAMAGE.
        */
        /*****************************************************************************/
        /*** heartbeat-client.c ***/
        /*** ***/
        /*** Demonstrates how to keep track of the server using a "heartbeat". If ***/
        /*** the heartbeat is lost, the connection can be reestablished and the ***/
        /*** session resumed. ***/
        /*****************************************************************************/
        #include <stdio.h>
        #include <stdlib.h>
        #include <unistd.h>
        #include <string.h>
        #include <errno.h>
        #include <fcntl.h>
        #include <signal.h>
        #include <resolv.h>
        #include <netinet/tcp.h>
        #include <netinet/in.h>
        #include <arpa/inet.h>
        #include <sys/socket.h>
    
        #define SERVER_PORT 11111    //监听端口
        #define SERVER_HOST "127.0.0.1"    //服务器IP地址
        #define DELAY 2            /*seconds */
    
        //两个有用的宏定义:检查和赋值并且检测
        #define CHK(eval) if(eval < 0){perror("eval"); exit(-1);}
        #define CHK2(res, eval) if((res = eval) < 0){perror("eval"); exit(-1);}
    
        int serverfd, got_reply = 1;
    
        /*---------------------------------------------------------------------
            sig_handler - if the single is OOB, set flag. If ALARM, send heartbeat.
         ---------------------------------------------------------------------*/
        void sig_handler(int signum)
        {
            int bytes, len;
    
            struct tcp_info info;
            int leng = sizeof(info);
    
            if (signum == SIGURG) {
        //*
                getsockopt(serverfd, IPPROTO_TCP, TCP_INFO, &info, (socklen_t *) &leng);
                if ((info.tcpi_state == TCP_ESTABLISHED)) {        // socket connected
                    ; //return 1;
                } else {        // socket disconnected
                    return;
                }
        //*/
                char c;
                CHK2(bytes, recv(serverfd, &c, sizeof(c), MSG_OOB));
                if (bytes == 0) return;
    
                got_reply = (c == 'Y');    /* Got reply */
                fprintf(stderr, "[server is alive]
    ");
            } else if (signum == SIGALRM) {
                printf("reply = %d
    ", got_reply);
                if (got_reply) {
                    alarm(DELAY);    // Wait a while
        //*
                    getsockopt(serverfd, IPPROTO_TCP, TCP_INFO, &info, (socklen_t *) &leng);
                    if ((info.tcpi_state == TCP_ESTABLISHED)) {        // socket connected
                        ; //return 1;
                    } else {        // socket disconnected
                        return;
                    }
        //*/
                    CHK2(len, send(serverfd, "?", 1, MSG_OOB));        // Alive??
                    if (len == 0) return;
                    got_reply = 0;
                } else {
                    fprintf(stderr, "Lost connection to server!
    ");
                    alarm(DELAY);    /* Wait a while */
                }
            }
        }
    
        /*---------------------------------------------------------------------
            main - set up client and begin the heartbeat.
         ---------------------------------------------------------------------*/
        int main(int count, char *strings[])
        {
    
            int bytes, len;
            char line[100];
    
            struct tcp_info info;
            int leng = sizeof(info);
    
            struct sigaction act;
            bzero(&act, sizeof(act));
            act.sa_handler = sig_handler;
            act.sa_flags = SA_RESTART;
            sigaction(SIGURG, &act, 0);
            sigaction(SIGALRM, &act, 0);
    
            struct sockaddr_in seraddr;
            seraddr.sin_family = PF_INET;
            seraddr.sin_port = htons(SERVER_PORT);
            seraddr.sin_addr.s_addr = inet_addr(SERVER_HOST);
    
            CHK2(serverfd, socket(PF_INET, SOCK_STREAM, 0));
            if (fcntl(serverfd, F_SETOWN, getpid()) != 0)    // claim SIGIO/SIGURG signals
                perror("Can't claim SIGURG and SIGIO");
    
            while (1)
            {
                got_reply = 1;
    
                close(serverfd);
                CHK2(serverfd, socket(PF_INET, SOCK_STREAM, 0));
                if (fcntl(serverfd, F_SETOWN, getpid()) != 0) {        // claim SIGIO/SIGURG signals
                    perror("Can't claim SIGURG and SIGIO");
                    continue;
                }
    
                if (connect(serverfd, (struct sockaddr *)&seraddr, sizeof(seraddr)) == 0) {
                    printf("connect [OK]
    ");
                    alarm(DELAY);
                    do {
        //*
                        getsockopt(serverfd, IPPROTO_TCP, TCP_INFO, &info, (socklen_t *) &leng);
                        if ((info.tcpi_state == TCP_ESTABLISHED)) {        // socket connected
                            ; //return 1;
                        } else {        // socket disconnected
                            break;
                        }
        //*/
                        //CHK2(len, send(serverfd, "?", 1, MSG_OOB));        // Alive??
                        //got_reply = 0;
                        //CHK2(len, send(serverfd, "restart", 7, 0));
                        //printf("send [restart]
    ");
                        memset(line, 0x00, 100);
                        gets(line);
                        printf("send [%s]
    ", line);
                        //CHK2(len, send(serverfd, "adsf", 4, 0)); sleep(1);
    
                        CHK2(len, send(serverfd, line, strlen(line), 0));        // send
                        if (len <= 0) break;
    
                        CHK2(bytes, recv(serverfd, line, sizeof(line), 0));        // recieve
                        if (bytes <= 0) break;
    
                    } while (bytes > 0);
    
                    printf("end while
    ");
    
                } else {
                    perror("connect failed, retry!
    ");
                    sleep(2);
                }
            }
            //close(serverfd);
            //return 0;
        }
    
    



  • 相关阅读:
    如何提高MySQL Limit查询的性能
    asp.net cache 缓存
    a标签的target指向iframe
    Entity Framework实例详解
    MySql循环插入数据(定义了存储过程)
    mysql 定义function rand
    [转] Socket心跳包异常检测的C语言实现,服务器与客户端代码案例
    tinyhttpd ------ C 语言实现最简单的 HTTP 服务器
    http通信过程中,Web浏览器与Web服务器之间将完成下列7个步骤
    http请求数据的格式
  • 原文地址:https://www.cnblogs.com/ztguang/p/12647012.html
Copyright © 2020-2023  润新知