【问题标题】:Can't figure out epoll example in manual无法在手册中找出 epoll 示例
【发布时间】:2020-04-16 04:42:06
【问题描述】:

最近在学习系统调用epoll。我已经有了关于这个主题的基本概念,但我坚持使用手册给出的示例。

/* Code to set up listening socket, 'listen_sock',
              (socket(), bind(), listen()) omitted */

epollfd = epoll_create1(0);
if (epollfd == -1) {
   perror("epoll_create1");
   exit(EXIT_FAILURE);
}

ev.events = EPOLLIN;
ev.data.fd = listen_sock;
if (epoll_ctl(epollfd, EPOLL_CTL_ADD, listen_sock, &ev) == -1) {
   perror("epoll_ctl: listen_sock");
   exit(EXIT_FAILURE);
}

for (;;) {
   nfds = epoll_wait(epollfd, events, MAX_EVENTS, -1);
   if (nfds == -1) {
       perror("epoll_wait");
       exit(EXIT_FAILURE);
   }

   for (n = 0; n < nfds; ++n) {
       if (events[n].data.fd == listen_sock) {
           conn_sock = accept(listen_sock,
                              (struct sockaddr *) &addr, &addrlen);
           if (conn_sock == -1) {
               perror("accept");
               exit(EXIT_FAILURE);
           }
           setnonblocking(conn_sock);
           ev.events = EPOLLIN | EPOLLET;
           ev.data.fd = conn_sock;
           if (epoll_ctl(epollfd, EPOLL_CTL_ADD, conn_sock,
                       &ev) == -1) {
               perror("epoll_ctl: conn_sock");
               exit(EXIT_FAILURE);
           }
       } else {
           do_use_fd(events[n].data.fd);
       }
   }
}

以下是我的假设:

  • 以上是服务器代码。
  • listen_sock 是从服务器中的socket() 返回的文件描述符。

我的问题是:

  1. 文件描述符events[n].data.fd 是什么意思?是服务器的fd 还是客户端的?

  2. 为什么如果events[n].data.fd == listen_sock,那么我们需要创建一个新的连接?

【问题讨论】:

标签: c sockets epoll


【解决方案1】:

您可以查看 epoll_wait 的手册页以了解有关 struct epoll_event 及其 data 成员的详细信息并帮助理解代码。

任何给定的events[n].data.fd 指的是一个有某种事件的fd。它可以是侦听套接字,也可以是客户端套接字(如果有活动的客户端连接)。

如果带有活动fdlisten_sock 监听套接字,这意味着一个新的客户端正在尝试连接。此时我们accept 连接并将新的conn_sock fd 添加到epollfds 集合中。

【讨论】:

  • 你能给我一个关于进入else块的场景吗?我想知道除了尝试连接服务器的人之外,什么样的活动可以让 fd 的状态发生变化。
  • 确保在处理新连接的if 块中的epoll_ctl(epollfd, EPOLL_CTL_ADD, conn_sock, &amp;ev) 调用会将客户端连接的套接字添加fds 的集合中进行轮询。在随后对epoll_wait 的调用中,如果客户端有可用数据,代码将分支到else 语句。
  • 当客户端调用connect 连接到服务器中的套接字listen_sock 时,为什么我们要检查服务器中conn_sock 的状态(数据是否可用)?
  • 这不是套接字编程的工作方式。请参阅问题下方 cmets 中其他用户提供的链接,以获取有关套接字编程的帮助。也可以查看wikipedia
  • 感谢您的提示,accept 将创建上面参考中提到的新文件描述符。我会选择你作为答案!
猜你喜欢
  • 1970-01-01
  • 2013-01-10
  • 2020-06-16
  • 2015-07-30
  • 2018-02-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多