게임서버 공부_socket_동기, 블럭 그리고 socket

동기/비동기, 블로킹/논블로킹은 관점의 차이

동기(Synchronous) / 비동기(Asynchronous) : 순서, 상황, 필요성

동기화 함수 : 독립된 스레드/프로세스간에 동기성(순서)를 가질수 있게 하는 함수들 ->

블로킹(Blocking)/논블로킹(Nonblocking) : 제어권, 동작, I/O

동기/비동기, 블로킹/넌블로킹 실제

read()함수로 데이터를 읽어서 파싱하는 코드

write()함수로 처리한 데이터를 파일에 입력.

동기/비동기식 처리

각각의 관점 참조한 블로그

리눅스에서의 block/non-block

비동기와 멀티스레딩 동기/비동기는 작업의 흐름에 관한 관점. 스레딩은 작업자의 개수에 따른 관점.

non-blocking과 멀티플랙싱

selec

select와 write buffer

WSAAsyncSelect흐름 : 콜백함수 호출. 각종 초기화(윈도우 클래스 등록 및 생성, 윈속초기화, 리슨소켓 생성) -> 바인드 -> 리슨 -> 셀렉트 -> 메세지 루프에서 무한 반복.

WSAEventSelect 윈속 초기화 -> 소켓 생성(비동기) -> 바인드 -> 리슨 -> wsaeventselect(소켓과 이벤트 연결) -> 이벤트대기(비동기) -> 이벤트 확인(FD_…) -> 각 이벤트에 맞는 처리

공통점 : 소켓들의 정보를 따로 자료구조에 담아서 처리해야 하는데, 각 함수들은 이를 수행하지 않으니 알아서 추가 및 삭제해야함.

멘토링

1. 책에서 소개한 여러 select모델들이 있는데, 일반 select나 IOCP만 사용하는 이유

WSAAsyncSelect나 WSAEventselect 둘다 내부적으로 Select를 사용하고 있고, 이를 쉽게 쓰기 위한 함수들이다. 차라리 Select를 멀티스래딩해서 쓰는게 호환성에서도 좋고 성능도 큰 차이가 안난다.

2. 소켓 버퍼

윈도우 7이전에는 소캣 버퍼 크기가 정적이여서 부족한경우가 많았고, 이를 소켓 생성시 설정해주었다(특히 send). 하지만 요즘은 OS가 동적으로 관리해줘서, 버퍼 크기를 유저가 설정해버리면 자원 낭비가 될 가능성이 크다.

3. 소켓 모델 선택

하지만 게임 서버 프로그래밍에서는 성능이 최우선이고, 업게 전반적인 분위기도 그렇고 IOCP를 쓰는게 거의 무조건 좋다고 한다(선택한건데 모르는거라고 오해할수도 있다고…)

리눅스쪽은 epoll을 많이 쓴다. 최근에 io_uring이 나왔지만, 리눅스쪽은 서버 HW의 버전 업데이트가 늦는 편이므로 아직은 epoll이 적합하다.

4. udp는 select같은 방식으로 처리할 필요가 없는가?

udp는 연결 개념이 없으므로 단일 소켓으로 처리해도 충분하다.

5. select에서 write_set

select사용시 write_set이 true가 되는 경우는 소켓 송신 버퍼가 비어있을때 이다. 하지만 대부분의 경우 해당 버퍼는 비어있으므로 확인을 안한다. 하지만 확인을 해야하는 경우는 다음과 같다.