*동작원리
1.비동기 입출력 함수를 호출함으로써 운영체제에 입출력 작업을 요청한다.
2.해당 스레드는 곧바로 alertable wait 상태에 진입한다. 여기서 alertable wait 상태
란 비동기 입출력을 위한 특별한 대기 상태로, 비동기 입출력 함수를 호출한 스레드 이
상태에 있어야만 완료 루틴이 호출될수 있다. 스레드를 alertable wait 상태로 만드는
함수는 다양하다. 몇 가지 예를 들면 WaitForSingleObjectEx(),WaitForMulitipleOvjectsEx()
,SleepEx(),WSAWaitForMultipleEvent()등이 있다. 마지막 함수인 WSAWaitForMultipleEvents()
는 WSAEventSelect모델과 Overlapped모델(I)에서 다룸, 마지막 인자에 TRUE를 사용하면 해
당 스레드는 alertable wait상태가 된다.
3.비동기 입출력 작업이 완료되면 운영체제는 스레드의 APC큐에 결과를 저장한다.
여기서 APC큐(Asynchronous Procedure Call Queue)란 비동기 입출력 결과 저장을 위해
운영체제가 각 스레드마다 할당하는 메모리 영역이다.
4.비동기 입출력 함수를 호출한 스레드가 alertable wait 상태에 있으면 운영체제는APC
큐에 저장된 정보(완료 루틴의 주소)를 참조하여 완료 루틴을 호출한다. 완료 루틴
내부에서 는 데이터를 처리한 후 다시 alertable wait상태에 진입해야한다.
========================= 소켓 입출력 절차 ====================================
1.비동기 입출력을 지원하는 소켓을 생성한다.
2.비동기 입출력 함수를 호출한다. 이때 완료 루틴의 시작 주소를 함수 인자로 전달
한다. 비동기 입출력 작업이 곧바로 완료되지 않으면, 소켓 함수는 오류를 리턴하고
오류코드는 WSA_IO_PENDING으로 설정된다.
3.비동기 입출력 함수를 호출한 스레드를 alertable wait상태로 만든다. 앞에서 소개한
WaitForSingleObjectEx(), WaitForMultipleObjectEx(),SleepEx(),WsaWaitForMultipleEvents()
등의 함수 중에서 적절한 것을 선택하여 사용하면 된다.
4.비동기 입출력 작업이 완료되면 운영체제는 완료 루틴을 호출한다. 완료 루틴에서는
비동기 입출력 결과를 확인하고 데이터를 처리한다.
5. 완료 루틴 호출이 모두 끝나면 스레드는 alertable wait 상태에서 빠져나온다
6.새로운 소켓을 생성하면 1~5 그렇지 않으면 2~5를 반복한다.
========================= 스레드를 alertable wait 상태로 바꾸는 함수)
void CALLBACK CompletionRoutine(
DWORD dwError,
DWORD cbTransferred,
LPWSAOVERLAPPED lpOverlapped,
DWORD dwFlags);
dwError:비동기 입출력 결과를 나타낸다. 오류가 발생하면 이 값은 0이 아닌 값이된다.
cbTransferred:전송바이트 수를 나타낸다. 통신 상대가 접속을 종료하면 이 값은 0이된다.
lpOverlapped:비동기 입출력 함수 호출 시 넘겨준 WSAOVERLAPPED구조체의 주소값이 이
인자를 통해 다시 애플리케이션에 넘어온다. Overlapped모델(II)에서는 이벤트 객체
를 사용하지 않으므로 WSAOVERLAPPED 구조체를 완료 루틴 내부에서 직접 사용할 일은 거의 없다.
dwFlags:항상 0이므로 적어도 현재까지는 사용하지 않음
'C/C++' 카테고리의 다른 글
WSASend (0) | 2014.05.02 |
---|---|
소켓 입출력 모델 - Overlapped 모델 (0) | 2014.05.02 |
iocp주의점 (0) | 2014.05.02 |
IOCP예제 (0) | 2014.05.02 |
[본문스크랩] 파일의 CRC32 값 구하기 프로그래밍팁 (0) | 2014.05.02 |