Overlapped IO 란? -------------------------------------------------------------------------------------------------------
앞서 비동기화된 알람방식에 대해서 알아봤다면 이번에는 IO작업 자체의 비동기 방식에 대해서 알아볼 차례이다.
비동기 방식의 소켓전송이란 여러개의 소켓이 동시에 IO작업을 처리하는 것을 의미한다.
여러개의 쓰레드나 비동기 시스템을 통해서 여러개의 파일을 동시에 읽어들이는 것과 동일하다고 보면 된다.
시스템 프로그래밍과 어느정도 겹치는 부분이 있지만. 비동기 방식은 다음의 함수들이 필요하다.
1. 비동기 옵션의 소켓
2. 비동기로 송수신이 가능한 함수
1. 비동기 옵션의 소켓을 생성하는 함수.
SOCKET WSASocket(
_In_ int af, -> 프로토콜 체계 정보 전달.
_In_ int type, -> 소켓의 데이터 전송방식에 대한 정보 전달.
_In_ int protocol, -> 두 소켓 사이에 사용되는 프로토콜 정보 전달.
_In_ LPWSAPROTOCOL_INFO lpProtocolInfo, -> 생성되는 소켓의 특성 정보를 담고 있는 WSAPROTOCOL_INFO 구조체 변수의 주소 값 전달,
필요 업는 경우 NULL 전달.
_In_ GROUP g, -> 함수의 확장을 위해서 예약되어 있는 매개변수, 따라서 0 전달.
_In_ DWORD dwFlags -> 소켓의 속성정보 전달.
); 성공시 소켓의 핸들, 실패시 INVALID_SOCKET 반환.
2. 비동기로 송수신이 가능한 함수
IOCP란? -------------------------------------------------------------------------------------------------------
소켓통신이란 일반적으로 정해진 통신규약이고 운영체제도 그에 따르고 있다.
즉 윈도우와 리눅스방식이 현재까지 크게 다르지 않았던 이유는 운영체제의 특징적인 부분보다는 기본적인 규격을 지키는 방식을 사용했기 때문이다.
하지만 운영체제란 분명히 그에 맞는 특색이 있고 특색에 따라서 더 많은 것을 지원해 줄수 있을 것이다.
IOCP란 윈도우에서 지원해주는 비동기 통신방식을 의미한다. 설명을 하자면 다음과 같은 방식을 가지고 있다.
1. 비동기방식을 사용하는 소켓을 다수 생성한다.
2. 쓰레드를 통해서 소켓에 발생하는 이벤트를 병렬 관찰 한다.
3. 각각의 소켓은 비동기로 입출력을 실행한다.
종합 -> 즉 다수의 소켓이 다수의 쓰레드에 의해서 관리 받으며 비동기로 데이터 송수신을 하게 되는 구조를 의미한다.
* 비동기 모드의 서버소켓 구성하기
accept함수는 현재까지 동기화구조로 구성되어 있었다. 하지만 이 서버 소켓도 비동기화 방식으로 구현이 가능하다.
비동기 소켓의 생성 방법은 WSASocket으로 생성을 하면 하지만. ioctlsocket함수를 통해서 실제 비동기 방식의 옵션을 켜줘야 한다.
int mode = 1;
hLisnSock = WSASocket(함수 호출)
ioctlsocket(hLisnSock, FIONBIO, &mode)
의미를 보면 다음과 같다.
"서버소켓 hLisnSock의 FIONBIO(입출력모드)를 mode의 주소에 저장된 값의 형태로 변경한다."
"mode의 값이 0이 아닌 수라면 두번째 인자값의 기능을 on시킨다고 보면 된다."
* IOCP방식으로 소켓을 관리할 포트 생성하기
포트가 무엇이냐면 소켓이 10개 있다고 했을때 윈도우 차원에서 이 소켓을 관리해줄 오브젝트를 생성하는 것을 의미한다.
다음의 함수를 통해서 생성이 가능하다.
HANDLE WINAPI CreateIoCompletionPort(
_In_ HANDLE FileHandle, -> CP 오브젝트 생성시에는 INVALID_HANDLE_VALUE 전달
_In_opt_ HANDLE ExistingCompletionPort, -> CP 오브젝트 생성시에는 NULL 전달.
_In_ ULONG_PTR CompletionKey, -> CP 오브젝트 생성시에는 0 전달.
_In_ DWORD NumberOfConcurrentThreads -> CP오브젝트에 할당되어 완료된 IO를 처리할 쓰레드의 수를 전달한다.
); 성공시 CP오브젝트 핸들 반환 실패시 NULL 반환
생성시라고 적혀있는 이유는 이 함수가 CP오브젝트와 소켓을 연결하는 역할로도 사용되기 때문이다.
HANDLE WINAPI CreateIoCompletionPort(
_In_ HANDLE FileHandle, -> CP 오브젝트에 연결할 소켓의 핸들 전달.
_In_opt_ HANDLE ExistingCompletionPort, -> 소켓과 연결할 CP 오브젝트 전달.
_In_ ULONG_PTR CompletionKey, -> 완료된 IO관련 정보의 전달을 위한 매개변수,
_In_ DWORD NumberOfConcurrentThreads -> 어떠한 값이 전달되건, 이 함수의 두번째 매개변수가 NULL이 아니라면 무시된다.
); 성공시 CP오브젝트의 핸들, 실패시 NULL 반환
세번째 정보는 IO는 CP 오브젝트와 그와 연결된 함수를 체크하는 항목과도 관련되어 있으니 확인해보도록 하자.
BOOL WINAPI GetQueuedCompletionStatus(
_In_ HANDLE CompletionPort, -> 완료된 IO정보가 등록되어있는 CP오브젝트의 핸들 전달.
_Out_ LPDWORD lpNumberOfBytes, -> 입출력 과정에서 송수된 데이터의 크기 정보를 저장할 변수의 주소 값 전달.
_Out_ PULONG_PTR lpCompletionKey,
-> CreateIoCompletionPort변수에서 연결 방식으로 사용할때의 세번째 변수의 값을 반환받을 변수의 주소 값 전달.
_Out_ LPOVERLAPPED *lpOverlapped,
-> WSASend, WSARecv 함수 호출시 전달하는 OVERLAPPED 구조체 변수의 주소 값이 저장된 변수의 주소 값 전달.
_In_ DWORD dwMilliseconds
-> 타임 아웃 전달, 여기서 지정한 시간이 완료되면 FALSE를 반환하면서 함수를 빠져나간다.
INFINITE를 전달하면 완료된 IO가 CP오브젝트에 등록될 때까지 블로킹 상태에 있게 된다.
);
1. CreateIoCompletionPort함수로 포트를 생성하고 그안에 소켓을 연결한다.
2. CreateIoCompletionPort함수로 생성된 포트로 관리하고 싶은 소켓을 연결한다.
3. GetQueuedCompletionStatus함수로 소켓들중 상태에 변화가 있는 소켓을 반환받아서 그와 관련된 작업을 한다.
'게임개발공부 > 서버 공부' 카테고리의 다른 글
열혈강의 TCP/IP <비동기 송수신 방식> (0) | 2013.12.07 |
---|---|
열혈강의 TCP/IP <멀티 플렉싱용 함수> (0) | 2013.12.05 |
열혈강의 TCP/IP <멀티 프로세스와 멀티 플렉싱> (0) | 2013.12.01 |
열혈강의 TCP/IP <소켓의 옵션과 입출력 버퍼 소켓의 옵션 재설정> (0) | 2013.12.01 |
열혈강의 TCP/IP <인터넷 도메인이름과 인터넷 주소> (0) | 2013.11.30 |