zoukankan      html  css  js  c++  java
  • (OK) C/S—心跳检测—heartbeat

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

    heartbeat-server.c

    点击(此处)折叠或打开

    1. // gcc heartbeat-server.c -o heartbeat-server
    2. // indent -npro -kr -i8 -ts8 -sob -l280 -ss -ncs -cp1 *
    3. /* heartbeat-server.c
    4.  *
    5.  * improved by ztguang, 2015.12.20
    6.  *
    7.  * Copyright (c) 2000 Sean Walton and Macmillan Publishers. Use may be in
    8.  * whole or in part in accordance to the General Public License (GPL).
    9.  *
    10.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
    11.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    12.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    13.  * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
    14.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    15.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
    16.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    17.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
    18.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
    19.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
    20.  * SUCH DAMAGE.
    21. */
    22. /*****************************************************************************/
    23. /*** heartbeat-server.c ***/
    24. /*** ***/
    25. /*** Demonstrates how to keep track of the server using a "heartbeat". If ***/
    26. /*** the heartbeat is lost, the connection can be reestablished and the ***/
    27. /*** session resumed. ***/
    28. /*****************************************************************************/
    29. #include <stdio.h>
    30. #include <stdlib.h>
    31. #include <unistd.h>
    32. #include <strings.h>
    33. #include <errno.h>
    34. #include <fcntl.h>
    35. #include <resolv.h>
    36. #include <signal.h>
    37. #include <sys/wait.h>
    38. #include <netinet/in.h>
    39. #include <arpa/inet.h>
    40. #include <sys/socket.h>

    41. #define BUF_SIZE 1024            //默认缓冲区
    42. #define SERVER_PORT 11111        //监听端口
    43. #define SERVER_HOST "127.0.0.1"    //服务器IP地址
    44. #define LISTEN_SIZE 10            //监听队列长度

    45. //两个有用的宏定义:检查和赋值并且检测
    46. #define CHK(eval) if(eval < 0){perror("eval"); exit(-1);}
    47. #define CHK2(res, eval) if((res = eval) < 0){perror("eval"); exit(-1);}

    48. int client;
    49. struct sigaction act;
    50. /*---------------------------------------------------------------------
    51.     sig_handler - catch and send heartbeat.
    52.  ---------------------------------------------------------------------*/
    53. void sig_handler(int signum)
    54. {
    55.     if (signum == SIGURG) {
    56.         char c;
    57.         recv(client, &c, sizeof(c), MSG_OOB);
    58.         if (c == '?')
    59.             /* Are you alive? */
    60.             send(client, "Y", 1, MSG_OOB);    /* */
    61.     } else if (signum == SIGCHLD)
    62.         wait(0);
    63. }

    64. /*---------------------------------------------------------------------
    65.     servlet - process requests
    66.  ---------------------------------------------------------------------*/
    67. void servlet(void)
    68. {
    69.     int bytes;
    70.     char buffer[BUF_SIZE];
    71.     bzero(&act, sizeof(act));
    72.     act.sa_handler = sig_handler;
    73.     act.sa_flags = SA_RESTART;
    74.     sigaction(SIGURG, &act, 0);    /* connect SIGURG signal */
    75.     if (fcntl(client, F_SETOWN, getpid()) != 0)
    76.         perror("Can't claim SIGIO and SIGURG");
    77.     do {
    78.         bzero(buffer, BUF_SIZE);
    79.         bytes = recv(client, buffer, sizeof(buffer), 0);
    80.         printf("recieve [%s] from client-%d ", buffer, client);
    81.         if (bytes > 0)
    82.             send(client, buffer, bytes, 0);
    83.     } while (bytes > 0);

    84.     printf("end while ");

    85.     close(client);
    86.     exit(0);
    87. }

    88. /*---------------------------------------------------------------------
    89.     main - set up client and begin the heartbeat.
    90.  ---------------------------------------------------------------------*/
    91. int main(int count, char *strings[])
    92. {
    93.     bzero(&act, sizeof(act));
    94.     act.sa_handler = sig_handler;
    95.     act.sa_flags = SA_NOCLDSTOP | SA_RESTART;
    96.     if (sigaction(SIGCHLD, &act, 0) != 0)
    97.         perror("sigaction()");

    98.     int listener;        //监听socket
    99.     struct sockaddr_in addr, peer;
    100.     addr.sin_family = PF_INET;
    101.     addr.sin_port = htons(SERVER_PORT);
    102.     addr.sin_addr.s_addr = inet_addr(SERVER_HOST);
    103.     socklen_t socklen;
    104.     socklen = sizeof(struct sockaddr_in);
    105.     CHK2(listener, socket(PF_INET, SOCK_STREAM, 0));    //初始化监听socket

    106.     // 设置套接字选项避免地址使用错误
    107.     int on = 1;
    108.     if ((setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on))) < 0) {
    109.         perror("server: setsockopt failed");
    110.         exit(EXIT_FAILURE);
    111.     }

    112.     CHK(bind(listener, (struct sockaddr *)&addr, sizeof(addr)));    //绑定监听socket

    113.     //printf("listen ");
    114.     CHK(listen(listener, LISTEN_SIZE));    //设置监听
    115.     printf("server: listening ");

    116.     while (1) {
    117.         client = accept(listener, (struct sockaddr *)&peer, &socklen);
    118.         printf("accept client-%d ", client);
    119.         if (client > 0) {
    120.             if (fork() == 0) {
    121.                 close(listener);
    122.                 servlet();
    123.             } else
    124.                 close(client);
    125.         } else
    126.             perror("accept()");
    127.     }
    128.     close(client);
    129.     return 0;
    130. }

    heartbeat-client.c

    点击(此处)折叠或打开

    1. // gcc heartbeat-client.c -o heartbeat-client
    2. // indent -npro -kr -i8 -ts8 -sob -l280 -ss -ncs -cp1 *
    3. /* heartbeat-client.c
    4.  *
    5.  * improved by ztguang, 2015.12.20
    6.  *
    7.  * Copyright (c) 2000 Sean Walton and Macmillan Publishers. Use may be in
    8.  * whole or in part in accordance to the General Public License (GPL).
    9.  *
    10.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
    11.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    12.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    13.  * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
    14.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    15.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
    16.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    17.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
    18.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
    19.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
    20.  * SUCH DAMAGE.
    21. */
    22. /*****************************************************************************/
    23. /*** heartbeat-client.c ***/
    24. /*** ***/
    25. /*** Demonstrates how to keep track of the server using a "heartbeat". If ***/
    26. /*** the heartbeat is lost, the connection can be reestablished and the ***/
    27. /*** session resumed. ***/
    28. /*****************************************************************************/
    29. #include <stdio.h>
    30. #include <stdlib.h>
    31. #include <unistd.h>
    32. #include <string.h>
    33. #include <errno.h>
    34. #include <fcntl.h>
    35. #include <signal.h>
    36. #include <resolv.h>
    37. #include <netinet/tcp.h>
    38. #include <netinet/in.h>
    39. #include <arpa/inet.h>
    40. #include <sys/socket.h>

    41. #define SERVER_PORT 11111    //监听端口
    42. #define SERVER_HOST "127.0.0.1"    //服务器IP地址
    43. #define DELAY 2            /*seconds */

    44. //两个有用的宏定义:检查和赋值并且检测
    45. #define CHK(eval) if(eval < 0){perror("eval"); exit(-1);}
    46. #define CHK2(res, eval) if((res = eval) < 0){perror("eval"); exit(-1);}

    47. int serverfd, got_reply = 1;

    48. /*---------------------------------------------------------------------
    49.     sig_handler - if the single is OOB, set flag. If ALARM, send heartbeat.
    50.  ---------------------------------------------------------------------*/
    51. void sig_handler(int signum)
    52. {
    53.     int bytes, len;

    54.     struct tcp_info info;
    55.     int leng = sizeof(info);

    56.     if (signum == SIGURG) {
    57. //*
    58.         getsockopt(serverfd, IPPROTO_TCP, TCP_INFO, &info, (socklen_t *) &leng);
    59.         if ((info.tcpi_state == TCP_ESTABLISHED)) {        // socket connected
    60.             ; //return 1;
    61.         } else {        // socket disconnected
    62.             return;
    63.         }
    64. //*/
    65.         char c;
    66.         CHK2(bytes, recv(serverfd, &c, sizeof(c), MSG_OOB));
    67.         if (bytes == 0) return;

    68.         got_reply = (c == 'Y');    /* Got reply */
    69.         fprintf(stderr, "[server is alive] ");
    70.     } else if (signum == SIGALRM) {
    71.         printf("reply = %d ", got_reply);
    72.         if (got_reply) {
    73.             alarm(DELAY);    // Wait a while
    74. //*
    75.             getsockopt(serverfd, IPPROTO_TCP, TCP_INFO, &info, (socklen_t *) &leng);
    76.             if ((info.tcpi_state == TCP_ESTABLISHED)) {        // socket connected
    77.                 ; //return 1;
    78.             } else {        // socket disconnected
    79.                 return;
    80.             }
    81. //*/
    82.             CHK2(len, send(serverfd, "?", 1, MSG_OOB));        // Alive??
    83.             if (len == 0) return;
    84.             got_reply = 0;
    85.         } else {
    86.             fprintf(stderr, "Lost connection to server! ");
    87.             alarm(DELAY);    /* Wait a while */
    88.         }
    89.     }
    90. }

    91. /*---------------------------------------------------------------------
    92.     main - set up client and begin the heartbeat.
    93.  ---------------------------------------------------------------------*/
    94. int main(int count, char *strings[])
    95. {

    96.     int bytes, len;
    97.     char line[100];

    98.     struct tcp_info info;
    99.     int leng = sizeof(info);

    100.     struct sigaction act;
    101.     bzero(&act, sizeof(act));
    102.     act.sa_handler = sig_handler;
    103.     act.sa_flags = SA_RESTART;
    104.     sigaction(SIGURG, &act, 0);
    105.     sigaction(SIGALRM, &act, 0);

    106.     struct sockaddr_in seraddr;
    107.     seraddr.sin_family = PF_INET;
    108.     seraddr.sin_port = htons(SERVER_PORT);
    109.     seraddr.sin_addr.s_addr = inet_addr(SERVER_HOST);

    110.     CHK2(serverfd, socket(PF_INET, SOCK_STREAM, 0));
    111.     if (fcntl(serverfd, F_SETOWN, getpid()) != 0)    // claim SIGIO/SIGURG signals
    112.         perror("Can't claim SIGURG and SIGIO");

    113.     while (1)
    114.     {
    115.         got_reply = 1;

    116.         close(serverfd);
    117.         CHK2(serverfd, socket(PF_INET, SOCK_STREAM, 0));
    118.         if (fcntl(serverfd, F_SETOWN, getpid()) != 0) {        // claim SIGIO/SIGURG signals
    119.             perror("Can't claim SIGURG and SIGIO");
    120.             continue;
    121.         }

    122.         if (connect(serverfd, (struct sockaddr *)&seraddr, sizeof(seraddr)) == 0) {
    123.             printf("connect [OK] ");
    124.             alarm(DELAY);
    125.             do {
    126. //*
    127.                 getsockopt(serverfd, IPPROTO_TCP, TCP_INFO, &info, (socklen_t *) &leng);
    128.                 if ((info.tcpi_state == TCP_ESTABLISHED)) {        // socket connected
    129.                     ; //return 1;
    130.                 } else {        // socket disconnected
    131.                     break;
    132.                 }
    133. //*/
    134.                 //CHK2(len, send(serverfd, "?", 1, MSG_OOB));        // Alive??
    135.                 //got_reply = 0;
    136.                 //CHK2(len, send(serverfd, "restart", 7, 0));
    137.                 //printf("send [restart] ");
    138.                 memset(line, 0x00, 100);
    139.                 gets(line);
    140.                 printf("send [%s] ", line);
    141.                 //CHK2(len, send(serverfd, "adsf", 4, 0)); sleep(1);

    142.                 CHK2(len, send(serverfd, line, strlen(line), 0));        // send
    143.                 if (len <= 0) break;

    144.                 CHK2(bytes, recv(serverfd, line, sizeof(line), 0));        // recieve
    145.                 if (bytes <= 0) break;

    146.             } while (bytes > 0);

    147.             printf("end while ");

    148.         } else {
    149.             perror("connect failed, retry! ");
    150.             sleep(2);
    151.         }
    152.     }
    153.     //close(serverfd);
    154.     //return 0;
    155. }






    <script>window._bd_share_config={"common":{"bdSnsKey":{},"bdText":"","bdMini":"2","bdMiniList":false,"bdPic":"","bdStyle":"0","bdSize":"16"},"share":{}};with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];</script>
    阅读(49) | 评论(0) | 转发(0) |
    0

    上一篇:如何判断SOCKET已经断开

    下一篇:遗产

    给主人留下些什么吧!~~
    评论热议
  • 相关阅读:
    慕课网-安卓攻城狮视频学习及练习(二)
    慕课网-安卓攻城狮视频学习及练习(一)
    1126 Eulerian Path
    1127 ZigZagging on a Tree
    1128 N Queens Puzzle
    1129 Recommendation System
    1130 Infix Expression
    1131 Subway Map
    1132 Cut Integer
    1133 Splitting A Linked List
  • 原文地址:https://www.cnblogs.com/ztguang/p/12649392.html
Copyright © 2011-2022 走看看