2013-03-08 37 views
1

在UNIX網絡編程卷1:圖6-22,有一段代碼如下:如何在此代碼中使用epoll而不是select?

/* include fig01 */ 
#include "unp.h" 

int main(int argc, char **argv) 
{ 

int     i, maxi, maxfd, listenfd, connfd, sockfd; 
int     nready, client[FD_SETSIZE]; 
ssize_t    n; 
fd_set    rset, allset; 
char    buf[MAXLINE]; 
socklen_t   clilen; 
struct sockaddr_in cliaddr, servaddr; 

listenfd = Socket(AF_INET, SOCK_STREAM, 0); 

bzero(&servaddr, sizeof(servaddr)); 
servaddr.sin_family  = AF_INET; 
servaddr.sin_addr.s_addr = htonl(INADDR_ANY); 
servaddr.sin_port  = htons(SERV_PORT); 

Bind(listenfd, (SA *) &servaddr, sizeof(servaddr)); 

Listen(listenfd, LISTENQ); 

maxfd = listenfd;   /* initialize */ 
maxi = -1;     /* index into client[] array */ 
for (i = 0; i < FD_SETSIZE; i++) 
    client[i] = -1;   /* -1 indicates available entry */ 
FD_ZERO(&allset); 
FD_SET(listenfd, &allset); 
/* end fig01 */ 

/* include fig02 */ 
for (; ;) { 
    rset = allset;  /* structure assignment */ 
    nready = Select(maxfd+1, &rset, NULL, NULL, NULL); 

    if (FD_ISSET(listenfd, &rset)) { /* new client connection */ 
     clilen = sizeof(cliaddr); 
     connfd = Accept(listenfd, (SA *) &cliaddr, &clilen); 
#ifdef NOTDEF 
     printf("new client: %s, port %d\n", 
       Inet_ntop(AF_INET, &cliaddr.sin_addr, 4, NULL), 
       ntohs(cliaddr.sin_port)); 
#endif 

     for (i = 0; i < FD_SETSIZE; i++) 
      if (client[i] < 0) { 
       client[i] = connfd; /* save descriptor */ 
       break; 
      } 
     if (i == FD_SETSIZE) 
      err_quit("too many clients"); 

     FD_SET(connfd, &allset); /* add new descriptor to set */ 
     if (connfd > maxfd) 
      maxfd = connfd;   /* for select */ 
     if (i > maxi) 
      maxi = i;    /* max index in client[] array */ 

     if (--nready <= 0) 
      continue;    /* no more readable descriptors */ 
    } 

    for (i = 0; i <= maxi; i++) { /* check all clients for data */ 
     if ((sockfd = client[i]) < 0) 
      continue; 
     if (FD_ISSET(sockfd, &rset)) { 
      if ((n = Read(sockfd, buf, MAXLINE)) == 0) { 
        /*4connection closed by client */ 
       Close(sockfd); 
       FD_CLR(sockfd, &allset); 
       client[i] = -1; 
      } else 
       Writen(sockfd, buf, n); 

      if (--nready <= 0) 
       break;    /* no more readable descriptors */ 
     } 
    } 
} 
} 
/* end fig02 */ 

我想知道如何在這裏使用「epoll的」,而不是「選擇」,但我有關於epoll的小知識,所以任何人都可以給我一些觀點?謝謝。

回答

3

你可以通過這個link。但是,使用epoll的之前,你需要確保下面的點 -

  1. 你想對你的系統進行有針對性的跨平臺系統(我的意思是它可以在多個操作系統上運行?) - 因爲epoll的僅在Linux系統中可用。

  2. 你的Linux內核版本是什麼?因爲epoll僅在Linux 2.6中可用。如果這兩個問題都得到解答,並且您感覺到epoll不是一種限制,那麼您可以繼續這樣做。

HTH!

+0

還有一點需要指出:你想在邊緣觸發模式下使用epoll還是epoll?除非啓用邊沿觸發模式,否則使用epoll覆蓋選擇幾乎沒有什麼優勢。 – 2013-03-09 19:06:28

相關問題