Select 모델
- select모델의 개념
select 모델이란 select 함수를 주로 사용하는 I/O 기반 소켓 프로그래밍이다.
select 모델을 사용하면 소켓 모드(블로킹, 넌블로킹)에 관계없이 여러 소켓을 한 스레드로 처리할 수 있다.
-select모델의 특징
select 모델은 소켓 함수 호출이 성공할 시점을 미리 알 수 있다는 특징이 있다.
함수를 호출할 수 있는지에 대한 여부를 미리 확인하기 때문에 가능하다.
수신/송신 버퍼에 데이터가 비었는데/꽉 찼는데 read/write 하는 상황이 기존 소켓 프로그래밍에 있었다.
select모델은 이 상황을 미리 확인 하여 예방할 수 있다.
또한 Select 모델은 여러 소켓에 대해 함수 호출 시점(또는 호출 결과)을 알려주는 역할을 할 뿐 소켓 정보를 관리해주지는 않는다. 따라서 각 소켓에 필요한 정보(응용 프로그램 버퍼, 송/수신 바이트 정보 등)을 관리하는 기능은 응용 프로그램이 구현해야 한다.
-select 모델의 장점
- 블로킹의 경우
조건이 만족되지 않아서 블로킹 되는 상황을 예방 - 논 블로킹의 경우
조건이 만족되지 않아서 불필요한 반복 체크를 예방
-select 모델의 단점
- while()을 통해 반복해 주어야 한다.
- set에 한번에 등록할 수 있는 소켓의 개수가 매우 적다.(64개까지만 소켓의 등록가능하고 초과한다면 추가적인 set을 적용하고 관리 해줘야 한다.)
IOCP 모델
- IOCP모델의 개념
Input/Ouptput Completion Port의 약자다. 입력과 출력의 완료를 담당할 포트를 지정해서 처리하겠다는 의미다. 입력과 출력의 완료시점에서의 통지는 overlapped(중첩 입출력)에서 처리가 되므로, 이 기술은 윈도의 중첩 입출력 기술을 확장시킨 것으로 볼 수 있다.
(간단히 말하면 윈도우에서 제공하는 비동기 IO 라이브러리로 생각하면 될것이다.)
-IOCP모델 동작 순서
1. 쓰레드 폴(미리 쓰레드를 할당) 을 이용하여 생성한다.
2. 비동기 I/O 시작
동기 함수(Connect Close Accept Send)과 같은 역활을 하는 비동기 함수들을 실행해서 윈도우 I/O에 남긴다. 이 동작을 거친 뒤에는 프로그램의 흐름이 다시 호출한 쓰레드로 바로 돌아온다. (비동기)
3. 비동기 입출력 완료
비동기 입출력이 윈도우 I/O에서 종료되면 IOCP라는 Port(항구)에 Queue자료구조로 쌓이게 된다.
4. GetQueuedCompletionStatus
쓰레드 중에서 작업이 끝난, 그러니까 할 일이 없는 쓰레드에서 GetQueuedCompletionStatus를 호출하면 IOCP에서 완료된 내용을 꺼내 받을 수 있다.
-IOCP 작동코드 예시
while (true)
{
DWORD dwTransferred = 0;
OverlappedIOContext* context = nullptr;
ClientSession* asCompletionKey = nullptr; //키로 세션을 활용
int ret = GetQueuedCompletionStatus(
hComletionPort , &dwTransferred,
(PULONG_PTR)&asCompletionKey, (LPOVERLAPPED*)&context, GQCS_TIMEOUT );
DWORD errorCode = GetLastError();
//time out처리
if (ret == 0 && errorCode == WAIT_TIMEOUT)
continue;
//기타 에러 처리
...
//overlapped 구조체에 I/O 타입을 전달하는 방법
switch (context->mIoType)
{
//각 I/O에 대응하는 완료함수를 불러서 처리한다.
case IO_SEND:
completionOk = SendCompletion(asCompletionKey, context, dwTransferred);
break;
case IO_RECV:
completionOk = ReceiveCompletion(asCompletionKey, context, dwTransferred);
break;
}
}bool ReceiveCompletion(const ClientSession* client,
OverlappedIOContext* context,
DWORD dwTransferred)
{
/// echo back 처리 client->PostSend()사용.
bool result = true;
if( !client->PostSend( context->mBuffer , dwTransferred ) )
{
printf_s( "PostSend error: %d\n" , GetLastError() );
delete context;
return false;
}
delete context;
return client->PostRecv();
}
출처: https://ozt88.tistory.com/23 [공부 모음:티스토리]
-select모델을 사용하지 않고 IOCP를 사용하는 이유
가장 큰 이유는 select 모델의 경우 소켓의 양이 한정되어있는 것이 가장 크다. 64개가 한계치고 한계치를 넘기기가 매우 힘들기 때문에 굳이 대용량 정보가 왔다가야하는 서버의 경우 IOCP 모델을 사용한다.
'코딩 > 게임서버공부' 카테고리의 다른 글
[게임서버공부] 응용계층, DNS, HTTP (0) | 2024.06.20 |
---|---|
[서버공부] 전송계층의 이해 (0) | 2024.06.18 |
[CS]서브넷마스크, IP 주소의 종류, 라우터와 라우팅 (1) | 2024.05.30 |
[게임서버 3주차]IP,ARP,라우팅의 이해 (0) | 2024.05.28 |
[CS]동기와 비동기의 이해(블록과 논블록) (0) | 2024.05.24 |