Chinaunix首页 | 论坛 | 博客
  • 博客访问: 200482
  • 博文数量: 70
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 865
  • 用 户 组: 普通用户
  • 注册时间: 2013-02-01 20:58
文章分类

全部博文(70)

文章存档

2015年(10)

2014年(15)

2013年(45)

我的朋友

分类: LINUX

2013-04-17 23:25:18


点击(此处)折叠或打开

  1. //-----------------------------------------------
  2. //TCP并发服务器
  3. //
  4. //-----------------------------------------------

  5. #include <stdio.h>
  6. #include <unistd.h>
  7. #include <sys/types.h>
  8. #include <sys/socket.h>
  9. #include <errno.h>
  10. #include <stdlib.h>
  11. #include <arpa/inet.h>
  12. #include <netinet/in.h>
  13. #include <strings.h>
  14. #include <signal.h>

  15. #define N 64


  16. //---------------- 信号处理 -----------------

  17. void handler(int signo)
  18. {

  19.     // ------------- wait --------------
  20.     //可能由于段时间大量的子进程结束而一起发送信号可能会被内核合并成一个信号
  21.     //而导致生产僵死状态的子进程

  22.     //--------------- 用waitpid解决 ---------------
  23. #if 0
  24.     int status;
  25.     pid_t ret;

  26.     ret = wait(&status);
  27.     printf("child %d terminate; exit code=%#x\n", ret, status);
  28. #endif

  29.     pid_t ret;

  30.     while ((ret = waitpid(-1, NULL, WNOHANG)) > 0)
  31.     {
  32.         //perror("waitpid");
  33.         printf("child %d terminate\n", ret);
  34.     }
  35. }

  36. int main(int argc, char *argv[] ) //./server 192.168.1.30 9000
  37. {
  38.     int listenfd, connfd;
  39.     struct sockaddr_in myaddr, peeraddr;
  40.     socklen_t len;
  41.     char buf[N] = {0};
  42.     ssize_t n;
  43.     pid_t pid;

  44.     if (argc != 3)
  45.     {
  46.         printf("usage:%s serverip serverport\n", argv[0]);
  47.         return 0;
  48.     }

  49.     signal(SIGCHLD, handler); // 注册信号

  50.     //------------------创建套接字--------------------
  51.     if ((listenfd = socket(PF_INET, SOCK_STREAM, 0)) == -1)
  52.     {
  53.         perror("socket");
  54.         exit(-1);
  55.     }

  56.     bzero(&myaddr, sizeof(myaddr));
  57.     bzero(&peeraddr, sizeof(peeraddr));

  58.     myaddr.sin_family = PF_INET;
  59.     myaddr.sin_port = htons(atoi(argv[2]));//htons(6000);
  60.     myaddr.sin_addr.s_addr = inet_addr(argv[1]);


  61.     //------------------ 绑定 --------------------
  62.     if (-1 == bind(listenfd, (struct sockaddr *)&myaddr, sizeof(myaddr)))
  63.     {
  64.         perror("bind");
  65.         exit(-1);
  66.     }

  67.     //------------------ 监听 --------------------
  68.     if (-1 == listen(listenfd, 5))
  69.     {
  70.         perror("listen");
  71.         exit(-1);
  72.     }

  73.     len = sizeof(peeraddr);
  74.     while (1)
  75.     {
  76.         //------------------ accept 阻塞 --------------------
  77.         if ((connfd = accept(listenfd, (struct sockaddr *)&peeraddr, &len)) == -1)
  78.         {
  79.             perror("accept");
  80.             exit(-1);
  81.         }

  82.         printf("from %s : %d\n", inet_ntoa(peeraddr.sin_addr) ,
  83.                 ntohs(peeraddr.sin_port));
  84.     
  85.         if ((pid = fork()) == -1) // 连接成功后创建子进程 来完成收发工作
  86.         {
  87.             perror("fork");
  88.             exit(-1);
  89.         }

  90.         if (pid == 0) // 子进程
  91.         {
  92.             close(listenfd);
  93.             while (1)
  94.             {
  95.                 bzero(buf, sizeof(buf));
  96.                 n = recv(connfd, buf, N, 0);//read(connfd, buf, N);
  97.                 printf("n=%d buf=%s", n, buf);
  98.                 if (n == 0)
  99.                     break;
  100.                 send(connfd, buf, n, 0); //write(connfd, buf, n);
  101.             }
  102.             close(connfd);
  103.             exit(0);
  104.         }
  105.         else
  106.             close(connfd); //父进程关闭 连接描述符
  107.     }


  108.     return 0;
  109. }

阅读(1601) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~