Не могу понять пример epoll в руководстве - PullRequest
0 голосов
/ 16 апреля 2020

Недавно я учусь на системном звонке epoll. У меня уже есть основа c понятия об этой топике c, но я застрял в примере, приведенном в руководстве.

/* 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, то нам нужно создать новое соединение?

1 Ответ

2 голосов
/ 16 апреля 2020

Вы можете посмотреть на странице справки для epoll_wait подробности о struct epoll_event и его data члене и помочь разобраться в коде.

Любой данный events[n].data.fd относится к fd с каким-то событием. Это может быть либо сокет прослушивания, либо клиентский сокет при наличии активных клиентских подключений.

Если fd с активностью равен прослушивающий сокет listen_sock, это означает, что новый клиент пытается установить соединение. На этом этапе мы accept устанавливаем соединение и добавляем новый conn_sock fd к набору epoll '* fd s.

...