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, -1);

    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. 程序运行结果

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

https://img-blog.csdn.net/20170424134930080?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcTEwMDc3Mjk5OTE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast

图1 服务器和客户端正常工作

5. 总结

  • 掌握 poll 函数
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值