32
Chapter 09. 소소 소소소 소소 (I)

Chapter 09. 소켓 입출력 모델 (I)

  • Upload
    belden

  • View
    45

  • Download
    0

Embed Size (px)

DESCRIPTION

Chapter 09. 소켓 입출력 모델 (I). 학습 목표. 블로킹과 넌블로킹 소켓 모드의 장단점을 이해한다 . Select 소켓 입출력 모델을 이해하고 활용한다 . WSAAsyncSelect 소켓 입출력 모델을 이해하고 활용한다 . WSAEventSelect 소켓 입출력 모델을 이해하고 활용한다. Blocking socket. Host A : Receive //step 1 Char readbuffer[4096]; Int ret; //step 2 - PowerPoint PPT Presentation

Citation preview

Page 1: Chapter  09. 소켓 입출력 모델 (I)

Chapter 09.

소켓 입출력 모델 (I)

Page 2: Chapter  09. 소켓 입출력 모델 (I)

- 2 -

학습 목표

• 블로킹과 넌블로킹 소켓 모드의 장단점을 이해한다 .• Select 소켓 입출력 모델을 이해하고 활용한다 .• WSAAsyncSelect 소켓 입출력 모델을 이해하고

활용한다 .• WSAEventSelect 소켓 입출력 모델을 이해하고

활용한다 .

Page 3: Chapter  09. 소켓 입출력 모델 (I)

- 3 -

Blocking socket

• Host A : Receive• //step 1• Char readbuffer[4096];• Int ret;• //step 2• Ret=recv(clientSocket, readBuffer, sizeof(readBuffer),0);• //step 3• readBuffer[ret] = 0;

• Host B : Send• Send(clientSocket,sendBuffer,strlen(sendBuffer),0);

• Connet, accept 등의 함수도 모두 완료될때 까지 멈춤• Send 함수 : 소켓버퍼에 데이터를 넣어주고 리턴

Page 4: Chapter  09. 소켓 입출력 모델 (I)

- 4 -

소켓 모드 (1/4)

• 소켓 모드 (socket mode)– 소켓 함수 호출시 동작 방식에 따라 블로킹 (blocking) 과

넌블로킹 (nonblocking) 소켓으로 구분

• 블로킹 소켓– 소켓 함수 호출 시 조건이 만족되지 않으면 함수는

리턴하지 않고 해당 스레드는 대기 상태 (wait state) 가 됨

소켓 함수 리턴 조건accept() 클라이언트가 접속했을 때send(), sendto() 송신 버퍼에 데이터를 모두 복사했을 때recv(), recvfrom() 수신 버퍼에 도착한 데이터가 있을 때

Page 5: Chapter  09. 소켓 입출력 모델 (I)

- 5 -

소켓 모드 (2/4)

• 넌블로킹 소켓– 소켓 함수 호출시 조건이 만족되지 않더라도 함수가 리턴하므로 해당

스레드는 계속 진행 가능– 어떤 작업을 요청 했을 때 바로 성공과 실패를 알려줌– socket() 함수는 기본적으로 블로킹 소켓을 생성하므로 ioctlsocket() 함수를

호출하여 넌블로킹 소켓으로 전환

// 블로킹 소켓 생성SOCKET listen_sock = socket(AF_INET, SOCK_STREAM, 0);if(listen_sock == INVALID_SOCKET) err_quit("socket()");

// 넌블로킹 소켓으로 전환u_long on = 1;retval = ioctlsocket(listen_sock, FIONBIO, &on);if(retval == SOCKET_ERROR) err_quit("ioctlsocket()");

Page 6: Chapter  09. 소켓 입출력 모델 (I)

- 6 -

소켓 모드 (3/4)

• 넌블로킹 소켓과 소켓 함수– 넌블로킹 소켓에 대해 소켓 함수를 호출했을 때 조건이

만족되지 않아 작업을 완료할 수 없으면 소켓 함수는 오류를 리턴

