Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1551133
  • 博文数量: 61
  • 博客积分: 472
  • 博客等级: 下士
  • 技术积分: 548
  • 用 户 组: 普通用户
  • 注册时间: 2012-03-26 11:52
文章分类
文章存档

2018年(1)

2017年(2)

2016年(6)

2015年(3)

2014年(19)

2013年(10)

2012年(20)

分类: LINUX

2014-11-01 19:33:52

原文地址:tcp/ip 服务器 poll模型 作者:asteriskchina

上一节,学习了select模型的实现方式,本节学习poll是否方式,为接下来学习epoll模型作准备。很显然epoll是对poll方式的改进,先看poll是如何工作的。


点击(此处)折叠或打开

  1. /* include fig01 */
  2. #include "unp.h"
  3. #include <limits.h> /* for OPEN_MAX */

  4. int
  5. main(int argc, char **argv)
  6. {
  7.     int i, maxi, listenfd, connfd, sockfd;
  8.     int nready;
  9.     ssize_t n;
  10.     char buf[MAXLINE];
  11.     socklen_t clilen;
  12.     struct pollfd client[OPEN_MAX];
  13.     struct sockaddr_in cliaddr, servaddr;

  14.     listenfd = Socket(AF_INET, SOCK_STREAM, 0);

  15.     bzero(&servaddr, sizeof(servaddr));
  16.     servaddr.sin_family = AF_INET;
  17.     servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
  18.     servaddr.sin_port = htons(SERV_PORT);

  19.     Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));

  20.     Listen(listenfd, LISTENQ);

  21.     client[0].fd = listenfd;
  22.     client[0].events = POLLRDNORM; //监听读事件
  23.     for (i = 1; i < OPEN_MAX; i++)
  24.         client[i].fd = -1; /* -1 indicates available entry */
  25.     maxi = 0; /* max index into client[] array */
  26. /* end fig01 */

  27. /* include fig02 */
  28.     for ( ; ; ) {
  29.         nready = Poll(client, maxi+1, INFTIM);

  30.         if (client[0].revents & POLLRDNORM) { /* 新的连接到来 */
  31.             clilen = sizeof(cliaddr);
  32.             connfd = Accept(listenfd, (SA *) &cliaddr, &clilen);
  33. #ifdef NOTDEF
  34.             printf("new client: %s\n", Sock_ntop((SA *) &cliaddr, clilen));
  35. #endif

  36.             for (i = 1; i < OPEN_MAX; i++)
  37.                 if (client[i].fd < 0) {
  38.                     client[i].fd = connfd; /* 保存描述符到client数组中 */
  39.                     break;
  40.                 }
  41.             if (i == OPEN_MAX)
  42.                 err_quit("too many clients");

  43.             client[i].events = POLLRDNORM; //设置为监听读事件
  44.             if (i > maxi)
  45.                 maxi = i; /* max index in client[] array */

  46.             if (--nready <= 0)
  47.                 continue; /* no more readable descriptors */
  48.         }

  49.         for (i = 1; i <= maxi; i++) { /* check all clients for data */
  50.             if ( (sockfd = client[i].fd) < 0)
  51.                 continue;
  52.             if (client[i].revents & (POLLRDNORM | POLLERR)) {
  53.                 if ( (n = read(sockfd, buf, MAXLINE)) < 0) {
  54.                     if (errno == ECONNRESET) {
  55.                             /*4connection reset by client */
  56. #ifdef NOTDEF
  57.                         printf("client[%d] aborted connection\n", i);
  58. #endif
  59.                         Close(sockfd);
  60.                         client[i].fd = -1;
  61.                     } else
  62.                         err_sys("read error");
  63.                 } else if (n == 0) {
  64.                         /*4connection closed by client */
  65. #ifdef NOTDEF
  66.                     printf("client[%d] closed connection\n", i);
  67. #endif
  68.                     Close(sockfd);
  69.                     client[i].fd = -1;
  70.                 } else
  71.                     Writen(sockfd, buf, n);

  72.                 if (--nready <= 0)
  73.                     break; /* no more readable descriptors */
  74.             }
  75.         }
  76.     }
  77. }
  78. /* end fig02 */


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