Chinaunix首页 | 论坛 | 博客
  • 博客访问: 6684663
  • 博文数量: 1159
  • 博客积分: 12444
  • 博客等级: 上将
  • 技术积分: 12570
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-13 21:34
文章分类

全部博文(1159)

文章存档

2016年(126)

2015年(350)

2014年(56)

2013年(91)

2012年(182)

2011年(193)

2010年(138)

2009年(23)

分类: C/C++

2015-12-20 17:22:58

/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\n", buffer, client);
  81.         if (bytes > 0)
  82.             send(client, buffer, bytes, 0);
  83.     } while (bytes > 0);

  84.     printf("end while\n");

  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\n");
  114.     CHK(listen(listener, LISTEN_SIZE));    //设置监听
  115.     printf("server: listening\n");

  116.     while (1) {
  117.         client = accept(listener, (struct sockaddr *)&peer, &socklen);
  118.         printf("accept client-%d\n", 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]\n");
  70.     } else if (signum == SIGALRM) {
  71.         printf("reply = %d\n", 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!\n");
  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]\n");
  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]\n");
  138.                 memset(line, 0x00, 100);
  139.                 gets(line);
  140.                 printf("send [%s]\n", 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\n");

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






阅读(2064) | 评论(0) | 转发(0) |
0

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

下一篇:遗产

给主人留下些什么吧!~~