Server/C++

Select 모델

Juzdalua 2024. 8. 7. 02:24

Select 함수는 동기 함수이다.

논블로킹 소켓을 사용했을 때, 수신하는 측에서 준비가 되지 않았는데 함수를 호출하면 WSAEWOULDBLOCK 에러를 리턴한다. 

수신측에서 무한루프를 돌며 대기하고 송신측에서는 다시 재송신을 하게 되는데 이런 상황에서 CPU 낭비가 발생된다.

논블로킹 소켓을 사용하되, 준비 되었을 때를 미리 파악하는게 Select 모델의 컨셉이다.

Select 함수가 핵심이 되는 모델이다.

// Select 모델은 q.empty()를 확인하는 것과 비슷하다.

queue<int> q;
if(q.empty() == false)
	q.pop();

 

클라이언트는 서버와 1:1 통신을 하기 때문에 IOCP까지 고급 스킬을 사용하지 않아도 될 경우가 있다. 간단한 모델을 사용하여 서버와 통신할 수 있다.

 

장점: 미리 체크하고 통신을 하기 때문에 CPU 낭비를 줄일 수 있다.

단점: FD_SETSIZE가 64로 크기가 작기 때문에 동시 접속이 많을 경우 코드의 반복이 필요하다.


소켓 함수 호출이 성공할 시점을 미리 알 수 있다.

send, recv 할 수 있는지 여부를 먼저 체크한다.

 

문제상황)

수신버퍼에 데이터가 없는데 read를 한다.

송신버퍼가 꽉 찼는데, write 한다.

=> Blocking -> 대기 / Non-Blocking -> WSAEWOULDBLOCK  에러

 

Blocking -> 조건이 만족되지 않아서 블로킹 되는 상황 예방

Non-Blocking -> 조건이 만족되지 않아서 불필요하게 반복 체크하는 상황 예방

 

socket set

1. 읽기[ ] 쓰기[ ] 예외(OOB)[ ] 관찰 대상 등록
OutOfBand는 send() 마지막 인자 MSG_OOB로 보내는 특별한 데이터. recv OOB 세팅을 해야 읽을 수 있음.

2. select(readSet, writeSet, exceptSet); -> 관찰 시작

3. 적어도 하나의 소켓이 준비되면 리턴 -> 낙오자는 알아서 제거됨

4. 남은 소켓 체크해서 진행

 

fd_set set;

FD_ZERO: 비운다
ex) FD_ZERO(set);

FD_SET: 소켓 s를 넣는다
ex) FD_SET(s, &set);

FD_CLR: 소켓 s를 제거
ex) FD_CLR(s, &set);

FD_ISSET: 소켓 s가 set에 들어있으면 0이 아닌 값을 리턴한다.
ex) bool isSet = FD_ISSET(s, &set);

 

코드)

https://github.com/Juzdalua/study-cpp/blob/main/Study/TCP-Select-SocketServer.cpp

 

study-cpp/Study/TCP-Select-SocketServer.cpp at main · Juzdalua/study-cpp

Study C++. Contribute to Juzdalua/study-cpp development by creating an account on GitHub.

github.com

 

'Server > C++' 카테고리의 다른 글

Blocking & Synchronous  (1) 2024.08.12
WSAEventSelect 모델  (0) 2024.08.10
논블로킹 소켓 (Non-Blocking Socket)  (0) 2024.08.07
Socket option  (0) 2024.08.06
UDP 소켓 프로그래밍  (0) 2024.08.06