출처 : 열혈 강의 TCP/ IP 프로그래밍
멀티 플렉싱 서버의 구현에 있어서 가장 대표적인 방법이다.
윈도우에도 이와 동일한 이름으로 동일한 기능을 제공하는 함수가 있어 이식성 또한 높다.
+ select 함수의 기능과 호출 순서
- 여러개의 파일 디스크립터를 모아 놓고 동시에 이들을 관리할수 있다
- 리눅스는 소켓 역시 파일이니 소켓 또한 비슷하게 관리할 수 있다
블록킹 되지 않고 데이터의 전송이 가능한 소켓은 무엇?
- 위에서 관찰항목이 각각 이벤트라고 하고 상황이 발생하는 것을 이벤트가 발생했다고 한다.
- 멀티 플렉싱 서버의 구현을 위해서는 select 함수를 잘 이해하고 이를 소켓에 적용해야 한다.
- select 함수의 호출 순서
- step1
- 파일 디스크립터의 설정
- 검사의 범위 설정
- 타임 아웃의 설정
- step2
- step3
+ 파일 디스크립터의 설정
- select 함수를 사용하면 여러개의 파일 디스크립터를 동시에 관찰 가능 ( 소켓의 관찰 )
- 모을때 관찰 항목 ( 수신, 전송, 예외) 에 따라서 구분해서 모아야 한다.
- 파일 디스크립터를 세묶음으로 모을때 사용되는 것이 fd_set 형 변수
- fd0 ~ fd3 까지 0과 1로 표현되는 비트 단위로 이루어진 배열
- 1로 설정되면 디스크립터가 관찰 대상임을 의미
- fd_set 형 변수에 값을 등록하거나 변경하는 등의 작업은 아래의 매크로를 통해 이루어짐
- FD_ZERO(fd_set* fdset)
- 인자로 전달된 주소의 fd_set 형 변수의 모든 비트를 0으로 초기화
- FD_SET(int fd, fd_set *fd_set)
- 매개변수로 전달된 fd 로 파일 디스크립터를 등록
- FD_CLR(int fd, fd_set *fd_set)
- 매개 변수 로 전달된 fd 의 파일 디스크립터를 정보를 삭제
- FD_ISSET(int fd, fd_Set *fd_set)
- 매개변수 fdset 으로 전달된 주소의 변수에 매개변수 fd로 전달된 파일 디스크립터 정보가 있으면 양수를 반환한다.
+ 검사(관찰) 의 범위 지정과 타임 아웃의 설정
- step One 의 파일 디스크립트 설정 이외의 나머지 두부분
+ select 함수
int select(int maxfd, fd_set *readset, fd_set *writeset, fd_set * exceptset, const struct timeval *timeout)
- maxfd
- readset
- 수신된 데이터의 존재 여부에 관심있는 파일 디스크립터 정보를 모두 등록해서 그 변수의 주소값을 전달한다.
- writeset
- fd_set 형 변수에 "블록킹 없는 데이터 전송의 가능 여부"에 관심 있는 파일 디스크립터 정도를 모두 등록해서 그 변수의 주소 값을 전달한다.
- exceptset
- "예외 상황의 발생 여부 " 에 관심있는 파일 디스크립터 정보를 모두 등록해서 그 변수의 주소 값을 전달한다.
- timeout
- select 함수 호출 이후에 무한정 블록킹 상태에 빠지지 않고록 타임 아웃 설정을 위한 주소값 전달
- 반환값 : 오류 발생시 -1 반환 / 타임 아웃에 의한 반환시에는 0이 반환
"파일 디스크립터 관찰 (검사 ) 범위는 어떻게 지정하는가?"
- select 함수는 관찰의 대상이 되는 파일 디스크립터의 수를 첫번째 인자로 요구
- 파일디스크립터의 값은 생성될때 마다 1씩 증가하기 때문에 가장 큰 파일의 디스크립터의 값에 1을 더해서 인자로 전달하면 된다.
"select 함수의 타임 아웃 시간은?"
+select 함수 호출 이후의 결과 확인
- 0이 아닌 양수가 반환되면 그 수만큼 파일 디스크립터에 변화가 발생했음을 의미.
- 호출 전과 동일하게 1로 남아있는 변수는 "변화 없음" 이 아니라 남아 있는 위치의 파일 디스크립터에서 변화가 발생하였다고 판단할 수 있다.