49-使用 poll 改写服务器

在前面,我们使用了 select 改写了服务器,本文使用 poll 来改写服务器。

1. 程序路径

代码托管在 gitos 上,请使用下面的命令获取:

git clone https://git.oschina.net/ivan_allen/unp.git

如果你已经 clone 过这个代码了,请使用 git pull 更新一下。本节程序所使用的程序路径是 unp/program/echo/multiplexing_poll_server

2. 回忆 poll 函数

#include <poll.h>  int poll(struct pollfd *fds, nfds_t nfds, int timeout);  struct pollfd {   int   fd;         /* file descriptor */   short events;     /* requested events */   short revents;    /* returned events */ };

如果你忘记了 poll 函数的用法,请参考《poll 函数》

3. 使用 poll 改写服务器

使用 poll 改写服务器,要比使用 select 函数简单的多。在 poll 这个版本中,我们只需要一个 struct pollfd 类型的数组即可。关于此数组的大小限制,由宏 OPEN_MAX,但是现代的 linux 内核已经将这个宏废弃,所以大家需要使用 POSIX 的 sysconf 函数,并指定其参数 _SC_OPEN_MAX 来动态获取这个值。

在我们的例子中,我只是简单的将 OPEN_MAX 指定为 1024.

服务器伪代码:

#define OPEN_MAX 1024 void server_routine() {   // ...   struct pollfd fds[OPEN_MAX];   listen(listenfd);    // 将 fd 成员初始化为 -1   for (i = 0; i < OPEN_MAX; ++i) fds[i].fd = -1;    fds[0].fd = listenfd;   fds[0].events = POLLIN; // 监听读事件    while(1) {     nready = poll(fds, OPEN_MAX, 0);      for(i = 0; i < OPEN_MAX; ++i) {       if (fds[i].fd == -1) continue;       if (fds[i].fd == listenfd && fds[i].revents & POLLIN) {         // 接受新连接         sockfd = accept(listenfd);         // 在 fds 找一个空闲位置,将新连接加入         insert(fds, sockfd);         if (--nready <= 0) break;       }       else if(fds[i] & POLLIN) {         // 处理客户端数据         ret = doServer(fds[i].fd);         if (ret == 0) {           close(fds[i].fd);           fds[i].fd = -1;         }         if (--nready <= 0) break;       }      }   } }

4. 程序运行结果

运行方式很简单,和之前的实验没什么两样:


这里写图片描述
图1 服务器和客户端正常工作

5. 总结

  • 掌握 poll 函数

说明:本文转自blog.csdn.net,用于学习交流分享,仅代表原文作者观点。如有疑问,请联系我们删除~