Работа с сокетом прослушивания от epoll - PullRequest
3 голосов
/ 19 июня 2011

Все ниже от man epoll страницы:

Функция do_use_fd () использует новый готовый файловый дескриптор пока EAGAIN не будет возвращен либо read (2), либо write (2).

Пример кода для ET срабатывает :

   for(;;) {
       nfds = epoll_wait(kdpfd, events, maxevents, -1);

       for(n = 0; n < nfds; ++n) {
           if(events[n].data.fd == listener) {
               client = accept(listener, (struct sockaddr *) &local,
                               &addrlen);
               if(client < 0){
                   perror("accept");
                   continue;
               }
               setnonblocking(client);
               ev.events = EPOLLIN | EPOLLET;
               ev.events = EPOLLIN | EPOLLET;
               ev.data.fd = client;
               if (epoll_ctl(kdpfd, EPOLL_CTL_ADD, client, &ev) < 0) {
                   fprintf(stderr, "epoll set insertion error: fd=%d\n",
                           client);
                   return -1;
               }
           }
           else
               do_use_fd(events[n].data.fd);
       }
   }

Так что для операции read/write мы должны делать это циклично, пока не будет получен EAGAIN, но почему это не так для accept?

IMO, приведенный выше код пропустит некоторые запросы, когда есть несколько клиентских сокетов, ожидающих принятия, так как он принимает только 1 клиентский сокет, мы должны также обернуть его в цикл до получения EAGAIN .

Или, может, мне чего-то не хватает?

1 Ответ

5 голосов
/ 19 июня 2011

Посмотрите, как сокет слушателя добавляется к epollfd:

ev.events = EPOLLIN;       // this is the crucial bit
ev.data.fd = listen_sock;

Он не добавляется в триггерном режиме, он добавляется в триггерном уровне. Так что нет необходимости в цикле, пока EAGAIN на этом.

...