– WSAGetLastError() 함수를 호출하여 오류 코드를 확인– (10038: 소켓연산 오류 )– 대개 오류 코드는 WSAEWOULDBLOCK 이 되며 , 이는

조건이 만족되지 않음을 나타내므로 나중에 다시 소켓 함수를 호출해야 함

Page 7: Chapter  09. 소켓 입출력 모델 (I)

- 7 -

소켓 모드 (4/4)

• 넌블로킹 소켓의 특징장점 • 소켓 함수 호출 시 블록되지 않으므로 다른 작업 진행 가능

• 멀티스레드를 사용하지 않고도 여러 개의 소켓 입출력 처리 가능

단점 • 소켓 함수를 호출할 때마다 WSAEWOULDBLOCK 등 오류 코드를 확인하고 , 다시 해당 함수를 호출해야 하므로 프로그램 구조가 복잡해짐• 블로킹 소켓을 사용한 경우보다 CPU 사용률이 높음

Page 8: Chapter  09. 소켓 입출력 모델 (I)

- 8 -

서버 작성 모델

• 반복 서버– 접속한 여러 클라이언트를 하나씩 차례대로 처리

• 병행 서버– 접속한 여러 클라이언트를 병렬적으로 처리

장점 하나의 스레드로 클라이언트를 처리하므로 시스템 자원 소모가 적음

단점 서버와 클라이언트의 통신 시간이 길어지면 다른 클라이언트의 대기 시간이 길어짐

장점 서버와 클라이언트의 통신 시간이 길어지더라도 다른 클라이언트의 통신에 영향을 주지 않음

단점 멀티프로세스 또는 멀티스레드를 이용하여 구현하므로 시스템 자원 소모가 큼

Page 9: Chapter  09. 소켓 입출력 모델 (I)

- 9 -

이상적인 소켓 입출력 모델

• 이상적인 서버의 특징– 모든 클라이언트 접속이 성공– 서버는 각 클라이언트의 서비스 요청에 최대한 빠르게

반응하며 , 고속으로 데이터를 전송– 시스템 자원 사용량을 최소화

• 이상적인 소켓 입출력 모델– 소켓 함수 호출 시 블로킹 최소화– 입출력 작업을 다른 작업과 병행– 스레드 개수를 최소화– 유저 모드와 커널 모드 전환 횟수와 데이터 복사를 최소화

Page 10: Chapter  09. 소켓 입출력 모델 (I)

- 10 -

윈도우의 소켓 입출력 모델

• 운영체제별 소켓 입출력 모델 지원

소켓 입출력 모델지원 운영체제

윈도우 CE윈도우 ( 클라이언트 버

전 )윈도우 ( 서버 버전 )

Select CE 1.0 이상 윈도우 95 이상 윈도우 NT 이상

WSAAsyncSelect x 윈도우 95 이상 윈도우 NT 이상

WSAEventSelect CE .NET 4.0 이상 윈도우 95 이상 윈도우 NT 3.51 이상

Overlapped CE .NET 4.0 이상 윈도우 95 이상 윈도우 NT 3.51 이상

Completion Port

x 윈도우 NT 3.5 이상 ( 윈도우 95/98/Me 제외 )

Page 11: Chapter  09. 소켓 입출력 모델 (I)

- 11 -

Select 모델 (1/6)

• Select 모델– select() 함수가 핵심적인 역할을 함 – 소켓 모드 ( 블로킹 , 넌블로킹 ) 에 관계없이 여러 개의

소켓을 하나의 스레드로 처리 가능

• 핵심 원리– 소켓 함수를 호출해야 할 시점을 알려줌으로써 함수 호출

시 항상 성공하도록 함• 블로킹 소켓 : 소켓 함수 호출 시 조건이 만족되지 않아 블로킹

되는 상황을 방지• 넌블로킹 소켓 : 소켓 함수 호출 시 조건이 만족되지 않아 다시

호출해야 하는 상황을 방지

Page 12: Chapter  09. 소켓 입출력 모델 (I)

