Study/TIL(Today I Learned)

24.04.10 서버 프로그래밍

에린_1 2024. 4. 10. 23:58
728x90

게임 서버 프로그래밍 교과서

5장. 게임 네트워킹

5.1 UML

  • 프로그램 구조 명세를 표현하는 대표적 수단이다.

UML 시퀀스 다이어그램

  • UML 시퀀스 다이어그램에서는 객체와 메시지를 사용한다.
  • 객체는 상호 작용의 주체(예 : 클라이언트, 서버)에 해당한다. 메시지는 상호작용의 내용(예 : 메시지 전달, 함수 실행, 이벤트 수신)으로 화살표이다. 화살표 방향을 보고 보내는 쪽과 받는 쪽을 구분할 수 있다.
  • 시퀀스도의 주요용도는 객체 간 메시징 흐름을 일목요연하게 표현하는 것이다.
  • 시퀀스도는 객체 사이에 메시지를 주고 받는 것을 한눈에 알아보기 쉽게 표현할 수 있다. 시퀀스도는 주고 받는 메시지를 어떻게 처리하는지 자세하게 표현하는 데는 한계가 있는데, 플로 차트를 함께 사용하면, 보다 자세하게 프로그램의 실행방식을 그림으로 묘사할 수 있다. 이것이 액티비티 다이어그램이다.
  • 액티비티 다이어그램은 플로차트와 비슷하지만, 몇 가지 차이가 있다. 실린더 도형은 활동 상태(action state)를 의미한다. 맨 위에 있는 것은 최초 상태를 의미한다.

5.2 게임 플레이 네트워킹

모든 역할을 서버에서 하기

  • 클라이언트가 하는 역할
    1. 사용자 입력(키 입력, 마우스 좌표)
    2. 화면 출력
  • 서버에서 하는 역할
    1. 게임 로직 연산
    2. 화면 렌더링(그래픽 데이터 보유)
    3. 화면 송출(비디오 스트리밍)
  • 온라인 게임을 방해하는 레이턴시가 길어지는 요인
    1. 서버가 멀리 있으면 네트워킹 중에 레이턴시가 추가된다.
    2. 클라우드 서버 안에서 가상머신은 다른 가상머신이 CPU 사용량을 잠식하면서 조금씩 지연시간이 있을 수 있다.
    3. 패킷 드롭으로 인한 재송신을 간헐적인 큰 지연시간을 일으킨다.
    4. 인구가 낮은 국가에서는 인터넷이 느리다
    5. 무선 네트워크에서는 레이턴시와 패킷 드롭률이 크게 증가한다.

