Computer Science 기본 지식/소켓 프로그래밍

[TCP/IP 소켓 프로그래밍] (11-2) 다중 접속 서버 - 레벨 트리거/엣지 트리거

로파이 2021. 4. 5. 20:15

출처 : 열혈 TCP/IP 소켓 프로그래밍 윤성우 저

 

epoll 기반 이벤트 발생

이벤트 발생 감지(트리거)에 대한 기준을 두가지로 변경할 수 있다.

1. 레벨 트리거: 입력버퍼에 데이터가 남아있는 동안에 계속해서 이벤트가 등록된다.

2. 엣지 트리거: 입력버퍼에 데이터가 처음 수신될 때 이벤트가 등록된다.

기본 트리거 방식은 레벨 트리거이다.

 

- 엣지 트리거 설정

struct epoll_event;

event.events = EPOLLIN(수신 데이터 감지) | EPOLLET(엣지 트리거);

 

- 소켓 속성 변경

엣지 트리거 방식의 특성상 블로킹 방식으로 동작하는 read & write 함수의 호출은 서버를 오랜 시간 멈추는 상황으로 이어질 수 있다. 엣지 트리거 방식에서는 소켓을 논블로킹 모드에서 read & write 함수를 호출해야한다.

 

다음 함수를 이용하여 소켓 설정을 변경한다.

int fcntl(int filedes, int cmd, ...);
  • 특성 변경의 대상이 되는 파일의 디스크립터 전달
  • 함수 호출의 목적에 해당하는 정보 전달
int flag = fcntl(fd, F_GETFL, 0);  // 기존 속성 정보
fcntl(fd, F_SETFL, flag|O_NONBLOCK);  // 논블로킹 속성 추가

 

epoll 서버 -  엣지 트리거 버전

레벨 트리거 버전의 코드에서 클라이언트에게 에코 메시지를 전송하는 부분에서 다른 점이 있다.

기본 데이터 수신은 4바이트씩 읽는다. BUF_SIZE 4;

수신 버퍼가 더 이상 읽을 데이터가 없을 경우

read 결과로 에러(-1)이 반환되 었을 때, #include <errno.h>의 errno가 EAGAIN이 되는 상황, 수신 버퍼에 더이상 읽을 데이터가 없음을 의미한다.

                // read all data in buffer
                while(1)
                {
                    // read 4 bytes
                    str_len = read(ep_events[i].data.fd, buf, BUF_SIZE);
                    if(str_len == 0) // close request
                    {
                    	// remove registration
                        epoll_ctl(epfd, EPOLL_CTL_DEL, ep_events[i].data.fd, NULL);
                        close(ep_events[i].data.fd);
                        printf("closed client: %d \n", ep_events[i].data.fd);
                        break;
                    }
                    else if(str_len < 0)
                    {
                        // empty buffer
                        if(errno==EAGAIN)
                            break;
                    }
                    else
                    {
                        write(ep_events[i].data.fd, buf, str_len);
                    }   
                }

 

엣지 트리거의 장점

 

데이터의 수신과 데이터가 처리되는 시점을 분리할 수 있다. 언제 데이터를 처리할 것인가? 종류와 로직에 따른 다른 구현이 필요할 때 유연한 서버 모델을 제공한다.