- 12 -

Select 모델 (2/6)

• 동작 원리읽기 셋 쓰기 셋 예외 셋

소켓

읽기 셋 쓰기 셋 예외 셋

소켓

Recv() send()

Page 13: Chapter  09. 소켓 입출력 모델 (I)

- 13 -

Select 모델 (3/6)

• 소켓 셋 ( 각각 읽기 , 쓰기 , 예외 셋 )

함수 호출 시점

클라이언트가 접속했으므로 accept() 함수를 호출할 수 있다 . 데이터를 받았으므로 recv(), recvfrom() 등의 함수를 호출할 수 있다.연결이 종료되었으므로 recv(), recvfrom() 등의 함수를 호출할 수 있 다 .이때 리턴값은 0 또는 SOCKET_ERROR 가 된다 .

함수 호출 시점송신 버퍼가 충분하므로 send(), sendto() 등의 함수를 호출하여 데이터를 보낼 수 있다 .

함수 호출 결과 넌블로킹 소켓을 사용한 connect() 함수 호출이 성공하였다 .

함수 호출 시점 OOB(Out-Of-Band) 데이터가 도착했으므로 recv(), recvfrom() 등의 함수를 호출하여 OOB 데이터를 받을 수 있다 .

함수 호출 결과 넌블로킹 소켓을 사용한 connect() 함수 호출이 실패하였다 .

Page 14: Chapter  09. 소켓 입출력 모델 (I)

- 14 -

Select 모델 (4/6)

• select() 함수int select ( int nfds, fd_set* readfds, fd_set* writefds, fd_set* exceptfds, const struct timeval* timeout) ; 성공 : 조건을 만족하는 소켓의 개수 또는 0( 타임아웃 ), 실패 : SOCKET_ERROR

Page 15: Chapter  09. 소켓 입출력 모델 (I)

- 15 -

Select 모델 (5/6)

• select() 함수를 이용한 소켓 입출력 절차① 소켓 셋을 비운다 (초기화 ).② 소켓 셋에 소켓을 넣는다 . 셋에 넣을 수 있는 소켓의

최대 개수는 FD_SETSIZE(=64) 로 정의되어 있다 .③ select() 함수를 호출한다 . select() 함수는 블로킹

함수로 동작하므로 조건이 만족되는 소켓이 있을 때까지 리턴하지 않는다 .④ select() 함수가 리턴한 후 소켓 셋에 존재하는 모든

소켓에 대해 적절한 소켓 함수를 호출하여 처리한다 .⑤ ①~④를 반복한다 .

Page 16: Chapter  09. 소켓 입출력 모델 (I)

- 16 -

Select 모델 (6/6)

• 소켓 셋을 다루기 위한 매크로 함수매크로 함수 역할

FD_CLR(SOCKET s, fd_set *set) 셋에서 소켓 s 를 제거

FD_ISSET(SOCKET s, fd_set *set) 소켓 s 가 셋에 들어 있으면 0 이 아닌 값을 리턴 . 그렇지 않으면 0 을 리턴

FD_SET(SOCKET s, fd_set *set) 셋에 소켓 s 를 넣음

FD_ZERO(fd_set *set) 셋을 비움

Page 17: Chapter  09. 소켓 입출력 모델 (I)

- 17 -

WSAAsyncSelect 모델 (1/6)

• WSAAsyncSelect 모델– WSAAsyncSelect() 함수가 핵심적인 역할을 함– 윈도우 메시지 형태로 소켓과 관련된 네트워크 이벤트를

처리 멀티스레드를 사용하지 않고도 여러 개의 소켓을 처리 가능

Page 18: Chapter  09. 소켓 입출력 모델 (I)

- 18 -

WSAAsyncSelect 모델 (2/6)

• 동작 원리

메시지 큐

소켓 관련 메시지

Page 19: Chapter  09. 소켓 입출력 모델 (I)

- 19 -

WSAAsyncSelect 모델 (3/6)