렌더링은 클라이언트에서 하기

  • 더 나은 방법은 게임 서버가 하는 역할 중에서 렌더링을 클라이언트에서 담당하는 것이다.
  • 시퀀스도에서 서버와 클라이언트가 하는 일은 다음과 같다.
    • 서버는 렌더링을 위한 최소 정보인 게임 월드 상태만 클라이언트에 보낸다. 월드 상태의 연산(scene update)은 서버에서 한다.
    • 렌더링은 클라이언트에서 수행한다. 이를 위한 그래픽 리소스는 클라이언트에서 보유한다.
    • 서버와 클라이언트의 월드 상태(scene)을 동일하게 유지한다. 즉, 동기화한다.
  • 씬의 상태에 영구적 변화를 가하는 것을 지속성 이벤트라고 한다.
  • 단발성 이벤트는 씬의 변화에 영향을 잠깐 주고 사라진다.
  • 미래가 클라이언트와 서버간에 서로 약속된, 결정적(deterministic)인 경우에는 지속성 이벤트보다는 단발성 이벤트가 더 효과적이다.
  • 이렇게 월드의 변화 정보를 서버에서 보내준다. 게임 플레이 연산은 모두 서버에서만 한다.
  • 이 방식이 원활하게 작동하려면 다음과 같이 해야 한다.
    1. 서버에서는 1/60 초 마다 월드 상태를 업데이트한다.
    2. 서버는 1/60 초 마다 월드 상태의 변화를 클라이언트에게 보낸다
    3. 클라이언트는 이를 지체없이 받는다.
    4. 클라이언트는 받은 것을 자기의 월드 상태에 반영한다. 그리고 다음 렌더링 프레임에서 이를 그린다.
  • 이것이 원활하게 작동하려면 서버와 클라이언트 사이에 레이턴시가 1/60초 보다 훨씬 낮아야 한다. 게다가 레이턴시가 항상 균일해야 한다. 그러나 현실적으로 이러한 네트워크 환경을 갖추려면 로컬 네트워크(LAN)이 아닌 이상 쉽지 않다.
  • 이 문제를 해결하려면 1/60초 대신 1/30초나 1/10초 단위로 월드 변화를 알리면 되는데 이렇게 되면 1/10초 마다 월드 상태가 변하면서 캐릭터 움직임이 딱딱해지는 문제가 생긴다.
  • 이 문제를 해결하려면 X값을 강제로 부드럽게 만들어야 하는데 이를 상태 값 보정이라고 한다.
  • 상태값 보정이란 서버에서 받는 상태 변화 메시지를 즉시 반영하는 것이 아니라 일정시간에 거쳐서 목적 상태로 변화하게 하는 것이다.
  • 이렇게 부드럽게 해주는 방법으로 선형 보간(lerp 또는 interpolation)이나 스플라인(spline) 같은 곡선형 보간이 있다.

추측항법(dead reckoning)

  • 캐릭터의 위치 정보를 이미 지난 약간의 시간만큼 예측한다.
  • 상대방 움직임을 어느정도 예상해서 그 위치로 갈 수 있게 보정시키는 방법을 의미한다. 추측항법이 제대로 작동하려면 몇 가지 배경 지식이 필요하다. 먼저 두 기기간의 레이턴시를 알고 있어야 한다. 레이턴시를 측정하는 방법에는 여러가지가 있지만, 대표적인 것은 라운드 트립 레이턴시(round trip latency)를 측정하는 방법이다. 라운드 트립 레이턴시를 측정하는 방법은 다음과 같다.
    • 기기 A에서 기기 B에 패킷을 보낸다.
    • 기기 B는 이를 받으면 기기 A에 패킷을 보낸다.
    • 기기 A는 1과정의 시간과 현재 시간의 차이를 구하여 2로 나눈다.
  • 추측항법을 포함한 이러한 방법을 통틀어 레이턴시 마스킹이라고 한다.

레이턴시 마스킹(latency masking)

  • 인터넷 환경이 그다지 빠르지 않을 때 플레이어가 입력한 명령이 서버를 거쳐 다시 도착할 때까지 시간이 걸린다. 이 문제를 해결하는 방법 중 하나는 사소한 것들은 클라이언트에서 판단하기 이다. 플레이어 자신이 조종하는 플레이어 캐릭터의 위치 계산은 클라이언트에서 판단하고, 클라이언트는 판단 결과를 서버에 보내주는 것이다.
  • 이 방법은 플레이어 자신이 조종하는 캐릭터가 즉시 반응하는 쾌적한 경험을 제공할 뿐만 아니라 서버에서 플레이어 캐릭터를 움직이는데 필요한 연산을 하지 않아도 되므로 서버 처리량이 줄어드는 장점도 있다 하지만 단점도 뒤따른다. 클라이언트가 해킹되어서 플레이어 캐릭터의 이동속도를 굉장히 빠르게 했다면 어떻게 될까?
  • 이 문제를 해결하려면 다음과 같이 해야한다.
    1. 클라이언트 플레이어 캐릭터의 이동 정보를 서버에 보낸다.
    2. 서버는 이동 정보를 받아서 정상적인 값 범위에 있는지 검사한다.
  • 혹은 이렇게 한다.
    1. 클라이언트는 플레이어 캐릭터의 명령 정보를 서버에 보낸다. 클라이언트에서는 자기 플레이어 캐릭터를 일방적으로 움직인다. 그러나 캐릭터 이동 정보 메시지는 서버에 보내지 않는다.
    2. 서버는 명령 정보에 따라 플레이어 캐릭터를 이동 처리한다. 플레이어 캐릭터의 이동 정보 메시지를 클라이언트에게 보낸다.
    3. 클라이언트는 서버에서 이동 정보 메시지를 받으면, 앞서 일반적으로 움직였던 플레이어 캐릭터 위치를 무시하고 서버에서 메시지에 따라 캐릭터를 이동시킨다.
  • 두 가지 방법은 일장일단이 있다. 두 번째 방법은 해킹을 막는데는 가장 좋지만, 레이턴시가 100밀리초를 넘을 때마다 캐릭터 움직임이 손상된다. 따라서 두 번째 방법은 각 주고 받는 메시지의 레이턴시가 다소 균일하고, 레이턴시가 낮은 경우(50밀리 초 이하)에 한해 채택하는 것이 일반적이다.

