블로그 이미지
래머
오늘도 열심히 개발하는 개발자입니다.

calendar

1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31

Notice

2014. 5. 2. 01:09 C/C++


소켓 입출력 모델 - 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, ...);




'C/C++' 카테고리의 다른 글

WSAEventSelect  (0) 2014.05.02
WSASend  (0) 2014.05.02
iocp주의점  (0) 2014.05.02
중첩된 io  (0) 2014.05.02
IOCP예제  (0) 2014.05.02
posted by 래머