• WSAAsyncSelect 모델을 이용한 소켓 입출력 절차① WSAAsyncSelect() 함수를 이용하여 소켓을 위한 윈도우 메시지와 처리할 네트워크 이벤트를 등록한다 . 예를 들면 , 소켓을 통해 데이터를 보내거나 받을 수 있는 상황이 되면 특정 윈도우 메시지로 알려달라는 내용을 등록한다 .② 등록한 네트워크 이벤트가 발생하면 윈도우 메시지가 발생하고 윈도우 프로시저가 호출된다 .③ 윈도우 프로시저에서는 받은 메시지 종류에 따라 적절한

소켓 함수를 호출하여 처리한다 .

Page 20: Chapter  09. 소켓 입출력 모델 (I)

- 20 -

WSAAsyncSelect 모델 (4/6)

• WSAAsyncSelect() 함수

• 사용 예

int WSAAsyncSelect ( SOCKET s, HWND hWnd, unsigned int wMsg, long lEvent) ; 성공 : 0, 실패 : SOCKET_ERROR

#define WM_SOCKET (WM_USER+1) // 사용자 정의 윈도우 메시지...WSAAsyncSelect(s, hWnd, WM_SOCKET, FD_READ|FD_WRITE);

Page 21: Chapter  09. 소켓 입출력 모델 (I)

- 21 -

WSAAsyncSelect 모델 (5/6)

• 네트워크 이벤트 상수값

네트워크 이벤트 의미

FD_ACCEPT 클라이언트가 접속하면 윈도우 메시지를 발생시킨다 .

FD_READ 데이터 수신이 가능하면 윈도우 메시지를 발생시킨다 .

FD_WRITE 데이터 송신이 가능하면 윈도우 메시지를 발생시킨다 .

FD_CLOSE 상대가 접속을 종료하면 윈도우 메시지를 발생시킨다 .

FD_CONNECT

접속이 완료되면 윈도우 메시지를 발생시킨다 .

FD_OOB OOB 데이터가 도착하면 윈도우 메시지를 발생시킨다 .

Page 22: Chapter  09. 소켓 입출력 모델 (I)

- 22 -

WSAAsyncSelect 모델 (6/6)

• 윈도우 프로시저

– hwnd• 메시지가 발생한 윈도우

– msg• WSAAsyncSelect() 함수 호출시 등록한 사용자 정의 메시지

– wParam• 네트워크 이벤트가 발생한 소켓

– lParam• 하위 16 비트는 발생한 네트워크 이벤트 , 상위 16 비트는 오류 코드

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam){ ....}

Page 23: Chapter  09. 소켓 입출력 모델 (I)

- 23 -

WSAEventSelect 모델 (1/10)

• WSAEventSelect 모델– WSAEventSelect() 함수가 핵심적인 역할을 함– 이벤트 객체를 통해 네트워크 이벤트를 감지 각 소켓에

대해 이벤트 객체를 생성하고 , 이 이벤트 객체를 관찰함으로써 멀티스레드를 사용하지 않고도 여러 개의 소켓을 처리 가능

Page 24: Chapter  09. 소켓 입출력 모델 (I)

- 24 -

WSAEventSelect 모델 (2/10)

• 동작 원리

소켓

이벤트 객체

네트워크 이벤트

소켓

네트워크 이벤트 발생

이벤트 객체

Page 25: Chapter  09. 소켓 입출력 모델 (I)

- 25 -

WSAEventSelect 모델 (3/10)

• 필수 기능– 이벤트 객체 생성과 제거 : WSACreateEvent(), WSACloseE

vent()– 소켓과 이벤트 객체 선택 : WSAEventSelect()– 이벤트 객체의 신호 상태 감지하기 : WSAWaitForMultipleE

vents()– 구체적인 네트워크 이벤트 알아내기 : WSAEnumNetworkE

vents()

Page 26: Chapter  09. 소켓 입출력 모델 (I)

- 26 -

WSAEventSelect 모델 (4/10)