5.3 넓은 월드, 많은 캐릭터 처리

  • 게임 월드 안에 캐릭터 수가 너무 많으면 통신량이 증가한다는 문제점이 발생한다. 특히 이런 문제는 mmorpg같은 대규모 멀티 플레이 온라인 게임에서 발생한다. 수 천명의 플레이어여도 플레이어의 화면에 나타나는 캐릭터는 그 중 일부이다. 이러한 문제를 가시 영역 필터링으로 해결할 수 있다.
  • 클라이언트는 자기 근처에 있는 다른 캐릭터들 정보만 가진다.
  • 서버에서는 모든 플레이어가 모든 캐릭터 정보를 가지고 있어야 한다. 그 뿐만 아니라 서버는 모든 플레이어의 가시 영역 정보도 가지고 있어야 한다. 그래야 서버에서는 캐릭터 움직임에 변화가 있을 때, 그 캐릭터를 볼 수 있는 다른 플레이어들의 클라이언트에만 변화했다는 내용의 메시지를 보낼 수 있기 때문이다.
  • 서버는 다음 정보를 가지고 있어야 한다.
    1. 플레이어 각각에 대해서 각 플레이어가 볼 수 있는 캐릭터 목록
    2. 캐릭터 각각에 대해서 자기 자신을 볼 수 있는 플레이어 목록

5.4 실제 레이턴시 줄이기

  • TCP 대신 UDP를 사용하는 것이다.( ex. 캐릭터 이동 메시지 같은 경우)
  • 메시지를 뭉쳐서(coalescence) 보내기, 무선 인터넷의 CSMA 알고리즘으로 발생하는 지연 시간을 줄이기 때문이다. 그렇다고 너무 뭉치면 기다리는 시간 자체가 네트워크 지연 시간처럼 느껴진다. 필자 경험 상 이 뭉치는 10밀리초 이하가 적당하다.
  • 클라이언트와 서버 간 통신과 클라이언트끼리 직접 통신하는 것을 같이 섞어 쓰는 방법도 좋다. 전자는 C/S 네트워킹이라고 하며, 후자는 P2P 네트워킹이라고 한다.

5.6 해킹과 보안

  • 해킹의 유형
    1. 크래킹(crack) : 다른 사람의 ID와 비밀번호를 도용하거나 비밀 정보를 보는 것을 의미한다. 서버에 저장된 데이터를 훼손하거나 훔치는 것도 포함된다.
    2. 치트(cheat) 혹은 조작(exploit) : 게임에서만 발견되는 형태의 해킹이다. 내 능력치를 비정상적으로 높이거나 다른 사람의 플레이를 망가뜨리는 것을 의미한다.
  • 요즘 많이 사용하는 암호화 알고리즘은 암호 키(encryption key)를 이용해서 암호화를 하는 것이다.
728x90