TCP/IP Accept接口由 epoll来管理的实现思路

177 阅读1分钟
int main(int argc, char* argv[])
{
   /*
   * 在这里进行一些初始化的操作,
   * 比如初始化数据和socket等。
   */

    // 内核中创建ep对象
    epfd=epoll_create(256);
    // 需要监听的socket放到ep中
    epoll_ctl(epfd,EPOLL_CTL_ADD,listenfd,&ev);
 
    while(1) {
      // 阻塞获取
      nfds = epoll_wait(epfd,events,20,0);
      for(i=0; i<nfds; ++i) {
      	  // 判断有事件的监听socket,则说明有新的连接到来了
          if(events[i].data.fd == listenfd) {
              // 如果是ET模式,在某一时刻,有多个连接同时到达,服务器的 TCP 就绪队列瞬间积累多个就绪连接,但
              // epoll 只会通知一次,accept 只处理一个连接,导致 TCP 就绪队列中剩下的连接都得不到处理。在这种情形下,我们应该如何有效的处理呢?
              // 解决的方法是:用 while 循环抱住 accept 调用,处理完 TCP 就绪队列中的所有连接后再退出循环。
              // 如何知道是否处理完就绪队列中的所有连接呢? accept 返回 -1 并且errno设置为 EAGAIN 就表示所有连接都处理完。 
              // 这里处理accept事件
              connfd = accept(listenfd);
              // 将新连接加入到epoll中管理读写事件
              epoll_ctl(epfd, EPOLL_CTL_ADD, connfd, &ev);
          } else if (events[i].events&EPOLLIN) {
              // 这里处理read事件,如果是ET模式,则需要循环读,直至数据读完
              read(sockfd, BUF, MAXLINE);
          } else if(events[i].events&EPOLLOUT) {
              // 这里处理write事件
              write(sockfd, BUF, n);
          }
      }
    }
    return 0;
}