본문 바로가기

게임 회사/서버 프로그래밍

[3] 소켓 프로그래밍

게임 서버 프로그래밍 시 주의사항

- 게임 서버는 TCP를 이용할 경우 클라이언트의 개수만큼 소켓이 있어야 함

- 파일 핸들을 하는 동안 스레드가 대기하는 일이 없어야 함

 

소켓에 대한 입출력 방식

- 동기 입출력 방식 : 블로킹 소켓(blocking socket)

- 비동기 입출력 방식 : 논블로킹 소켓(non-blocking socket), Overlapped I/O, epoll, I/O Completion Port(IOCP)

 

블로킹 소켓(blocking socket)

1) 블로킹(blocking)이란?

- 디바이스에서 처리 요청(받은 데이터를 디바이스에 기록 혹은 호출)을 걸어 놓고 응답을 대기하는 함수 호출 시, 스레드에서 발생하는 대기 현상

- 해당 상태에서는 CPU 사용량이 0%이므로 스레드는 waitable state가 됨

- 이 상태동안 파일이나 소켓의 실제 처리는 디바이스에서 이루어짐

2) 송신 버퍼와 수신 버퍼

- 소켓은 송신 버퍼(send buffer)와 수신 버퍼(receive buffer)를 하나씩 가지고 있음

- 송신 버퍼는 일련의 바이트 배열(byte array), 크기는 고정되어 있으나 마음대로 변경할 수 있음

- send()함수가 호출되면 송신 측 소켓의 송신 버퍼에 데이터가 채워지지만 금방 빠져나감

- 송신 버퍼가 꽉 차있을 경우 블로킹이 발생

- 수신 버퍼는 수신할 데이터가 있을 때까지 블로킹 상태

- TCP는 송신자가 초당 보내는 데이터양이 수신자가 초당 수신할 수 있는 데이터양보다 많을 때, 알아서 송신자 측 운영체제가 초당 송신량을 줄임(혼잡 제어)

- UDP는 혼잡 제어가 없기 때문에 같은 상황에서 네트워크가 두절될 수 있는데 이를 혼잡(Congestion)이라 함

 

논블록 소켓(non-block socket)

- 논블록 소켓은 호출 함수에 대하여 성공, 혹은 would_block 둘 중 하나만 반환함

- would block이 호출되면 아무것도 안함

- TCP에서 0바이트를 송신하면 아무것도 하지 않음, 이를 이용해 TCP 소켓이 어떤 상태인지 확인할 수 있음

- 0바이트 송신 함수가 성공하면 TCP 연결이 되어있다는 의미, ENOTCONN(소켓이 연결되지 않았음)

- select 함수 = 여러 소켓 중 하나라도 송신 버퍼에 빈 공간이 생기거나 수신 버퍼에 뭔가가 들어오면 그 상황을 알려줌, 그것을 알리기 전까지는 블로킹 중이어서 CPU 사용량 폭주를 해결하는 함수

 

논블록 소켓의 장단점

장점

- 스레드 블로킹이 없으므로 중도 취소 가능

- 스레드 개수가 1개이거나 적어도 소켓 여러개 다룸

- 스레드 개수가 적거나 1개이므로 연산량이 낭비되지 않으며 호출 스택 메모리도 낭비되지 않음

단점

- would block인 경우 재시도 호출 낭비

- 소켓 I/O 함수 호출 때 입력하는 데이터 블록에 대한 복사 연산 발생

- send()receive() 함수는 재시도 호출해야 하는 API가 일관되지 않음

 

Overlapped I/O or 비동기 I/O

- 논블록 소켓에서 발생하는 재시도용 호출 낭비 문제와 소켓 함수에 데이터 블록 복사 부하 문제를 해결

- 코드가 돌고 있는 것과 별개로 백그라운드에서 OS가 데이터에 접근

- 단 소켓 개수에 비례해서 루프가 돌기 때문에 성능에 문제가 발생

- 이를 해결하기 위해 epoll IOCP가 등장

 

epoll

- epoll은 소켓이 I/O 상태가 되면 이를 사용자에게 알려줌

- , 리눅스와 안드로이드에서만 사용 가능

 

select 방식과 IOCP 방식

1) select 방식

- read, write에서 버퍼가 비었는지 수시로 확인하며 빈 경우 사용

2) IOCP

- 데이터 전송을 요청해두고 다른 일을 수행함

- 수신 측도 데이터가 수신되기 전까지 다른 작업을 수행

- OS가 성능처리를 해주며 일을 분담

'게임 회사 > 서버 프로그래밍' 카테고리의 다른 글

[2] 컴퓨터 네트워크  (0) 2022.06.01
[1]스레드와 멀티 스레드  (0) 2022.05.31