Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2112765
  • 博文数量: 438
  • 博客积分: 3871
  • 博客等级: 中校
  • 技术积分: 6075
  • 用 户 组: 普通用户
  • 注册时间: 2011-09-10 00:11
个人简介

邮箱: wangcong02345@163.com

文章分类

全部博文(438)

文章存档

2017年(15)

2016年(119)

2015年(91)

2014年(62)

2013年(56)

2012年(79)

2011年(16)

分类: LINUX

2015-06-17 17:42:58

1. 流程描述
跟select很类似,注意这儿将client的第0项固定为listen的socket,
for循环要从1开始遍历
2. 代码
  1. cong@msi:/work/test/tcpip/13poll/serv$ cat tcpserv.c
  2. #include "utils.h"

  3. int main ( int argc, char *argv[] )
  4. {
  5.     ssize_t n;
  6.     int i, maxi;
  7.     int listenfd, connfd, sockfd;
  8.     int nready;
  9.     struct pollfd client[OPEN_MAX];                 -->只需要分配一个pollfd即可
  10.     struct sockaddr_in servaddr, cliaddr;
  11.     char buf[MAXLINE];
  12.     socklen_t clilen;
  13.     listenfd = socket(AF_INET, SOCK_STREAM, 0);
  14.     if(listenfd< 0)
  15.         return -1;
  16.     bzero(&servaddr, sizeof(servaddr));
  17.     servaddr.sin_family = AF_INET;
  18.     servaddr.sin_port = htons(13999);
  19.     servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
  20.     //inet_pton(AF_INET, TIME_SERV_ADDR, &servaddr.sin_addr);
  21.      
  22.     bind(listenfd, (const struct sockaddr*)&servaddr, sizeof(servaddr));
  23.     listen(listenfd, LISTENQ);
  24.     //把第0项固定为listen的socket,其它的作为client的socket
  25.     client[0].fd = listenfd;
  26.     client[0].events = POLLRDNORM;
  27.     maxi = 0;
  28.     for(i=1; i<OPEN_MAX; i++)
  29.         client[i].fd = -1;    -->其它的sockfd都设为-1
  30.     while(1)
  31.     {
  32.         nready = poll(client, maxi+1, INFTIM);
  33.         if(nready<0)
  34.             continue;
  35.         if(client[0].revents & POLLRDNORM)  -->当有变化时先检查固定的listen的socket是否有变化
  36.         {                                   -->若有变化,说明client有连接
  37.             clilen = sizeof(cliaddr);
  38.             connfd = accept(listenfd, (struct sockaddr*)&cliaddr,&clilen);
  39.             for(i=0; i<OPEN_MAX; i++)
  40.             {
  41.                 if(client[i].fd < 0)
  42.                 {
  43.                     client[i].fd = connfd;
  44.                     break;
  45.                 }
  46.             }
  47.             if(i==OPEN_MAX)
  48.                 dbmsg("too many clients");
  49.             client[i].events = POLLRDNORM;
  50.             if(i>maxi)
  51.                 maxi = i;
  52.             if(--nready <= 0)
  53.                 continue;
  54.         }
  55.         for(i=1; i<=maxi; i++)                  -->第0个socket固定为listen,所以从第1个socket开始遍历
  56.         {                                       -->若有变化,说明client有数据
  57.             if( (sockfd = client[i].fd) < 0)
  58.                 continue;
  59.             //if(FD_ISSET(sockfd, &rset))
  60.             if(client[i].revents & (POLLRDNORM|POLLERR))
  61.             {
  62.                 if( (n=read(sockfd, buf, MAXLINE)) < 0)  -->当收到client的数据<0时
  63.                 {
  64.                     if(errno == ECONNRESET)              -->如果是ECONNRESET,则说明client退出
  65.                     {
  66.                         close(sockfd);
  67.                         client[i].fd = -1;
  68.                     }
  69.                 }else {
  70.                     write(sockfd, buf, n);
  71.                 }
  72.                 if(--nready <= 0)
  73.                     break;
  74.             }
  75.         }
  76.     }
  77.     return EXIT_SUCCESS;
  78. }

serv.rar (下载后改名为serv.tar.gz)
client.rar (下载后改名为client.tar.gz)
阅读(877) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~