• WSAEventSelect 모델을 이용한 소켓 입출력 절차① 소켓을 생성할 때마다 WSACreateEvent() 함수를 이용하여

이벤트 객체를 생성한다 .② WSAEventSelect() 함수를 이용하여 소켓과 이벤트 객체를 짝지음과 동시에 , 처리할 네트워크 이벤트를 등록한다 . 예를 들면 , 소켓을 통해 데이터를 보내거나 받을 수 있는 상황이 되면 이벤트 객체를 신호 상태로 변경하라는 내용을 등록한다 .

③ WSAWaitForMultipleEvents() 함수를 호출하여 이벤트 객체가 신호 상태가 되기를 기다린다 . 등록한 네트워크 이벤트가 발생하면 해당 소켓과 연관된 이벤트 객체가 신호 상태가 된다 .

④ WSAEnumNetworkEvents() 함수를 호출하여 발생한 네트워크 이벤트를 알아내고 , 적절한 소켓 함수를 호출하여 처리한다 .

Page 27: Chapter  09. 소켓 입출력 모델 (I)

- 27 -

WSAEventSelect 모델 (5/10)

• 이벤트 객체 생성과 제거WSAEVENT WSACreateEvent ( ) ; 성공 : 이벤트 객체 핸들 , 실패 : WSA_INVALID_EVENT

BOOL WSACloseEvent (WSAEVENT hEvent) ; 성공 : TRUE, 실패 : FALSE

Page 28: Chapter  09. 소켓 입출력 모델 (I)

- 28 -

WSAEventSelect 모델 (6/10)

• 소켓과 이벤트 객체 선택int WSAEventSelect ( SOCKET s, WSAEVENT hEventObject, long lNetworkEvents) ; 성공 : 0, 실패 : SOCKET_ERROR

Page 29: Chapter  09. 소켓 입출력 모델 (I)

- 29 -

WSAEventSelect 모델 (7/10)

• 이벤트 객체의 신호 상태 감지하기

DWORD WSAWaitForMultipleEvents ( DWORD cEvents, const WSAEVENT* lphEvents, BOOL fWaitAll, DWORD dwTimeout, BOOL fAlertable) ;성공 : WSA_WAIT_EVENT_0 ~ WSA_WAIT_EVENT_0 + cEvents-1 또는 WSA_WAIT_TIMEOUT, 실패 : WSA_WAIT_FAILED

Page 30: Chapter  09. 소켓 입출력 모델 (I)

- 30 -

WSAEventSelect 모델 (8/10)

• 구체적인 네트워크 이벤트 알아내기int WSAEnumNetworkEvents ( SOCKET s, WSAEVENT hEventObject, LPWSANETWORKEVENTS lpNetworkEvents) ; 성공 : 0, 실패 : SOCKET_ERROR

Page 31: Chapter  09. 소켓 입출력 모델 (I)

- 31 -

WSAEventSelect 모델 (9/10)

• 예제 코드SOCKET s;WSAEVENT hEvent;WSANETWORKEVENTS NetworkEvents;...WSAEnumNetworkEvents(s, hEvent, &NetworkEvents);

// FD_ACCEPT 이벤트 처리if(NetworkEvents.lNetworkEvents & FD_ACCEPT){ if(NetworkEvents.iErrorCode[FD_ACCEPT_BIT] != 0){ printf(" 오류 코드 = %d\n", NetworkEvents.iErrorCode[FD_ACCEPT_BIT]); } else{ // accept() 함수 호출 }}

Page 32: Chapter  09. 소켓 입출력 모델 (I)

- 32 -

WSAEventSelect 모델 (10/10)

• 예제 코드 (cont’d)

// FD_READ 이벤트 처리if(NetworkEvents.lNetworkEvents & FD_READ){ if(NetworkEvents.iErrorCode[FD_READ_BIT] != 0){ printf(" 오류 코드 = %d\n", NetworkEvents.iErrorCode[FD_READ_BIT]); } else{ // read() 함수 호출 }}...