유닉스 네트워크 프로그래밍strcli의 epoll 구현

6037 단어
직접 코드를 올리고 이어서 설명하다
 1 #include "../lib/unp.h"
 2 #include <sys/epoll.h>
 3 
 4 void
 5 str_cli(FILE *fp, int sockfd)
 6 {
 7     int efd;
 8     struct epoll_event event;
 9     struct epoll_event events[20];
10     int i;
11     int nfds;
12     char        buf[MAXLINE];
13     int        n;
14 
15     efd = epoll_create (10);
16     if(efd<0){
17         err_sys("epoll create failed");
18     }
19     event.data.fd=fileno(fp);
20     event.events=EPOLLIN;
21     epoll_ctl(efd,EPOLL_CTL_ADD,fileno(fp),&event);
22 
23     event.data.fd=sockfd;
24     event.events=EPOLLIN;
25     epoll_ctl(efd,EPOLL_CTL_ADD,sockfd,&event);
26 
27 
28     for ( ; ; ) {
29         nfds=epoll_wait(efd,events,sizeof(events)/sizeof(struct epoll_event),-1);
30         if(nfds<0){
31             err_sys("epoll wait error %d ",errno);
32         }
33         for(i=0;i<nfds;i++){
34             if(events[i].data.fd==sockfd){
35                 if ( (n = Read(sockfd, buf, MAXLINE)) == 0) {
36                     err_quit("str_cli: server terminated prematurely");
37                 }
38                 Write(fileno(stdout), buf, n);
39             }
40             if(events[i].data.fd==fileno(fp)){
41                 if ( (n = Read(fileno(fp), buf, MAXLINE)) == 0) {
42                     close(sockfd);
43                     break;
44                 }
45 
46                 Writen(sockfd, buf, n);
47             }
48         }
49 
50     }
51     close(efd);
52 }

epoll은 주로 epoll 이 있어요.create,epoll_ctl,epoll_wait 세 함수,
참고로 이 블로그입니다.http://blog.csdn.net/xiajun07061225/article/details/9250579
epoll은 변화된 파일 설명자만 되돌려주기 때문에 select와poll에 비해 반복되는 낭비를 줄일 수 있습니다.
 
1. int epoll_create(int size);
epoll의 핸들을 만듭니다.linux2에서6.8 이후에는 크기 매개 변수가 무시됩니다.주의해야 할 것은 epoll 핸들을 만들면 fd 값을 차지합니다. linux에서/proc/프로세스 id/fd/를 보면 이 fd를 볼 수 있기 때문에 epoll을 사용한 후에close () 를 호출해서 닫아야 합니다. 그렇지 않으면 fd가 소모될 수 있습니다.
 
2. int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
epoll의 이벤트 등록 함수는 select () 와는 달리 이벤트를 감청할 때 내부 핵에 어떤 종류의 이벤트를 감청해야 하는지 알려주는 것이 아니라, 여기에 감청할 이벤트 형식을 먼저 등록합니다.
첫 번째 파라미터는 epollcreate()의 반환 값입니다.
두 번째 매개변수는 동작을 나타내고 다음 세 개의 매크로를 나타냅니다.
EPOLL_CTL_ADD: 새 fd를 epfd에 등록하기;
EPOLL_CTL_MOD: 등록된 fd의 감청 이벤트 수정하기;
EPOLL_CTL_DEL: epfd에서 fd 삭제;
 
세 번째 파라미터는 감청이 필요한 fd입니다.
네 번째 파라미터는 핵에 감청이 필요한 것을 알려주는 것이다.struct epoll이벤트 구조는 다음과 같습니다.
 
//트리거 이벤트의 어떤 파일 설명자와 관련된 데이터를 저장합니다 (구체적인 사용 방식과 관련이 있습니다)
  •   

  • typedef union epoll_data {  
  •     void *ptr;  

  •     int fd;  
  •     __uint32_t u32;  

  •     __uint64_t u64;  
  • } epoll_data_t;  

  • //관심 있는 사건과 촉발된 사건
  • struct epoll_event {  

  •     __uint32_t events; /* Epoll events */  
  •     epoll_data_t data; /* User data variable */  

  • };  
     
     
    이벤트는 다음과 같은 매크로의 집합일 수 있습니다.
    EPOLIN: 대응하는 파일 설명자를 읽을 수 있음을 나타냅니다(대단 SOCKET 정상 닫기 포함).
    EPOLLOUT: 해당 파일 설명자를 쓸 수 있음을 나타냅니다.
    EPOLPRI: 대응하는 파일 설명자에 긴급한 데이터가 읽을 수 있음을 표시한다(이곳은 대외 데이터가 왔다는 것을 표시해야 한다).
    EPOLLERR: 해당 파일 설명자에 오류가 발생했음을 나타냅니다.
    EPOLLHUP: 해당 파일 설명자가 끊겼음을 나타냅니다.
    EPOLLET: EPOLL을 모서리 트리거(Edge Triggered) 모드로 설정합니다. 이것은 수평 트리거(Level Triggered)에 상대적입니다.
    EPOLLONESHOT: 사건을 한 번만 감청하고, 이번 사건을 감청한 후에도 이 소켓을 계속 감청해야 한다면, 이 소켓을 EPOLL 대기열에 다시 넣어야 한다.
     
    3. int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout);
    epoll이 감시하는 이벤트에서 이미 발송된 이벤트를 수집합니다.매개 변수 이벤트는 분배된 epoll이벤트 구조체 수조, epoll은 발생하는 이벤트를 이벤트 수조에 값을 부여합니다. (이벤트는 빈 바늘이 될 수 없습니다. 내부 핵은 데이터를 이 이벤트 수조에 복사하는 것만 책임지고 사용자 상태에서 메모리를 분배하는 것을 도와주지 않습니다.)maxevents가 알려준 내부 핵 이 이벤트가 얼마나 큰지, 이 maxevents의 값은 창설 epoll 보다 클 수 없습니다.create () 시 크기, 매개 변수 timeout은 시간 초과 (밀리초, 0은 즉시 되돌아오고 -1은 확실하지 않으며 영구적으로 막힌다는 말도 있습니다.함수 호출이 성공하면 입출력에 대해 준비된 파일 설명자 수를 반환합니다. 예를 들어 0을 반환하면 시간 초과가 표시됩니다.

    좋은 웹페이지 즐겨찾기