49-使用 poll 改写服务器

来源:互联网 发布:约旦语言翻译软件 编辑:程序博客网 时间:2024/05/16 16:18

在前面,我们使用了 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 1024void 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 函数
0 0
原创粉丝点击