select 함수의 이해와 서버의 구현
- select 함수의 기능과 호출순서
- 한 곳에 여러 개의 file descriptor를 모아놓고 동시에 이벤트를 관찰 가능
- 수신한 데이터의 존재 여부
- blocking없는 데이터 전송의 가능 여부
- 예외상황의 발생 여부
- 호출 순서
- file descriptor의 설정, 검사의 범위 지정, 타임아웃의 설정
- select 함수의 호출
- 호출 결과 확인
- file descriptor의 설정
- 관찰할 여러 개의 file descriptor를 관찰항목(수신, 전송, 예외)에 따라서 구분하여 모음
- fd_set형 변수를 사용하여 file descriptor를 세 묶음으로 모음

- 비트 단위로 이뤄진 배열(file descriptor 0, 1, ...)에서 1일 경우 file descriptor가 관찰의 대상임
- fd_set형 변수에 값을 등록하거나 변경하는 등의 작업은 매크로 함수들의 도움으로 이뤄짐
void FD_CLR(int fd, fd_set *fdset); // fdset 주소의 변수에서 fd로 전달된 file descriptor 정보를 삭제
void FD_SET(int fd, fd_set *fdset); // fdset 주소의 변수에 fd로 전달된 file descriptor 정보를 등록
void FD_ZERO(fd_set *fdset); // 인자로 전달된 주소의 fd_set형 변수의 모든 비트를 0으로 초기화
void FD_ISSET(int fd, fd_set *fdset); // fdset 주소의 변수에 fd로 전달된 file descriptor 정보가 있으면 양수 반환 (함수의 호출 결과를 확인)

- 검사(관찰)의 범위지정과 타임아웃의 설정
#include <sys/select.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
int select(int mafdl, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
→ 성공 시 0 이상, 실패 시 -1 반환
- mafdl: 검사 대상이 되는 file descriptor 수
- readfds: 수신된 데이터의 존재여부에 관심있는 file descriptor 정보를 모두 등록해 변수의 주소값 전달
- writefds: blocking 없는 데이터 전송이 가능한지에 관심있는 file descriptor를 등록해 변수의 주소값 전달
- exceptfds: 예외 상황의 발생여부에 관심있는 file descriptor 정보를 등록해 변수의 주소값 전달
- timeout: select함수 호출 이후 무한정 blocking 상태에 빠지지 않도록 time-out 설정
- return: 오류 발생: -1; 타임 아웃에 의한 반환: 0; 관심대상으로 등록된 file descriptor에 관심에 관련된 변화 발생: 변화가 발생한 file descriptor의 수
- 검사의 범위지정: file descriptor은 생성될때마다 1씩 증가하므로 가장 큰 file descriptor 값에 1을 더해 관찰의 대상이 되는 file descriptor의 수 저장
- 타임아웃의 설정: select 함수의 경우 변화가 발생해야 반환값을 반환하므로 무한정 blocking 상태에 머물게 하지 않도록 타임아웃 지정 (NULL: 타임아웃 지정안함)
#include <sys/time.h>
struct timeval {
long tv_sec; // 초
long tv_usec; // 마이크로 초
};
- select 함수호출 이후의 결과 확인

- 관심 대상으로 지정된 file descriptor 중 변화가 발생한 file descriptor만이 그대로 1을 유지
- select 함수를 호출하는 예제
- select 함수 호출 후에는 구조체 timeval의 멤버 tv_sec, tv_usec의 값이 타임아웃이 발생하기까지 남아있던 시간으로 변하므로 select 함수 호출 전 timeval 구조체 변수의 초기화를 반복
- select 함수가 0보다 큰 값을 반환하여 변화를 보인 file descriptor가 stdin이 맞는지 확인하고 맞으면 표준입력으로부터 데이터를 읽어 출력


// 실행창

- 멀티플렉싱 서버의 구현



// 실행창

- 연결 요청에 필요한 서버 socket, 데이터 송수신을 위한 socket의 file descriptor를 reads 비트 배열에서 관심 대상으로 설정
- 클라이언트의 연결요청도 데이터의 전송을 통해 이뤄짐
- select 함수에서 1이상 반환했을때만 FD_ISSET함수 호출
- temps 비트 배열(file descriptor)을 통해 서버 socket와의 연결요청한 경우, 송수신을 위한 socket을 생성하고 select함수로 수신 데이터 여부를 확인하기 위해 reads 비트 배열에 file descriptor등록
- temps 비트 배열(file descriptor)을 통해 또는 수신한 데이터 확인하여 file descriptor로 수신한 데이터를 읽고 송신 (수신 데이터가 없을 경우 file descriptor 등록 해제)
- 상태변화 확인 -> 서버 socket에서 변화 여부 확인 -> 연결 요청 수락 -> fd_set 형 변수에 클라이언트와 연결된 socket의 file descriptor 정보 등록