1 #define POLL_FD_SIZE 1024 2 int doServicePoll(int listenFd) 3 { 4 struct sockaddr_in cliAddr; 5 socklen_t len; 6 7 int i; 8 struct pollfd pollFdSet[POLL_FD_SIZE]; 9 for(i = 0 ; i < POLL_FD_SIZE; i++) { 10 pollFdSet[i].fd = -1; 11 } 12 pollFdSet[0].fd = listenFd; 13 pollFdSet[0].events = POLLIN; 14 15 int pollRet; 16 int fdNum = 0; //表示数组的下标 17 18 int acceptFd; 19 int readNum; 20 while(1) { 21 pollRet = poll(pollFdSet, fdNum + 1, 10000); //fdNum + 1表示数组的界限 22 if(pollRet < 0) { 23 if(errno == EINTR) continue; 24 ERR_EXIT("poll"); 25 } else if(pollRet == 0) { 26 continue; 27 } 28 if(pollFdSet[0].revents & POLLIN) { //注意点 是& 而不是== 29 memset(&cliAddr, 0, sizeof(cliAddr)); 30 len = sizeof(cliAddr); 31 if((acceptFd = accept(pollFdSet[0].fd, (struct sockaddr *)&cliAddr, &len)) < 0) { 32 ERR_EXIT("accept"); 33 } 34 printf("recv a connect from %s, port %d, fd %d ", 35 inet_ntoa(cliAddr.sin_addr), ntohs(cliAddr.sin_port), acceptFd); 36 for(i = 1; i < (POLL_FD_SIZE -1); i++) { 37 if(pollFdSet[i].fd == -1) { 38 pollFdSet[i].fd = acceptFd; 39 pollFdSet[i].events = POLLIN; 40 if(i > fdNum) { 41 fdNum = i; 42 } 43 break; 44 } 45 } 46 if(i == POLL_FD_SIZE -1) { 47 ERR_EXIT("too many clients!"); 48 } 49 if(--pollRet == 0) continue; 50 } 51 52 for(i = 1; i < (fdNum +1); i++) { 53 if(pollFdSet[i].fd < 0) { 54 continue; 55 } 56 if(pollFdSet[i].revents & POLLIN) { //注意点 是& 而不是== 57 printf("need recv msg "); 58 readNum = handleRead(pollFdSet[i].fd); 59 if(readNum == READ_ERROR) { 60 ERR_EXIT("handleRead"); 61 } else if(readNum == READ_CLOSE) { 62 close(pollFdSet[i].fd); 63 printf("client closed, remove %d ", i); 64 pollFdSet[i].fd = -1; 65 if(i == fdNum) { 66 fdNum--; 67 } 68 } 69 if(--pollRet == 0) { 70 break; 71 } 72 } 73 } 74 } 75 }
注意点:
1 pollFdSet[i].fd == -1 是判断是否需要监听的条件。
2 fdNum是表示监听描述符的个数。
3 判断是否可读 是通过 pollFdSet[i].revents & POLLIN 是否为真来表示的,其他可写等亦如此。