소켓 입출력 모델 - Overlapped 모델
[동기 입출력(synchronous I/O)]
애플리캐이션은 입출력 함수를 호출한 후 입출력 작업이 끝날때 까지 대기하다 끝나면 입출력 결과를 처리하거나 다른 작업을 할수 있다
Select, WSAAsyncSelect, WSAEventSelect 소켓 모델은 모두 동기 입출력 방식으로 동작. 단 입출력 함수를 안전하게 호출할수
있는 시점을 운영체제가 알려주기 때문에 단순한 동기 입출력 방식보다 편하게 여러 소켓을 처리할수 있다
- 이와 같이 운영체제가 함수 호출 시점을 알려주는 개념을 비동기 통지라고 부른다.
[비동기 입출력(asynchronous I/O = overlapped I/O)]
어플리캐이션은 입출력 함수를 호출한 후 입출력 작업의 완료 여부와 무관하게 다른 작업을 할 수 있다
입출력 작업이 끝나면 운영체제는 작업 완료를 어플리캐이션에게 알려준다
비동기 입출력 방식에서는 입출력 완료를 운영체제에서 알려주는 개념이 반드시 필요하므로 비동기 통지도 사용한다고 볼수 있다
- Overlapped, Completion Port(IOCP)는 비동기 입출력과 비동기 통지를 결합한 형태라 할수 있다
[Overlapeed 모델]
* 사용 절차
1. 비동기 입출력을 지원하는 소켓을 생성
- socket() 함수로 생성한 소켓은 기본적으로 비동기 입출력을 지원한다
2. 비동기 입출력을 지원하는 소켓 함수 호출(총 13개의 함수)
- AcceptEx(), ConnectEx(), DisconnectEx(), TransmitFile(), TransmitPackets(), WSAIoctl(), WSASPIoctl(),
WSAProviderConfigChange(), WSARecvMsg(), WSARecv(), WSARecvFrom(), WSASend(), WSASendTo()
3. 운영체제는 소켓 입출력 작업 완료를 애플리캐이션에게 알려주고(=비동기 통지), 애플리케이션은 결과를 처리
* 비동기 통지 방식에 따른 Overlapped 모델 분류
1. Overlapped 모델( I )
: 소켓 입출력 작업이 완료되면 운영체제는 애플리케이션이 등록한 이벤트 객체를 신호상태로 바꾼다
애플리케이션은 이벤트 객체를 관찰함으로써 작업 완료를 감지할수 있다
2. Overlaped 모델( II )
: 소켓 입출력 작업이 완료되면 운영체제는 애플리케이션이 등록한 함수를 자동으로 호출한다
일반적으로 운영체제가 호출하는 애플리케이션 함수를 콜백 함수(callback function) 라 부르는데.
특별히 Overlapped 모델에서는 완료 루틴(completion routine) 이라 칭한다
[WSASend(), WSARecv()]
int WSASend(
SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount,
LPDWORD lpNumberOfBytesSent,
DWORD dwFlags,
LPWSAOVERLAPPED lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoution
); 성공 : 0. 실패 : SOCKET_ERROR
int WSARecv(
SOCKET s, LPWSABUF lpBUffers, DWORD dwBufferCount,
LPDWORD lpNumberOfBytesRecvd,
LPDWORD lpFlags,
LPWSAOVERLAPPED lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
); 성공 : 0. 실패 : SOCKET_ERROR
s : 비동기 입출력을 할 소켓
lpBuffers : WSABUF 구조체 배열의 시작주소. 각각의 배열 원소(WSABUF 타입)는 버퍼의 시작 주소와 길이(바이트단위)를 담고 있다
dwBufferCount : WSABUF 구조체 배열의 원소개수
lpNumberOfBytesSent, lpNumberOfBytesRecvd
: DWORD 형 변수 주소값으로 함수 호출이 성공하면 이 변수에 보내거나 받은 바이트가 저장된다
dwFlags, lpFlags : send(), recv() 함수의 마지막 인자와 동일한 역활
lpOverlapped
: WSAOVERLAPPED 구조체 변수의 주소값
이 구조체는 비동기 입출력을 위한 정보를 운영체제에 전달하거나 운영체제가 비동기 입출력 결과를 애플리케이션에 전달할때 사용
WSAOVERLAPPED 구조체 변수중 처음 네 개는 운영체제가 내부적으로만 사용.
마지막 변수인 hEvent 는 이벤트 객체 핸들값으로 Overlapped 모델( I ) 에서만 사용한다.
입출력 작업이 완료되면 hEvent 가 가리키는 이벤트 객체는 신호상태가 된다.
lpCompletionRoutine : 입출력 작업이 완료되면 운영체제가 자동으로 호출할 완료루틴(콜백함수)의 주소값
* WSASend(), WSARecv() 함수 특징
송신측에서 WSABUF 구조체를 사용하면 여려개의 버퍼에 저장된 데이터를 모아서(Gather) 보낼 수 있다.
수신측에서도 역시 WSABUF 구조체를 사용하면 여러개의 버퍼에 흩어(Scatter)저장할 수 있다.
buf[128];
buf[256];
WSABUF wsabuf[2];
wsabuf[0].buf = buf1;
wsabuf[0].len = 128;
wsabuf[1].buf = buf2;
wsabuf[1].len = 256;
// 송신측 코드
WSASend(sock, wsabuf, 2, ...);
// 수신측 코드
WSARecv(sock, wsabuf, 2, ...);