입출력 다중화 기술은 유닉스 운영체제(:12) 시스템에서 하나 이상의 파일로 부터의 입력과 출력을 함께 관리하기 위해서 사용한다. 자세한 내용은 입출력:::다중화(:12)를 참고한다.
윈도는 BSD:::socket(:12)의 입출력 다중화 인터페이스인 select(:2)함수를 그대로 사용하고 있다.
int select(
__in int nfds,
__inout fd_set *readfds,
__inout fd_set *writefds,
__inout fd_set *exceptfds,
__in const struct timeval *timeout
);
몇 가지 다른 점은 nfds를 사용하지 않는 다는 점이다. 윈속에서 nfds는 BSD socket과의 호환을 위해서 남겨두었다. 이는 fd_set 구조체의 차이에 기인한다. BSD select의 fd_set과는 달리 윈속은 fd_set에 관리할 파일의 개수 정보를 저장하기 때문이다.
typedef struct fd_set {
u_int fd_count; // fd_array에 설정된 파일의 총 개수
SOCKET fd_array[FD_SETSIZE];
} fd_set;
파일 대응
윈도는 소켓과 파일을 다른 객체로 보기 때문에, select함수로 파일을 다룰 수는 없다. 리눅스는 표준입력과 소켓을 모두 select로 처리할 수 있기 때문에, 예컨데 콘솔 채팅 클라이언트도 단일 쓰레드 모델로 만들 수 있지만, 윈속 select로는 그렇게 할 수 없다. 어쩔 수 없이 멀티 쓰레드 프로그래밍 기술을 응용해야 한다.
지원 윈도 버전
windows 2000 Professional, windows 2000 Server 이상에서 지원한다.
리눅스 프로그램 보다는 구조가 단순하다. 이는 fd_set 구조체의 차이에 기인한다. 비트 배열이 아닌 소켓 지시자를 저장하는 SOCK 배열로, 배열에 저장된 소켓의 크기를 알려 줄 뿐더러, 배열을 (마치 링크드:::리스트(:12) 처럼)직접 관리해 주기 때문이다. 리눅스(:12)라면 프로그래머가 직접 해야 할 일을 윈속(:12)에서 대신 처리해 준다.
WSAEventSelect 구현
윈도의 이벤트 객체를 이용해서 네트워크 이벤트를 감지한다. 각 소켓에 대해서 이벤트 객체를 설정하고, 이 이벤트 객체를 관찰한다. 이벤트의 타입이 다를 뿐, 이벤트를 기다린 다는 점에서 기본 원리는 BSD select를 이용한 방식과 동일하다.
다음과 같은 흐름을 가진다.
WSACreateEvent(:4200)함수로 이벤트 객체를 생성한다.
WSAEventSelect(:4200)함수로 소켓과 이벤트를 짝 짓는다.
WSAWaitForMultipleEvents(:4100)함수로 이벤트를 기다린다.
이벤트가 발생하면, 이벤트의 종류를 확인해서 처리한다.
더 이상 사용하지 않는 이벤트는 WSACloseEvent(:4200)함수로 이벤트 객체를 제거한다.
WSAEventSelect 함수로 등록할 수 있는 소켓 이벤트는 다음과 같다.
WSAEventSelect 함수를 호출하면 자동으로 소켓을 비동기/비봉쇄 모드로 설정한다. 때문에 이를 감안해서 recv/recv 함수를 호출해야 한다. 예를 들어 FD_READ 이벤트를 받고 나서 read(:4200)을 호출 했을 때, WSAEWOULDBLOCK에러가 발생할 수도 있다는 의미다. 견고한 애플리케이션을 만들려면 이러한 예외 사항을 처리해 주어야 한다. 위의 프로그램은 WSAEWOULDBLOCK 처리는 포함하지 않고 있다.
WSAAsyncSelect 구현
비동기 이벤트 방식 중 가장 널리 사용되는 방법중의 하나다. WSAEventSelect와 비슷한 매커니즘을 가진다. 차이점이라면 WSAEventSelect는 이벤트 객체를 사용해서 입출력을 다루고, WSAAsyncSelect함수는 윈도우 메시지 형태로 네트워크 이벤트를 처리한다는 점이다.
WSAAsyncSelect를 이용한 데이터 처리 흐름이다. WSAEventSelect와 큰 차이가 없다.
소켓에서 관심있는 네트워크 이벤트와 메시지를 핸들할 윈도 핸들러를 함께 등록한다.
네트워크 이벤트가 발생하면, 윈도 메시지가 발생하고 윈도 프로시저가 호출된다. 이때 실행되는 윈도 프로시저의 이름은 WndProc이다.
Contents
입출력 다중화 모델
BSD select 입출력 다중화
파일 대응
지원 윈도 버전
예제
WSAEventSelect 구현
WSAAsyncSelect 구현
Recent Posts
Archive Posts
Tags