90

온라인 게임을 지탱하는 기술

  • View
    254

  • Download
    17

Embed Size (px)

DESCRIPTION

나카지마 켄고 지음 | 김상우 옮김 | 게임 개발 시리즈 _ 004 | ISBN: 9788992939010 | 30,000원 | 2012년 06월 15일 발행 | 624쪽

Citation preview

Page 1: 온라인 게임을 지탱하는 기술
Page 2: 온라인 게임을 지탱하는 기술
Page 3: 온라인 게임을 지탱하는 기술
Page 4: 온라인 게임을 지탱하는 기술

이 책에 대해서 ………………………………………………………………………………………………… 24

이 책의 구성 …………………………………………………………………………………………………… 26

샘플 게임 & 동영상 ………………………………………………………………………………………… 28

이 책의 보충정보 코너에 대한 안내 ………………………………………………………………………… 30

감사의 말씀 …………………………………………………………………………………………………… 30

기본 용어의 정리 ……………………………………………………………………………………………… 31

제 0 장

[속성] 온라인 게임 프로그래밍

0.1 [온라인 게임 프로그래밍을 위한] 네트워크 프로그래밍의 기초 ………………………… 41

네트워크 프로그래밍은 필수(!) ……………………………………………………………………… 41

네트워크 프로그래밍, 인터넷 프로그래밍 …………………………………………………………… 41

인터넷 프로그래밍의 역사와 사상 …………………………………………………………………… 42

OSI 참조 모델 ………………………………………………………………………………………… 43

온라인 게임 시스템과 레이어 ……………………………………………………………………… 44

레이어4는 대부분의 경우 TCP를 사용하고,

레이어3 이하는 직접적인 조정이 필요 없음 ……………………………………………………… 44

레이어5 이상은 게임단에서 구현한다 …………………………………………………………… 45

소켓 API의 기초 지식 …………………………………………………………………………………… 45

온라인 게임과 소켓 API ………………………………………………………………………………… 46

커넥션 지향(스트림형), 커넥션리스 지향(데이터그램형) ……………………………………… 46

0.2 [소켓 프로그래밍 입문] 복수의 동시 접속을 처리, 성능을 추구한다 …………………… 49

통신로의 특정 …………………………………………………………………………………………… 49

소켓 API의 기본 …………………………………………………………………………………………50

TCP 통신로의 상태 전이와 소켓 API………………………………………………………………… 52

복수의 동시 접속을 처리한다 ………………………………………………………………………… 55

동기적 호출(블로킹)과 스레드 ………………………………………………………………………… 55

스레드 방식의 처리 부하 문제 ……………………………………………………………………… 57

싱글 스레드, 논블록킹, 이벤트 구동 ………………………………………………………………… 57

온라인 게임에서의 입출력 구현의 특징 ……………………………………………………………… 58

온라인 게임과 구현 언어 ……………………………………………………………………………… 59

성능의 최대화 & 개발 효율 향상 …………………………………………………………………… 59

온라인 게임 고유의 특성에 의한 언어별 성능 차이 …………………………………………… 60

멀티코어 서버의 성능을 끌어낸다 …………………………………………………………………… 61

컨텍스트 스위치 - CPU의 설정 상태를 일시적으로 보관해 둔다 …………………………… 62

멀티코어 머신이며 서버 프로세스 수를 너무 늘리지만 않으면 OK ………………………… 63

목 차

Page 5: 온라인 게임을 지탱하는 기술

멀티코어 머신과 네트워크의 스루풋 ………………………………………………………………… 63

이더넷 프레임 ………………………………………………………………………………………… 63

네트워크 계층별 헤더 ……………………………………………………………………………… 65

멀티코어 머신의 송신 능력 ………………………………………………………………………… 67

서버 구현의 간소화 …………………………………………………………………………………… 68

libevent의 특징 …………………………………………………………………………………… 68

0.3 [RPC 공략] 최소 기능의 통신 미들웨어 ……………………………………………………… 69

통신 라이브러리의 필요성 ……………………………………………………………………………… 69

포맷을 결정하고 송수신한다 ……………………………………………………………………… 71

온라인 게임에서 사용하는 RPC의 전체적인 모습 ………………………………………………… 72

RPC 스터브 코드를 자동 생성하는 RPC 툴 …………………………………………………… 73

온라인 게임과 바이너리 데이터 교환 포맷/라이브러리 ………………………………………… 74

[보충] UDP의 이용 ……………………………………………………………………………………… 75

0.4 게임 프로그래밍의 기초 …………………………………………………………………………… 76

게임 프로그래밍의 역사 ………………………………………………………………………………… 76

「점만 찍을 수 있다면 게임은 만들 수 있다」 인베이더 게임 ……………………………………… 77

가상의 코드로 알 수 있다! 게임 프로그램의 기본 해부 …………………………………………… 78

초기화 ………………………………………………………………………………………………… 79

무한 루프 ……………………………………………………………………………………………… 80

각 스프라이트의 동작 - 게임 로직의 본체 ……………………………………………………… 81

화면 표시 ……………………………………………………………………………………………… 83

서브루틴 ……………………………………………………………………………………………… 84

게임 프로그래밍의 비결 ……………………………………………………………………………… 86

두 가지 프로그래밍 기법의 유사성 …………………………………………………………………… 87

0.5 요약 ……………………………………………………………………………………………………… 88

제 1 장

온라인 게임의 역사와 진화

1.1 온라인 게임의 기술사 ………………………………………………………………………………… 93

온라인 게임의 역사는 아직 50년 …………………………………………………………………… 93

1950년 이전 : 계산기의 등장 ………………………………………………………………………… 93

1950년대: 초기 비디오 게임 ………………………………………………………………………… 94

1960년대 : 영향력을 가진 각종 머신의 등장 ……………………………………………………… 96

1970년대: 온라인 게임 기본 요소가 갖추어짐 ……………………………………………………… 99

목 차

Page 6: 온라인 게임을 지탱하는 기술

1980년대: 네트워크 대전 게임의 등장 …………………………………………………………… 100

1990년대: 게임 시장의 확대 ……………………………………………………………………… 102

2000년대 전반 : 온라인 게임의 상업적 성립 …………………………………………………… 104

2000년대 후반: 웹 브라우저 기반 MMOG의 상업적 성공 …………………………………… 105

2010년대 이후 : 과연 어떤 일이 일어날 것인가? …………………………………………… 107

1.2 [기술의 변천에서 알 수 있는] 게임 문화/경제권 …………………………………………… 107

기술의 변천도를 읽자 ………………………………………………………………………………… 107

3개의 영역(카테고리) ………………………………………………………………………………… 107

해커 문화권 ………………………………………………………………………………………… 108

콘솔/아케이드 게임 비즈니스권 ………………………………………………………………… 109

마이크로소프트권 ………………………………………………………………………………… 109

두 가지의 게임 경제/문화권 …………………………………………………………………… 110

문화, 경제, 기술의 관계 ……………………………………………………………………………… 112

1.3 요약 …………………………………………………………………………………………………… 113

제 2 장

온라인 게임이란 무엇인가?

2.1 「온라인 게임」이라는 용어의 정의 ……………………………………………………………… 116

온라인 게임의 4개의 측면 …………………………………………………………………………… 116

2.2 온라인 게임의 물리적 측면 ……………………………………………………………………… 117

물리적 구성요소 ……………………………………………………………………………………… 117

컴퓨터 네트워크 …………………………………………………………………………………… 118

물리 모델/ 물리적인 네트워크 구성 ……………………………………………………………… 118

이 책이 대상으로 하는 회선은 「인터넷」 기반 ………………………………………………… 120

2.3 온라인 게임의 개념적인 측면 …………………………………………………………………… 121

온라인 게임과 기본구조 ……………………………………………………………………………… 121

게임 플레이의 기본 - 「인지」 「판단」 「조작」의 반복 ………………………………………… 121

비디오 게임의 구조 ……………………………………………………………………………… 121

게임 플레이 공간 ……………………………………………………………………………………… 122

게임의 진행 …………………………………………………………………………………………… 123

하나의 게임의 진행을 공유한다 …………………………………………………………………… 124

공유가 「가능하다」 ………………………………………………………………………………… 124

목 차

Page 7: 온라인 게임을 지탱하는 기술

2.4 온라인 게임의 비즈니스적 측면 ………………………………………………………………… 125

비즈니스적 관점의 요구 ……………………………………………………………………………… 125

테스트 플레이어를 효과적으로 모으고 싶다 ……………………………………………………… 127

클로즈 베타 테스트(CBT) ……………………………………………………………………… 128

오픈 베타 테스트(OBT) ………………………………………………………………………… 128

자주 갱신하고 싶다 …………………………………………………………………………………… 129

정기적 패치 …………………………………………………………………………………… 129

대규모 패치(확장 디스크, 추가 패키지) …………………………………………………… 129

긴급 메인터넌스 ……………………………………………………………………………… 130

머신의 대수와 회선 대역을 절약하고 싶다 ………………………………………………………… 130

인건비& 설비 코스트 - 운영, 개발 후에 소요되는 코스트가 큼 …………………… 130

머신 코스트의 견적 - 서버가 고장 날 확률을 포함해 둔다 ………………………………… 131

회선 코스트의 견적 - 대역은 가능한 절약한다 ……………………………………………… 131

작게 시작하고 싶다. 스케일러빌러티를 지니게 하고 싶다 ……………………………………… 132

다양한 과금 옵션을 제공하고 싶다 ………………………………………………………………… 132

게임 포인트의 등장 - 과금의 세분화, 리얼타임화의 실현 ………………………………… 133

공격자를 저렴한 비용으로, 빨리, 확실히 배제하고 싶다 ………………………………………… 134

상업적 의도의 어뷰즈 …………………………………………………………………………… 135

상업적 의도가 없는 어뷰즈 - 여러 가지의 공격, 3D 온라인 게임 전용 게임 클라이언트 136

서비스 정지 시간과 횟수를 줄이고 싶다 …………………………………………………………… 137

❶ 계획적인 메인터넌스로 인한 정지 …………………………………………………………… 137

❷ 결함이나 공격에 의한 서비스 정지 ………………………………………………………… 138

게임 플레이 결과를 피드백하고 싶다 ……………………………………………………………… 139

게임 플레이의 메타 정보 ………………………………………………………………………… 140

하이스코어 랭킹 ……………………………………………………………………………… 140

플레이 실적 …………………………………………………………………………………… 140

그 외의 통계 …………………………………………………………………………………… 141

한층 더 고도의 기술이 요구되는 플레이 실적 ………………………………………………… 141

더욱 간단하게 다른 플레이어와 만날 수 있게 하고 싶다 ……………………………………… 142

자동 선택식 …………………………………………………………………………………… 142

전용 로비 ……………………………………………………………………………………… 143

가상 세계(비쥬얼 로비, 버추얼 로비) ……………………………………………………… 143

전용 로비 형식과 가상 세계의 차이점 ………………………………………………………… 143

플레이어 매칭의 향후 …………………………………………………………………………… 144

2.5 온라인 게임의 사람과 조직적 측면 …………………………………………………………… 144

온라인 게임 서비스의 운영에 관한 사람들 ………………………………………………………… 144

세 가지 기능과 분담 패턴 ………………………………………………………………………… 145

온라인 게임 서비스 운영의 3가지 전문 기능 ……………………………………………………… 146

만드는 사람들 ……………………………………………………………………………………… 146

반드시 필요한 4가지 직종 ……………………………………………………………………… 147

목 차

Page 8: 온라인 게임을 지탱하는 기술

소규모 팀 …………………………………………………………………………………………… 147

대규모 팀 …………………………………………………………………………………………… 147

직종의 밸런스에서 엿볼 수 있는 게임 개발의 특유한 점 - 데이터 작성 스텝의 비율 ……… 148

운용하는 사람들 ……………………………………………………………………………………… 149

서버 설비 …………………………………………………………………………………………… 149

2.6 온라인 게임 프로그래머에 요구되는 지식군 ………………………………………………… 150

온라인 게임 프로그래머에 필요한 능력과 경험 …………………………………………………… 150

프로그래밍 기초 스킬 …………………………………………………………………………… 150

게임 프로그래밍의 기초 지식(온라인 게임 개발에서도 필요) ……………………………… 152

게임 클라이언트 개발 지식 ……………………………………………………………………… 154

DB 지식 …………………………………………………………………………………………… 155

시스템 운용 지식S ………………………………………………………………………………… 155

여러 방면에서 필요한 온라인 게임의 개발 지식 ………………………………………………… 156

2.7 온라인 게임을 뒷받침하는 기술의 대구분 …………………………………………………… 157

온라인 게임을 뒷받침하는 기술의 4가지 형식 …………………………………………………… 157

C/S형과 P2P형 - 물리적인 구조의 두 가지 전형적 패턴 ………………………………… 157

MMO형과 MO형 - 논리적인 구조의 두 가지 전형적 패턴 ……………………………… 158

온라인 게임의 4가지 형식 - 물리적 구조×논리적 구조 …………………………………… 159

2.8 개발 코스트를 좌우하는 기술적 포인트 ……………………………………………………… 159

온라인 게임과 개발 기법의 현재 …………………………………………………………………… 159

온라인 게임의 게임 본체를 뒷받침하는 3가지 축 ………………………………………………… 160

게임 데이터 형식 ………………………………………………………………………………… 160

게임 통신 형식 …………………………………………………………………………………… 162

게임 반응속도 ……………………………………………………………………………………… 163

2.9 요약 …………………………………………………………………………………………………… 166

제 3 장

온라인 게임의 아키텍처

3.1 [게임 프로그램의 특성] 좋은 리스폰스를 계속해서 유지한다 …………………………… 175

리스폰스의 중요성 …………………………………………………………………………………… 175

온 메모리가 필요한 이유 …………………………………………………………………………… 175

16밀리초마다 변화 ……………………………………………………………………………… 176

게임 진행을 표현하는 데 필요한 정보와 그 사이즈 ………………………………………… 177

RDBMS를 이용해 구현할 수 있을까? - 온 메모리와의 비교 ……………………………… 178

목 차

Page 9: 온라인 게임을 지탱하는 기술

대량의 오브젝트 표시 …………………………………………………………………………… 179

패밀리컴퓨터와 CPU 사이클 …………………………………………………………………… 180

패밀리컴퓨터로 RDBMS? ……………………………………………………………………… 181

플레이스테이션 3(PS3)과 CPU 사이클 - RDBMS 방식으로 개발할 수 있을까? …… 181

플레이어의 조작을 예상할 수 없다 …………………………………………………………… 182

RDBMS 방식으로는 실현할 수 없는 정보량, 처리 속도 …………………………………… 183

CPU와 동일 머신에 게임 진행 데이터를 배치해야 한다 ………………………………………… 183

3.2 온라인 게임 특유의 요소 ………………………………………………………………………… 184

통신 레이턴시 ………………………………………………………………………………………… 184

통신 시간의 내역 ………………………………………………………………………………… 185

피할 수 없는 지연 - 지연과 게임 장르 ………………………………………………………… 185

대역 …………………………………………………………………………………………………… 188

서버 머신 ……………………………………………………………………………………………… 189

보안 …………………………………………………………………………………………………… 189

치트 - 최대의 보안 이슈 ………………………………………………………………………… 189

치트는 왜 행해지는가? …………………………………………………………………………… 190

치트 행위의 수단 ………………………………………………………………………………… 191

치트의 조작 대상 ………………………………………………………………………………… 192

노이먼형 컴퓨터의 숙명 - 치트 행위에 대한 방지 서비스 ………………………………… 193

무서운 치트 행위의 파급 효과 …………………………………………………………………… 193

보조 시스템(주변 시스템) …………………………………………………………………………… 194

3.3 물리 아키텍처의 상세 해부 C/S형, P2P형 ………………………………………………… 195

기본적 네트워크 토폴로지 …………………………………………………………………………… 195

실제로 사용되는 것은 스타와 버스, 풀 메시 - 통신 레이턴시의 최소화 ………………… 196

물리 아키텍처의 종류 ………………………………………………………………………………… 197

C/S형 ………………………………………………………………………………………………… 197

리플렉터형 ………………………………………………………………………………………… 198

P2P형 ………………………………………………………………………………………………… 199

NAT 트래버설 …………………………………………………………………………………… 200

C/S+P2P 혼합형 …………………………………………………………………………………… 200

ad-hoc 모드 ………………………………………………………………………………………… 201

3.4 논리 아키텍처의 상세 해부 MO형 …………………………………………………………… 202

MO, MMO란? ……………………………………………………………………………………… 203

MMO와 MO의 하이브리드(혼합) ……………………………………………………………… 203

MO형, MOG ………………………………………………………………………………………… 204

동기식 ………………………………………………………………………………………………… 204

동기식/풀 메시형의 구현 …………………………………………………………………………… 205

각 단말(플레이어)이 송수신하는 정보의 내용 ………………………………………………… 205

목 차

Page 10: 온라인 게임을 지탱하는 기술

동기식/풀 메시형에 필요한 조건과 메리트 …………………………………………………… 207

동기식/풀 메시형의 3가지 문제점 - 통신망과 송수신의 완전성의 취약점, 게임의 중도 참가 208

통신로의 신뢰성 …………………………………………………………………………………… 209

「가장 느린 단말의 속도에 맞춰진다」는 문제 ………………………………………………… 211

동기식/스타형 ………………………………………………………………………………………… 212

스타형이 가지고 있는 4가지 문제 ……………………………………………………………… 214

동기식 전반의 큰 문제 - 게임 도중에 참가할 수 없다 ……………………………………… 215

동기식의 메리트와 문제 해결 방법 ……………………………………………………………… 216

비동기식 ……………………………………………………………………………………………… 217

비동기식의 구현 방침을 세우는 방법 - 게임 내용의 상세한 분석이 필수 …………………… 217

3가지 기본 요소 「자신」 「상대」 「환경」 …………………………………………………………… 217

3가지 요소의 관계 ………………………………………………………………………………… 218

자신과 상대 ……………………………………………………………………………………… 219

격투 게임의 예 …………………………………………………………………………………… 219

공격, 방어, 타격 판정 …………………………………………………………………………… 220

격투 게임의 시퀀스 그림 ………………………………………………………………………… 222

추상도가 낮은, 원인을 알 수 있는 데이터를 송신할 필요가 있다 - 결과의 납득 ……… 223

결과가 어긋나는 문제 발생! ……………………………………………………………………… 224

결과의 정합성을 유지하는 방법 …………………………………………………………………… 225

데미지를 발생시킨 쪽의 결과를 사용한다 ……………………………………………………… 225

데미지를 받은 쪽의 결과를 사용한다 …………………………………………………………… 226

방식 선택의 원칙 - 플레이어의 만족감 향상을 위해 ………………………………………… 227

자신과 환경 ……………………………………………………………………………………… 228

배타 제어가 필요한 타입의 환경 요소 - 경합하는 자원 「폭탄」 …………………………… 228

배타 제어가 필요 없는 타입의 환경 요소 - 줄지 않는 자원 「물」 ………………………… 229

게임의 환경 요소는 의외로 다루기 어렵다 - 일단 게임 내용을 상세하게 이해한다 …… 229

배타 제어의 구현 …………………………………………………………………………………… 230

아이템 듀프 문제 ………………………………………………………………………………… 230

아이템에 고유한 ID를 부여한다 - 듀프가 일어났는지를 판정, 발생하는 문제 ………… 231

아이템 듀프의 대책 - 중재 역할의 소프트웨어를 배치한다. ……………………………… 233

중재역의 기본 기능과 사용법 …………………………………………………………………… 235

폭탄 이외의 환경 요소의 경우 …………………………………………………………………… 236

자동적으로 상태가 변화하는 환경 ………………………………………………………………… 237

동적인 환경에서 일어나는 문제 - 완전하게 병행 관리하는 방법으로는 어렵다 ………… 238

동적 환경에서 일어나는 문제의 대처법 선택 ……………………………………………………… 241

상대와 환경의 관계 ……………………………………………………………………………… 242

3.5 논리 아키텍처 상세 해부 MMO형 …………………………………………………………… 244

MMO형, MMOG …………………………………………………………………………………… 244

영속적이란? - 게임 플레이 소요 시간과 축적성 …………………………………………… 244

목 차

Page 11: 온라인 게임을 지탱하는 기술

영속적인 데이터, 대량으로 축적되는 데이터의 일관성 유지의 어려움 …………………… 245

클라이언트와 서버의 완전 분리 ………………………………………………………………… 246

MMOG의 구조 ………………………………………………………………………………………… 247

MMO형의 구현 방침 - 브라우저식, 순수한 C/S모델 ……………………………………… 247

브라우저식과 동기식 및 비동기식의 차이 ……………………………………………………… 248

MMO형에 있어서 서버, 클라이언트의 기능 ………………………………………………… 248

서버의 처리 - 서버 측의 게임은 계속 진행된다. …………………………………………… 249

MMO형만의 과제 …………………………………………………………………………………… 250

3.6 정리 …………………………………………………………………………………………………… 251

제 4 장

[실전] C/S MMO 게임 개발

4.1 온라인 게임 개발의 기본적인 흐름 …………………………………………………………… 255

프로젝트 자료/성과물 ………………………………………………………………………………… 255

준비와 초기 구현은 동시에 병행한다 …………………………………………………………… 258

개발의 진행과 자료 준비의 순서 …………………………………………………………………… 258

기술자의 자료/성과물 ………………………………………………………………………………… 259

4.2 C/S MMO 게임의 경향과 대책 ……………………………………………………………… 260

C/S MMO 게임의 특징 ……………………………………………………………………………… 260

C/S MMO형(MMO형) 게임의 특성 ……………………………………………………………… 261

C/S MMO형의 제약 …………………………………………………………………………… 262

4.3 [기획 자료와 5개의 설계 자료] 가공의 게임 「K Online」의 개발에서 배운다 ……… 263

샘플 게임의 소재 찾기 ……………………………………………………………………………… 263

기획 상세 자료 ………………………………………………………………………………………… 265

기획 상세 자료의 필요성 ………………………………………………………………………… 266

MMOG의 방대한 게임 설정 ………………………………………………………………………… 266

5가지 설계 자료 …………………………………………………………………………………… 267

설계상의 중요한 판단 ………………………………………………………………………………… 267

4.4 시스템 기본 구조도의 작성 ………………………………………………………………… 269

시스템 기본 구조도의 기본 ………………………………………………………………………… 269

확장성을 가진 서버 시스템이 필요 ………………………………………………………………… 269

다양한 보틀넥 - 스케일업 방식의 선택에 대해서 …………………………………………… 270

게임 서버/DB의 보틀넥을 해소한다 ……………………………………………………………… 274

목 차

Page 12: 온라인 게임을 지탱하는 기술

아무것도 고려하지 않는 경우 ……………………………………………………………………… 274

공간 분할법 …………………………………………………………………………………………… 275

공간 카피 …………………………………………………………………………………………… 276

인스턴스법 …………………………………………………………………………………………… 277

패러렐 월드 방식 …………………………………………………………………………………… 278

가장 보틀넥이 되기 쉬운 것은 DB의 쓰기 처리 ……………………………………………… 279

패러렐 월드 방식의 DB 분할 …………………………………………………………………… 280

패러렐 월드 방식의 문제 ………………………………………………………………………… 280

복수의 방법을 병용 ………………………………………………………………………………… 281

각 방식의 도입 난이도 ……………………………………………………………………………… 282

각 월드의 DB(게임 DB) 서버의 절대 성능 향상 ………………………………………………… 283

애플리케이션단의 개선점 연구 ………………………………………………………………… 283

K Online의 설계 사이징 …………………………………………………………………………… 284

보틀넥의 확인 ……………………………………………………………………………………… 284

설계 사이징에 대한 판단 원칙 …………………………………………………………………… 285

게임 로직의 처리 부하로부터 사이징 ……………………………………………………………… 285

게임 DB의 처리 부하로부터 사이징 ……………………………………………………………… 287

규모에 대한 최소한의 검토 결과, 보다 나은 유저 체험을 위하여… …………………………… 289

서버의 기본 구조, 시스템 기본 구조도의 작성 ………………………………………………… 290

4.5 프로세스 관계도 작성 ………………………………………………………………………… 291

프로세스 관계도 준비 …………………………………………………………………………… 292

서버 접속 구성 ……………………………………………………………………………………… 292

서버의 접속 구성 …………………………………………………………………………………… 294

패러렐 월드 방식을 사용하여 확장하는 경우 ……………………………………………………… 295

4.6 대역/머신 리소스 계산 자료의 작성 ……………………………………………………… 296

프로세스 리스트를 토대로 머신 리소스를 사이징 ………………………………………………… 296

CPU 센트릭 머신, 스토리지 센트릭 머신 ………………………………………………………… 299

머신 리소스의 코스트 견적 ………………………………………………………………………… 299

머신 리소스 유지 코스트 ………………………………………………………………………… 300

대역 코스트의 견적 …………………………………………………………………………………… 300

트래픽의 98%가 플레이어/NPC의 이동 통지이다 ………………………………………… 301

대역 반감을 위한 지침 ……………………………………………………………………………… 302

기획의 조정 - 대역 삭감 작전 ……………………………………………………………… 302

프로그램을 연구 - 대역 삭감 작전 ………………………………………………………… 303

대역 삭감에는 기획 내용의 재검토가 효과적 ……………………………………………………… 303

4.7 프로토콜 정의 자료의 작성 프로토콜의 기본적인 성질 ……………………………… 304

프로토콜 정의 자료의 기본 ……………………………………………………………………… 304

「프로토콜의 기본적인 성질」의 핵심요소 …………………………………………………………… 305

목 차

Page 13: 온라인 게임을 지탱하는 기술

프로토콜의 종류와 프로세스 관계의 종류 ………………………………………………………… 305

8 종류의 프로토콜 …………………………………………………………………………………… 306

C/S MMO에서는 TCP를 이용한다 ……………………………………………………………… 307

「프로토콜의 기본적인 성질」과 그 대응 일람표 …………………………………………………… 308

프로토콜 설계의 기본 전략 ……………………………………………………………………… 310

4.8 프로토콜 정의 자료 프로토콜의 API 사양(개관) ……………………………………… 310

프로토콜 구현의 원칙 ………………………………………………………………………………… 311

백엔드에 기본/범용 기능을, 프론트엔드에 전용 기능을 구현한다 ………………………… 311

백엔드에 프론트엔드가 의존하는 구조 ………………………………………………………… 311

프로토콜은 스테이트리스&단순한 기능으로 한다 …………………………………………… 312

외부로부터 오는 예외적 현상은 한 곳에 집중시킨다 ………………………………………… 312

우수한 API의 호출 시퀀스 - 호출하지 않는 것이 우수!? ………………………………… 313

8가지 프로토콜의 기능/형태 개요 ………………………………………………………………… 316

gmsv 프로토콜 …………………………………………………………………………………… 316

loginsv 프로토콜 ………………………………………………………………………………… 316

msgsv 프로토콜 ………………………………………………………………………………… 317

dbsv 프로토콜 …………………………………………………………………………………… 317

worldsv 프로토콜 ……………………………………………………………………………… 318

commondbsv 프로토콜 ……………………………………………………………………… 318

authsv 프로토콜 ………………………………………………………………………………… 319

logsv 프로토콜 …………………………………………………………………………………… 319

4.9 프로토콜 정의 자료 프로토콜의 API 사양(상세) ……………………………………… 319

프로토콜의 API 사양(상세) 작업 …………………………………………………………………… 320

API의 함수 정의 ……………………………………………………………………………………… 320

gmsv 프로토콜 …………………………………………………………………………………… 320

API 타입과 메시지의 특성 ……………………………………………………………………… 321

loginsv 프로토콜 ………………………………………………………………………………… 322

msgsv 프로토콜 ………………………………………………………………………………… 323

dbsv 프로토콜 …………………………………………………………………………………… 324

worldsv 프로토콜 ……………………………………………………………………………… 325

commondbsv 프로토콜 ……………………………………………………………………… 325

authsv 프로토콜 ………………………………………………………………………………… 326

logsv 프로토콜 …………………………………………………………………………………… 327

정수 정의 ……………………………………………………………………………………………… 327

API의 호출 시퀀스 …………………………………………………………………………………… 328

필요한 시퀀스도 - 복수의 프로세스가 관계하는 일반적인 처리란 무엇인가? …………… 329

� 인증 ……………………………………………………………………………………………… 330

gmsv의 캐릭터 작성 ………………………………………………………………………… 332

gmsv, msgsv에 로그인 …………………………………………………………………… 333

� gmsv로부터 로그아웃 ……………………………………………………………………… 333

목 차

Page 14: 온라인 게임을 지탱하는 기술

� gmsv의 캐릭터 이동 ………………………………………………………………………… 333

� gmsv의 캐릭터 인벤토리 조작(숍, 트레이드) …………………………………………… 334

� msgsv의 친구 목록에 친구를 추가, 삭제 ………………………………………………… 335

� 온라인 친구에게 메시지를 송신한다. ……………………………………………………… 335

시퀀스도의 작성 포인트 ……………………………………………………………………………… 337

4.10 프로토콜 정의 자료 패킷의 포맷 ………………………………………………………… 338

C/S MMO에서는 주로 TCP를 이용한다 ………………………………………………………… 338

C/S MMO는 전용 바이트 배열을 가지는 바이너리 프로토콜을 사용한다 …………………… 338

바이너리 프로토콜의 구현 ………………………………………………………………………… 338

레코드의 크기 ……………………………………………………………………………………… 339

헤더 ………………………………………………………………………………………………… 339

데이터 부분의 압축과 암호화 …………………………………………………………………… 340

구현상의 요령 ……………………………………………………………………………………… 341

4.11 DB 설계도 ……………………………………………………………………………………… 342

중요한 테이블의 설계는 프로그래밍을 시작하기 전에 …………………………………………… 342

C/S MMO에서의 DB 구현의 역사적 변천 ……………………………………………………… 343

70~80년대:데이터의 영속화 없음. 부활의 주문 ………………………………………… 343

90년대:파일로 저장 …………………………………………………………………………… 343

2000년대 전반~:RDBMS …………………………………………………………………… 345

K Online에 필요한 테이블 추려내기 ……………………………………………………………… 346

영속화가 필요한 정보와 데이터의 포함 관계 ………………………………………………… 349

데이터의 특성과 개별 테이블의 준비 …………………………………………………………… 352

DB의 성능 예측 ……………………………………………………………………………………… 353

DB의 처리 성능과 사이즈 ……………………………………………………………………… 353

테이블의 특성, 주의해야 할 테이블 …………………………………………………………… 355

발행하는 쿼리의 내용 - read편 ……………………………………………………………… 356

발행하는 쿼리의 내용 - write편 ……………………………………………………………… 357

4.12 서버/클라이언트 소프트웨어+미들웨어 실전에 빠뜨릴 수 없는 개발 기반 ……… 359

온라인 게임의 미들웨어 ……………………………………………………………………………… 359

C/S MMO용의 미들웨어 ……………………………………………………………………… 360

풀 장비형 미들웨어 ……………………………………………………………………………… 360

소규모형 MMOG 미들웨어 ……………………………………………………………………… 361

통신 미들웨어만을 이용 ………………………………………………………………………… 362

개발 기반 소프트웨어 ………………………………………………………………………………… 362

서버 관련 소프트웨어 …………………………………………………………………………… 363

클라이언트 관련 소프트웨어 …………………………………………………………………… 364

목 차

Page 15: 온라인 게임을 지탱하는 기술

4.13 프로그램을 작성할 때 기본 원칙 ……………………………………………………………… 365

프로그래밍을 시작하는 방법, 이어가는 방법 ……………………………………………………… 365

데이터 구조 우선의 원칙 …………………………………………………………………………… 366

비디오 게임에서의 데이터 분류 ………………………………………………………………… 366

데이터 구조를 구현하기 전의 검토 ………………………………………………………………… 369

적 캐릭터와 팝 설정 ……………………………………………………………………………… 369

플레이 가능 상태 유지의 원칙 ……………………………………………………………………… 371

백엔드는 나중에 만든다는 원칙 …………………………………………………………………… 372

계속적 측정의 원칙 ………………………………………………………………………………… 372

클라이언트 개발에서의 계속적 측정의 예 ……………………………………………………… 373

서버 개발에서의 계속적 측정 …………………………………………………………………… 373

4.14 C/S MMO 게임 「K Online」의 구현 프로그래밍 작업 스타트! ……………………… 375

개발의 순서 …………………………………………………………………………………………… 375

K Onilne의 분담 계획 ……………………………………………………………………………… 376

K Online에서의 「스켈레톤」과 「프로토타입」 단계 나누기 ……………………………………… 377

[스텝 1~2]스켈레톤~프로토타입 단계 …………………………………………………………… 379

스켈레톤 코드의 준비 …………………………………………………………………………… 379

autocli ………………………………………………………………………………………… 380

cli ……………………………………………………………………………………………… 381

프로토콜 ………………………………………………………………………………………… 383

ID ………………………………………………………………………………………………… 383

gmsv …………………………………………………………………………………………… 384

dbsv …………………………………………………………………………………………… 385

「작동해 보지 않으면 알 수 없다!」 ………………………………………………………………… 385

게임 개발의 난항 - 기업에 의한 온라인 게임 개발 ………………………………………… 386

스켈레톤의 전체 모습 ………………………………………………………………………………… 388

cli의 내용 ………………………………………………………………………………………… 388

gmsb, dbsv, proto의 내용 ………………………………………………………………… 390

어떤 순서로 무엇을 작성할 것인가 ……………………………………………………………… 392

먼저 프로토콜 정의 파일 k.xml를 작성한다 ……………………………………………………… 393

프로토콜 정의 포인트 ………………………………………………………………………………… 394

통신 소통 확인:ping 함수 ………………………………………………………………………… 395

어카운트 등록&어카운트 인증: …………………………………………………………………… 397

캐릭터 작성:createCharacter 함수 ………………………………………………………… 398

로그인:login 함수 ………………………………………………………………………………… 399

지상 이동:move함수, moveNotify …………………………………………………………… 400

매스 단위 …………………………………………………………………………………………… 401

경로 탐색과 실제 이동 처리 ……………………………………………………………………… 401

이동 경로를 송신하는 방법 - 최종 결과를 우선하여 송신한다 …………………………… 404

이동 결과의 통지 범위 …………………………………………………………………………… 405

목 차

Page 16: 온라인 게임을 지탱하는 기술

moveNotify 함수 ……………………………………………………………………………… 406

attack 함수, attackNotify 함수 …………………………………………………………… 409

gmsv/Makefile를 작성한다 …………………………………………………………………… 410

gmsv/climain.cpp와 gmsvmain.cpp를 샘플에서 카피 ………………………………… 410

sv.cpp에 signup 함수를 구현 ……………………………………………………………… 411

「dbsv 1회 왕복」형의 요구와 스레드…………………………………………………………… 417

자동 테스트 클라이언트 autocli의 구현 ………………………………………………………… 419

테스트 상태 변화 ………………………………………………………………………………… 419

autocli의 main() 함수 ………………………………………………………………………… 420

signup() 함수 …………………………………………………………………………………… 423

그래피컬 클라이언트 cli의 작성과 동작 확인 …………………………………………………… 428

SDL ………………………………………………………………………………………………… 428

그림을 그린다 ……………………………………………………………………………………… 429

동작 확인 …………………………………………………………………………………………… 430

폰트 처리의 구현 ………………………………………………………………………………… 431

적을 등장시킨다, 적을 뒤쫓는다 ………………………………………………………………… 431

적을 쓰러뜨린다, 경험치가 쌓인다 ……………………………………………………………… 432

다음에도 플레이 가능하게 한다 - 플레이 상태의 저장 ……………………………………… 433

스켈레톤 이후의 개발 ……………………………………………………………………………… 433

4.15 정리 ………………………………………………………………………………………………… 434

제 5 장

[실전] P2P MO 게임 개발

5.1 P2P MO 게임의 경향과 대책 …………………………………………………………………… 437

P2P MO와 액션 게임 - 게임 상태가 높은 빈도로 변화한다 ………………………………… 437

RPC형의 구현과 공유 메모리형의 구현 …………………………………………………………… 438

P2P MO 게임의 특징 ……………………………………………………………………………… 439

P2P MO 게임의 이점 ……………………………………………………………………………… 441

기획 초기부터 「멀티 플레이」를 의식한다. ………………………………………………………… 441

5.2 가공의 게임 「J Multiplayer」의 개발에서 배운다 ………………………………………… 442

J Multiplayer - K Online과 비교 ……………………………………………………………… 442

P2P MO 게임 개발의 기본적 흐름 ………………………………………………………………… 442

P2P MO 게임 개발의 성과물 - 개발의 단계와 각종 자료 …………………………………… 442

기획 상세 자료 …………………………………………………………………………………… 443

C/S MMO와의 데이터량/규모의 차이 …………………………………………………………… 444

목 차

Page 17: 온라인 게임을 지탱하는 기술

5.3 P2P MO 게임의 설계 자료 ……………………………………………………………………… 446

시스템 기본 구조도 …………………………………………………………………………………… 446

프로세스 관계도 ……………………………………………………………………………………… 447

스타형인가, 풀 메시형인가 ……………………………………………………………………… 448

우선은 스타형을 검토한다 ……………………………………………………………………… 448

게임 도중에 참가하는 구현 ……………………………………………………………………… 449

대역/머신 리소스 계산 자료 ………………………………………………………………………… 450

프로토콜 정의 자료, API 사양 ……………………………………………………………………… 450

프로토콜의 시퀀스도 ……………………………………………………………………………… 451

함수나 정수의 정의 ……………………………………………………………………………… 451

대역 소비량의 사이징 ………………………………………………………………………………… 456

「600분의 1」 - 게임 기획 내용을 정밀 조사하여 해결책을 찾는다. ……………………… 458

그 외의 자료 …………………………………………………………………………………………… 463

5.4 서버/클라이언트 소프트웨어+미들웨어, 기본 원칙 ……………………………………… 463

P2P MO 개발 성과물의 실제의 모습 ……………………………………………………………… 463

P2P MO용 미들웨어 ………………………………………………………………………………… 465

프로그램 작성 시의 기본 원칙 ……………………………………………………………………… 465

5.5 P2P MO 게임 「J Multiplayer」의 구현 …………………………………………………… 466

J Multiplayer의 작업 분담 계획 ………………………………………………………………… 466

구현 작업의 흐름 - K Online의 복습 …………………………………………………………… 467

J Multiplayer의 개발 요령 ……………………………………………………………………… 467

제1단계에 필요한 요소 ……………………………………………………………………………… 467

클라이언트 프로그램의 구현 예 …………………………………………………………………… 468

「공유 메모리형」으로 구현 - 구현 개시 …………………………………………………………… 469

경합상태 - 공유 메모리형에서의 주의점 ……………………………………………………… 469

락(Lock) …………………………………………………………………………………………… 471

P2P MO와 경합상태 …………………………………………………………………………… 472

P2P MO의 구현에서 어떤 방식으로 경합을 방지하는 것이 좋은지에 대한 판단 …………… 473

동기화 관련 구현 예 ……………………………………………………………………………… 473

가동물 열거와 클래스 설계 ……………………………………………………………………… 474

기본 동작의 취급을 매트릭스화 ………………………………………………………………… 475

게임 진행 상태를 변경하는 조작에 대한 사양 정의 ………………………………………… 475

PlayerCharacter 처리의 사양 정의 ………………………………………………………… 475

Enemy 처리의 사양 정의 Enemy/Create ………………………………………………… 476

Bullet 처리의 사양 정의 ………………………………………………………………………… 479

공유 메모리를 어떻게 코드화할까 ………………………………………………………………… 480

RPC형 - C/S MMO의 경우 …………………………………………………………………… 480

공유 메모리형 - P2P MO의 경우 …………………………………………………………… 480

RPC형의 코딩량 - move(5,5) ……………………………………………………………… 481

목 차

Page 18: 온라인 게임을 지탱하는 기술

공유 메모리형의 코딩량 - move(5,5) ……………………………………………………… 482

공유 메모리형의 강점, 약점 ……………………………………………………………………… 483

[보충]코드를 간략하게 할 수 있을까? …………………………………………………………… 483

SyncValue 클래스 ………………………………………………………………………………… 484

5.6 C/S MO 게임을 뒷받침하는 기술 [보충] …………………………………………………… 491

C/S MO와 NAT 문제 ……………………………………………………………………………… 491

NAT, NAT 문제란? ………………………………………………………………………………… 491

NAT 트래버셜 - 접속 통신로를 확립하는 기술 ………………………………………………… 492

NAT 트래버셜 기술의 한계 ……………………………………………………………………… 493

NAT 트래버셜 기술을 사용하는 경우의 또 다른 단점 ……………………………………… 493

NAT 문제의 현실적 대처 …………………………………………………………………………… 494

릴레이 서버 …………………………………………………………………………………………… 494

릴레이 서버의 트레이드오프 ………………………………………………………………………… 495

� 지연이 커지는 문제 …………………………………………………………………………… 495

서버 대역 코스트가 발생하는 문제 ………………………………………………………… 496

5.7 정리 …………………………………………………………………………………………………… 497

제 6 장

온라인 게임의 보조 시스템

6.1 보조 시스템에 요구되는 각종 기능 …………………………………………………………… 500

기존 서비스로 알아보는 보조 시스템의 기능 ……………………………………………………… 500

범용 ………………………………………………………………………………………………… 500

게임기용 …………………………………………………………………………………………… 501

웹 브라우저 베이스 게임 전용 …………………………………………………………………… 502

기존 미들웨어 ……………………………………………………………………………………… 502

기존 서비스의 기능 일람 …………………………………………………………………………… 503

Web 베이스 개발 방법과 C/S형의 개발 방법 …………………………………………………… 503

6.2 커뮤니케이션/ 통신 보조 시스템 ……………………………………………………………… 506

플레이어 매칭 ………………………………………………………………………………………… 506

P2P MO 게임에서 멀티 플레이가 가능한 조건 ……………………………………………… 507

매칭 서버 …………………………………………………………………………………………… 507

멀티 플레이를 실현하는 두 가지 조건의 구체화─J Multiplayer의 경우 ……………… 508

멀티 플레이를 실현하는 두 가지 조건의 실현─J Multiplayer의 경우 ………………… 508

매칭 결과 화면 …………………………………………………………………………………… 510

목 차

Page 19: 온라인 게임을 지탱하는 기술

로비 ……………………………………………………………………………………………………… 511

로비와 매칭 ………………………………………………………………………………………… 511

스타크래프트 II의 예 ……………………………………………………………………………… 511

구현 포인트 ………………………………………………………………………………………… 512

릴레이 서버 …………………………………………………………………………………………… 513

릴레이 서버에 요구되는 성능 …………………………………………………………………… 513

채팅 ……………………………………………………………………………………………………… 515

자작 채팅의 구현 ………………………………………………………………………………… 515

자작 채팅의 기본 동작 …………………………………………………………………………… 516

메시지 전달의 규모 ……………………………………………………………………………… 516

메일 ……………………………………………………………………………………………………… 518

친구 목록 ……………………………………………………………………………………………… 518

프레젠스 ………………………………………………………………………………………………… 519

게임 서비스의 프레젠스 특징 …………………………………………………………………… 519

프레젠스의 구현 …………………………………………………………………………………… 520

락 서버 ………………………………………………………………………………………………… 521

락 서버의 구현 …………………………………………………………………………………… 521

블랙 리스트 …………………………………………………………………………………………… 522

블랙 리스트의 구현 ……………………………………………………………………………… 522

보이스 채팅 …………………………………………………………………………………………… 523

6.3 게임 클라이언트 구현의 보조 시스템 ………………………………………………………… 524

플레이 실적 관리 ……………………………………………………………………………………… 524

플레이 실적 관리의 구현에 대해 ………………………………………………………………… 524

스토리지 기능 ………………………………………………………………………………………… 525

(게임 클라이언트) 업데이트 ………………………………………………………………………… 526

업데이트의 기본 기능 …………………………………………………………………………… 526

업데이트와 액세스 패턴 ………………………………………………………………………… 527

업데이트 기능을 자작하는 방법 ………………………………………………………………… 528

랭킹 ……………………………………………………………………………………………………… 529

랭킹 기능의 구현─온라인 게임 특유의 요구 사항 …………………………………………… 529

잠정 랭킹법 …………………………………………………………………………………………… 531

6.4 운영 보조 시스템 …………………………………………………………………………………… 531

뉴스 배포 ……………………………………………………………………………………………… 531

뉴스 전달 방법 …………………………………………………………………………………… 532

6.5 과금 결제 관련 보조 시스템……………………………………………………………………… 532

과금 인증 ……………………………………………………………………………………………… 533

온라인 게임의 과금 ……………………………………………………………………………… 533

목 차

Page 20: 온라인 게임을 지탱하는 기술

결제 처리의 구조 ………………………………………………………………………………… 533

결제 시퀀스 ………………………………………………………………………………………… 534

결제 회사를 사용하는 이점 ……………………………………………………………………… 536

버추얼 포인트 관리 …………………………………………………………………………………… 536

P2P MO의 경우, C/S MMO의 경우 ………………………………………………………… 537

버추얼 포인트 관리 서버의 구현 ………………………………………………………………… 537

버추얼 포인트 관리의 주의점 …………………………………………………………………… 538

6.6 그 외의 보조 기능 ………………………………………………………………………………… 541

게임 데이터 열람/검색 툴 …………………………………………………………………………… 541

플레이 데이터의 저장 상태 ……………………………………………………………………… 542

깔끔하지 않은 저장 상태 ………………………………………………………………………… 542

기계도 인간도 읽을 수 있는 형식으로 해 둔다 ……………………………………………… 543

키워드 검색을 위한 방법 연구 …………………………………………………………………… 543

게임 설정 데이터와 DB ………………………………………………………………………… 543

워드 필터 ……………………………………………………………………………………………… 544

6.7 정리 …………………………………………………………………………………………………… 544

제 7 장

온라인 게임 운영을 뒷받침하는 인프라

7.1 인프라 구축의 기초지식 …………………………………………………………………………… 547

C/S MMO와 P2P MO의 인프라[복습] ………………………………………………………… 547

인프라 구축에 필요한 작업 ………………………………………………………………………… 547

인프라에 소요되는 코스트와 견적 ………………………………………………………………… 548

코스트의 감각, 단위 ………………………………………………………………………………… 550

온라인 게임 서버에서 어느 정도 허용되는 조건 ………………………………………………… 550

하드웨어, 정보 기기 ………………………………………………………………………………… 551

서버 머신 …………………………………………………………………………………………… 551

스토리지 …………………………………………………………………………………………… 552

네트워크 스위치 …………………………………………………………………………………… 552

라우터/방화벽 ……………………………………………………………………………………… 552

소프트웨어 ……………………………………………………………………………………………… 553

서버 OS …………………………………………………………………………………………… 553

DBMS ……………………………………………………………………………………………… 554

바이러스 스캔 소프트웨어 ……………………………………………………………………… 554

가상화 소프트 ……………………………………………………………………………………… 555

목 차

Page 21: 온라인 게임을 지탱하는 기술

데이터 센터 관련 ……………………………………………………………………………………… 555

데이터 센터 이용료 ……………………………………………………………………………… 556

데이터 센터 구축 비용 …………………………………………………………………………… 557

서비스(데이터 센터 관련 제외) ……………………………………………………………………… 557

서버 감시 서비스 ………………………………………………………………………………… 558

도메인 사용료, 전자서명 서비스료 ……………………………………………………………… 559

회선 이용료 …………………………………………………………………………………………… 559

전기세 …………………………………………………………………………………………………… 560

7.2 개발자를 위한 인프라 구축 노하우 …………………………………………………………… 560

서비스 스케일의 확대/축소 ………………………………………………………………………… 560

일반적인 환경 ………………………………………………………………………………………… 561

사이징이 어려운 조건 …………………………………………………………………………… 561

부하 곡선 ……………………………………………………………………………………………… 562

최초에 피크가 온다는 전제로 설계한다 ………………………………………………………… 562

K Online의 경우 ………………………………………………………………………………… 563

J Multiplayer의 경우 ………………………………………………………………………… 564

개발자를 위한 인프라 구축의 포인트 ……………………………………………………………… 564

서버 디플로이먼트 …………………………………………………………………………………… 564

메인터넌스 시간과 디폴로이먼트의 자동화 …………………………………………………… 566

스테이징 ………………………………………………………………………………………………… 566

온라인 게임 고유의 주의점 ……………………………………………………………………… 567

서버 모니터링, 생사 감시 …………………………………………………………………………… 567

로그 출력/관리 ………………………………………………………………………………………… 568

로그 방침 - 「가능한 모두」 「원인과 결과 양쪽 모두」 ………………………………………… 569

로그 출력 방법 - 추천하는 방법, syslog의 문제점 ………………………………………… 569

로그 서버 …………………………………………………………………………………………… 570

7.3 K Online, J Multiplayer의 인프라 구축 ………………………………………………… 571

K Online의 인프라 ………………………………………………………………………………… 571

알파 테스트 ………………………………………………………………………………………… 571

클로즈 베타 테스트 ……………………………………………………………………………… 572

오픈 베타 테스트 ………………………………………………………………………………… 572

J Multiplayer의 인프라 …………………………………………………………………………… 573

일부 보조 시스템은 자작한다 …………………………………………………………………… 573

먼저 부하 검증을 실시하여 인프라를 사이징한다 …………………………………………… 573

동시 플레이수, 등록 유저수 - 랭킹의 경우의 일반적인 부하 검증 절차[1] ……………… 574

플레이 스타일을 예측한다 - 랭킹의 경우의 일반적인 부하 검증 절차[2] ……………… 575

부하 검증 결과를 설계에 반영시킨다. ………………………………………………………… 575

목 차

Page 22: 온라인 게임을 지탱하는 기술

7.4 부하 테스트 ………………………………………………………………………………………… 577

부하 테스트의 준비 …………………………………………………………………………………… 577

K Online의 상용 환경 부하 테스트 ……………………………………………………………… 577

K Online의 테스트 시나리오 …………………………………………………………………… 578

테스트의 분할 ……………………………………………………………………………………… 578

부하 테스트에 필요한 환경 ……………………………………………………………………… 579

부하 테스트에서 사용하는 서버 감시 커맨드 ……………………………………………………… 579

vmstat, /proc/interrupts ………………………………………………………………… 579

ps …………………………………………………………………………………………………… 583

top ………………………………………………………………………………………………… 583

netstat …………………………………………………………………………………………… 583

J Multiplayer의 상용 환경 부하 테스트 ………………………………………………………… 585

J Multiplayer의 테스트 시나리오 …………………………………………………………… 585

부하 테스트에 필요한 환경 ……………………………………………………………………… 586

7.5 운용 개시 ……………………………………………………………………………………………… 586

운용 개시 직전 - 시큐리티 설정의 확인부터 ……………………………………………………… 587

시스템 외부로부터의 공격에 대한 시큐리티 …………………………………………………… 587

시스템 내부의 관리 수단에 관한 시큐리티 …………………………………………………… 587

운용 개시 직후 - 시스템 감시 ……………………………………………………………………… 588

수십 대의 서버를 그룹화 …………………………………………………………………………… 590

트러블이 발생했을 때의 대응 ……………………………………………………………………… 592

7.6 요약 …………………………………………………………………………………………………… 593

제 8 장

온라인 게임의 개발 체제

8.1 게임의 기획 내용과 개발 팀 온라인 게임 특유의 과제 …………………………………… 596

「게임의 기획 내용」이 팀 운영의 열쇠를 쥐고 있다 ……………………………………………… 596

게임 데이터의 영속화 정도 ………………………………………………………………………… 596

운영 개시 후 3개월이 가장 힘들다. 운영은 5~10년 계속한다 …………………………… 597

게임의 운영과 기술자 …………………………………………………………………………… 597

실제의 프로젝트 관리에 있어서의 과제 ………………………………………………………… 597

게임에 있어서의 플레이어들 간의 관계 …………………………………………………………… 598

플레이 결과의 공유 범위 …………………………………………………………………………… 599

채팅 시스템의 내용 …………………………………………………………………………………… 600

목 차

Page 23: 온라인 게임을 지탱하는 기술

메인터넌스와 업데이트의 스케줄 …………………………………………………………………… 601

소스 코드의 규모 …………………………………………………………………………………… 601

빌드 시간 …………………………………………………………………………………………… 602

프로그램의 기동에 걸리는 시간 ………………………………………………………………… 603

평가를 위한 스텝 수 ……………………………………………………………………………… 603

서버 프로그램의 기동 절차 ……………………………………………………………………… 603

데이터의 밸리데이션 ……………………………………………………………………………… 603

8.2 온라인 게임 개발 팀의 실제 일반 소프트웨어 개발에도 공통되는 화제 ……………… 604

작업 분담 ……………………………………………………………………………………………… 604

온라인 게임 프로그래머의 지속적인 스킬 업 방법 ……………………………………………… 605

무예의 스텝 업 지침 「수·파·리」에서 배운다 ……………………………………………… 606

「수」의 단계 - 흉내부터 시작할 것 ……………………………………………………………… 607

「파」의 단계 - 세미나, 컨퍼런스, 그리고 경계 영역으로 뛰어들 것 ……………………… 608

「리」의 단계 - 엔지니어의 스텝 업, 그 다음에 놓여 있는 것은... ………………………… 609

프로젝트 관리방법 …………………………………………………………………………………… 609

개발 환경의 선정 ……………………………………………………………………………………… 610

프로젝트 이관 ………………………………………………………………………………………… 611

테스트 준비 ………………………………………………………………………………………… 611

개발 환경의 구축 시간은 짧다 …………………………………………………………………… 612

정보 시큐리티의 조절 …………………………………………………………………………… 612

8.3 요약 …………………………………………………………………………………………………… 613

찾아보기 ……………………………………………………………………………………………………… 620

목 차

Page 24: 온라인 게임을 지탱하는 기술

2011년 1월, 애플 앱스토어의 애플리케이션 소프트웨어 판매 다운로드 건

수가 100억 건을 넘었습니다. 그리고 구글의 안드로이드 마켓이나 크롬

웹 스토어, 아마존 앱스토어(아마존의 안드로이드 애플리케이션 마켓, 원

고 집필 시점에서 오픈 날짜는 미정), 가상통화 시스템인 페이스북 크레

딧(Facebook Credits), 온라인 게임 플랫폼인 밸브소프트웨어(Valve

Software)의 Steam 등 일반적인 오퍼레이션 시스템 대상의 애플리케이션

스토어, 결제 시스템, 게임 배포 시스템이 쏟아져 나왔고, 정식으로 오픈과

동시에 폭발적인 매출 신장을 기록하고 있습니다.

어느 애플리케이션 스토어를 막론하고 가장 다운로드 수가 많은 것은 게임

카테고리이며 판매량의 절반 이상을 게임이 점유하고 있습니다. 페이스북

같은 경우는 매출의 대부분을 게임이 차지한다고 합니다. 특히 현란한 3D

게임이나 높은 몰입도의 전쟁 게임 등이 스마트폰과 PC에서 10달러 이하

라는 값싼 가격으로 제공되고 있습니다. 몇 년 이내로 수백억, 수천억 개의

게임이 다운로드될 것입니다. 게임은 전 세계적으로 「모두 함께 어떤 것에

몰두하여 즐거운 시간을 보내고 싶다」는 인간의 기본적인 욕구를 만족시키

기 위한, 아주 저렴한 현실적 수단으로써 중요한 위치를 차지하게 된 것입

니다.

이러한 게임의 거의 대부분이 통신기능을 갖추어, 보다 리얼타임으로 보다

아름답고, 보다 방대한 데이터베이스를 활용하며, 보다 고도의 알고리즘을

사용하는 쪽으로 발전하고 있습니다.

또한, 시장규모의 확대에 따라 다양한 게임 제작 방법도 주목받고 있습니

다. 하지만, 같은 게임이라고 해도 종이를 구겨서 던지는 일인용 아이폰 게

임 paper toss와 대규모 온라인 유저가 접속하는 리얼타임 전략시뮬레이

션 게임 ‘월드 오브 크레프트(world of warcraft)’는 전혀 다른 개발 수단

을 필요로 합니다.

이 책에 대해서

Page 25: 온라인 게임을 지탱하는 기술

차량에 비유하자면 자전거와 고속철도 정도의 차이가 있습니다. 개발비와

매출액도 수만 배 이상의 격차가 있으며, 그것의 구현에 요구되는 지식도

크게 다릅니다. 따라서 「리얼타임 대규모 온라인 게임」을 개발/운영하는 것

은 유능한 인재를 끌어 모을 수 있는 큰 자본을 가진 대기업만이 가능한 실

정입니다. 반면 웹 서비스라면 한 사람의 개발자라도 수천만 명의 사용자

가 모이는 서비스를 펼쳐나갈 수 있습니다. 양쪽에 이러한 격차가 발생하

는 원인 중 하나는 온라인 게임 개발에 필요한 지식이 충분히 공유되고 있

지 않기 때문입니다.

이 책은 리얼타임 통신을 하며, 대량의 통신량을 동반하는 멀티플레이어

타입의 게임 개발에 중점을 두고 설명하고 있으며, 일반적인 스킬을 가진

프로그래머 개인이 고액의 미들웨어나 특수한 개발환경을 이용하지 않고

도 온라인 게임을 제작할 수 있도록 철저히 기초 지식을 해설하고 있습니

다. 예로 들고 있는 일반적인 코드에 대해서도 C/S MMO 게임과 P2P MO

게임의 두 가지 패턴을 기술하였습니다. 아울러, 게임의 운영이나 인프라

에 관한 화제도 소개하여 온라인 게임 개발 기술의 전체적인 면모를 살펴

볼 수 있습니다. 이 책의 내용은 프로그래머를 대상으로 설명하고 있지

만, 온라인 게임을 둘러싼 기술의 전체적인 개요를 살펴볼 수 있다는 점

에서 온라인 게임 비즈니스에 뛰어들고자 하는 게임 프로듀서나 기업 경

영자, 혹은 온라인 게임에 관심을 가지고 있는 여러분들에게 참고가 될

것입니다.

대기업뿐 아니라 개인, 벤처기업이 좀더 많은 온라인 게임을 제작하여 아

이디어 넘치는 온라인 게임이 끊임없이 개발되는 세상이 펼쳐지기를 기대

합니다.

2011년 2월 나카시마 켄고

이 책에 대해서

Page 26: 온라인 게임을 지탱하는 기술

이 책의 구성은 아래와 같습니다. 프로그래밍에 관한 해설(제0장, 제4~5

장)에서는 C 언어나 자바 등의 일반적인 프로그래밍 언어에 관한 기본적인

지식을 가지고 있는 것을 전제로 하고 있습니다. 그 외의 장(제1~3장, 제

6~8장)은 프로그래머가 아니라도 이해할 수 있는 내용입니다.

제0장 [속성] 온라인 게임 프로그래밍

네트워크와 게임 프로그래밍 기술의 기초

전업 온라인 게임 개발자와, 다른 업계의 개발자(웹 프로그래머나 사무용 애플

리케이션 프로그래머 등)의 차이점에 대해 구체적으로 소개하겠습니다.

제1장 온라인 게임의 역사와 진화

게임이 「네트워크」를 도입하다!

제2장 온라인 게임이란 무엇인가?

다양한 각도에서 보는 「온라인 게임」

제3장 온라인 게임의 아키텍처

게임의 재미와 기술적인 제약과의 싸움

온라인 게임의 역사와 배경, 비즈니스, 장르별 차이점, 아키텍처 등의 배경 지식

에 관한 내용을 정리했습니다.

제4장 [실전] C/S MMO 게임 개발

상시 가동하는 서버

제5장 [실전] P2P MO 게임 개발

전용 서버 없이 액션 게임을 구현한다

온라인 게임 대부분을 포괄하는 큰 두 가지 구현방법에 대해, 샘플 게임의

코드를 통해 개발의 흐름을 체험할 수 있습니다.

이 책의 구성

Page 27: 온라인 게임을 지탱하는 기술

제6장 온라인 게임의 보조 시스템

서비스 강화를 위해 빠질 수 없는 장치들

제7장 온라인 게임 운영을 뒷받침하는 인프라

구축, 부하 테스트, 운영 개시

제8장 온라인 게임의 개발 체제

팀 운영의 과제

온라인 게임에서 중요한 「운영」을 뒷받침하는 보조 기술과 구성방법에 대해 소

개하고 있습니다.

※ 이 책의 구성에 대해서

시중에 나와 있는 책들은 일반적으로 온라인 게임에 대한 정의→그 배경에 대한 설명→과제의 인식→해결방

법에 대한 개요 설명→샘플 프로그램 구현의 순서로 소개해 나가고 있습니다. 이 책도 기본적으로 그러한 흐

름에 맞추어 기술하지만, 온라인 게임 구현을 위한 「네트워크 프로그래밍」과 「게임 프로그래밍」에 대해서는

속성 학습을 위해 맨 앞에 배치하였습니다.

제0장에서는 책 전체의 기본이 되는 전문 용어를 가능한 망라해 놓았으므로 이 장을 먼저 살펴본다면 실제

필요한 기술에 대한 개요를 파악할 수 있습니다. 또 나중에 나오는 장에서 잘 모르는 부분이 있을 때 다시 읽

어봄으로 한층 더 이해력이 깊어지도록 구성하였습니다.

만약 독자 자신이 제0장에서 다룬 내용에 대해 거의 이해하고 있다면, 어떤 회사에서라도 온라인 게임 프

로그래머로서 바로 실전에 투입될 수 있는 능력을 가지고 있다는 뜻입니다. 하지만 정말 모르는 것들뿐이구

나…라고 느끼는 경우라도 걱정할 필요는 없습니다. 제0장 이하에서 각각의 기술이 왜 필요한가를 심도 있게

설명하였으므로, 각 장의 순서와 관계없이 모르는 부분을 찾아가며 읽기를 권합니다. 그렇게 한다면 틀림없

이 잘 이해할 수 있게 될 것입니다.

이 책의 구성

Page 28: 온라인 게임을 지탱하는 기술

이 책의 설명 중 지면의 제약으로 인해 일부는 실제로 존재하지 않는 가상

의 코드를 사용하고 있는 부분이 있습니다. 또한 실제로 작동하는 샘플 게

임(C/S MMO 타입과 P2P MO 타입의 두 종류)은 보충 정보 코너(다음 페

이지 참조)에서 내려받을 수 있습니다. 소스 코드는 어디까지나 프로그래

밍 수법에 대한 이해를 돕기 위한 것입니다. 실제 동작하는 모습의 확인이

나 이 책에 게재된 가상 코드의 참고 용도로만 사용해 주십시오.

아울러, 실제 동작하는 모습을 확인할 수 있도록 위의 두 가지 게임의 동영

상을 준비했으니 참고하기 바랍니다(조금 뒤에 나오는 ‘이 책의 보충정보

코너에 대한 안내’ 참조).

샘플 게임의 동작 환경

샘플 게임의 실행을 위해서는 아래와 같은 환경이 필요합니다. 이 모든 소프

트웨어는 라이선스 내용을 확인한 후 개인의 책임하에 사용하기 바랍니다.

• Mac OS X v10.6(Snow Leopard)

• Xcode  URL http://www.apple.com/jp/macosx/developers/

• Boost 1.41.0  URL http://www.boost.org/LICENSE_1_0.txt

• SDL 1.2.14  URL http://www.libsdl.org/license-lgpl.php

• 통신 미들웨어 VCE ※ 아래의 「통신 미들웨어 VCE 에 대해」를 참조

• 그 외 MySQL 등

※ 자세한 것은 아카이브(archive)에 동봉된 readme.txt를 참조

통신 미들웨어 「VCE」에 대해서

통신 미들웨어 「VCE」는 ㈜스퀘어 에닉스가 저작권을 포함한 지적재산

권·소유권을 가지고 있습니다. 이 책에서는 업계 기술 수준의 향상과

샘플 게임 & 동영상

Page 29: 온라인 게임을 지탱하는 기술

진흥을 위해서 이 책의 일부 범위 내에서 특별히 라이선스를 제공받고

있습니다.

책을 구입한 독자 여러분 한정으로 다음 페이지 보충정보 코너에 기재되어

있는 URL에 접속하여, 기술평론사 사이트의 부속규약에 동의하면 VCE(기

술평론사를 통한 제공판)을 사용할 수 있습니다.

그리고 이 책 샘플 게임 프로그램 아카이브(archive)에 저장되어 있는

VCE 바이너리 데이터는 프로그램 개시일로부터 일정기간(1회 기동에 최

대 한 시간 예정, 상세 내용은 readme.txt를 참조)이 지나면 통신이 불가

능해집니다. VCE를 사용하는 것에 따른 모든 손해에 대해서, ㈜스퀘어 에

닉스, 저자, ㈜기술평론사는 일체의 책임도 지지 않습니다.

※반드시 읽어주세요

• 샘플 게임 프로그램의 아카이브에 저장되어 있는 데이터 및 프로그램은 오직 이

책의 본문 내용에 관한 참조/보조자료로 사용하는 것을 목적으로 제공하고 있습

니다

• 이 책의 샘플 게임 프로그램과 데이터를 사용하여 발생한 장애, 문제점에 관해서

는 프로그램과 데이터의 제작자, 개발원/제공처, 저자, 더불어 ㈜기술평론사는 일

체의 책임도 지지 않습니다. 개인의 책임하에 사용해 주십시오.

• 수록물, 프로그램의 내용과 사용방법에 관해서, 유선상의 문의를 포함한 보조적인

사무에 관한 요구는 일절 받지 않습니다. 양해해 주십시오.

• 이 책에서 구현한 샘플 게임 프로그램 본체 소스코드는 퍼블릭 도메인으로 어떠한

제약 없이 자유로이 사용하셔도 됩니다.

• 그 외에 사용 전 주의사항에 대해서는 샘플 게임 프로그램의 아카이브의

readme.txt를 반드시 참고하기 바랍니다.

샘플 게임 & 동영상

Page 30: 온라인 게임을 지탱하는 기술

이 책의 보충정보 코너에 대한 안내

샘플 게임의 다운로드 및 동영상 안내 등은 아래 사이트를 참조하기 바랍

니다.

샘플 게임 다운로드 등 웹 지원 페이지

URL http://gihyo.jp/book/2011/978-4-7741-4580-8/support

플레이 동영상 등 스페셜 콘텐츠

URL http://gihyo.jp/magazine/wdpress/plus/978-4-7741-4580-8

※ 샘플 게임을 포함한 콘텐츠 다운로드 서비스는 예고 없이 종료될 수도 있습니다.

양해바랍니다.

감사의 말씀

이 책의 내용은 지금까지의 온라인 게임 개발 프로젝트에서, 실패를 포함

한 다양한 경험 속에서 얻어진 것입니다. 일일이 기술하지는 못하지만, 귀

중한 경험을 하게 해 주신 각 프로젝트 관계자 여러분께 감사의 말씀을 전

합니다

그리고 이 책의 샘플코드를 이용한 통신 미들웨어 VCE를 「업계 기술 수준

의 향상」을 취지로 무상 이용을 승낙해주신 ㈜스퀘어 에닉스에도 감사드립

니다.

마지막으로, 2년의 가까운 시간을 집필하면서 설 연휴까지 반납하고 작

업하거나 아이들과 마음껏 놀아주지도 못했습니다. 여러모로 가족들에

게 대단히 미안한 마음이 듭니다. 특히 아내의 깊은 배려에 감사의 말을

전합니다.

감사의 말씀

Page 31: 온라인 게임을 지탱하는 기술

이 책에서 취급하는 내용은 광범위하며 다양한 용어가 등장합니다. 책에 나오는

네트워크/게임/프로그래밍 관련 기본 용어를 보조자료로서 정리해 두었습니다.

사용되는 상황이나 문맥에 따라 차이가 나는 경우도 있지만 책의 해설 내용을 중

심으로 정리하였습니다. 이 책을 읽어나갈 때 참조하기 바랍니다. 네트워크 환경

으로는 인터넷, OS 서버로는 리눅스를 가정하고 있습니다.

16밀리초/프레임 레이트Frame Rate

래스크 주사 방식 디스플레이인 텔레비전을 사용하는 경우 비디오 게임은 일반적

으로 초당 60회로 화면을 갱신한다. 이 화면 갱신 시간이 프레임 레이트로, 1초당

60분의 1인 16밀리초(0.0167초=16.7밀리초)이다. 플레이어가 게임의 상황 변화를

인식할 수 있는 가장 짧은 시간 간격이다.

ARPGAction Role Playing Game

RPG 중 액션감이 있는 리얼타임 게임 또는 어드벤처 게임의 특징을 가지는 게임을

말한다.

Bot

봇. 게임 플레이어로 가장하여 자동으로 게임 서버에 접속하여 효율적인 플레이를

통해 단기간에 높은 스코어를 쌓는 등 악질적인 경제활동을 하는 프로그램. 테스

트 봇은 게스트를 자동화하기 위해 개발자가 준비한 자동 테스트 클라이언트 프로

그램을 말한다.

CPU 사이클CPU Cycle

CPU가 동작하는 최소 단위. 1GHz의 CPU는 1초당 10억 사이클이며, 1사이클에

서 실행 가능한 명령은 1초당 10억 회다. 명령의 종류에 따라 실행에 필요한 사이

클 횟수는 1미만에서 수백까지로 그 차이는 크다.

FPSFirst-Person Shooter

주인공의 시점에서 플레이하는 슈팅 게임의 한 장르.

기본 용어 정리

Page 32: 온라인 게임을 지탱하는 기술

I/OInput/Output

입출력. 네트워크 I/O, 디스크 I/O 등 서버 프로그램의 I/O는 대부분 네트워크 I/

O이다.

MMOMassively Multiplayer Online

이 책에서는 대규모의 사용자를 가진 멀티플레이어 참가형의 온라인 게임을 말한

다. MMOG.

MOMultiplayer Online

이 책에서는 비교적 소수를 대상으로 하는 멀티플레이어 참가형의 온라인 게임을

말한다. MOG.

ROGRemote Procedure Call

원격 절차 호출. 다른 컴퓨터의 서비스(함수 등)를 불러오는 것. 예를 들면 클라이

언트로부터 서버로 명령하여 그 결과를 받아올 경우 사용한다.

RPGRole Playing Game

게임 설정에 따라 플레이어가 캐릭터의 역할을 연기하는 게임

TCPTransport Control Protocol

인터넷 전체를 뒷받침하는 데이터 전송을 위한 통신 규격. 필요에 따라

IP(Internet Protocol) 패킷을 재전송하여 큰 데이터를 보내는 것이 가능하다. 그

대신에 느린 링크에서 속도를 내기 위해서는 대량의 메모리가 필요하다.

월드 오브 크래프트World of Warcraft

과거 5년 이상 동안, 전 세계 시장 점유율 최고를 독점하고 있는 Blizzard

Entertainment 사의 MMORPG. 등록된 사용자는 1200만, 동시접속 수는 중국에

서만 100만을 자랑한다.

이벤트 구동Event Driven

이벤트가 발생한 타이밍에 처리를 진행하는 프로그래밍 방식. 이벤트 종류의 예를

기본 용어 정리

Page 33: 온라인 게임을 지탱하는 기술

들면, 「데이터가 전송되었을 때」 「마우스가 움직였을 때」 등이다. 네트워크 프로그

래밍이나 게임 프로그래밍에서는 이벤트 구동 방식의 프로그램을 많이 이용한다.

영속성Persistent

게임 데이터에서의 영속성은 게임 플레이에 필요한 시간의 길이이다. 다시 말해,

게임 진행에 필요한 시간의 길이가 어느 정도인가를 나타낸다. 레이싱 게임 등은

수분 이내에 사용되고 버려지는 데이터가 중심이 되기 때문에 영속적이지 않으며

데이터의 비축성이 낮다. 그러나 MMORPG와 같이 멈추지 않고 계속되는 게임은

영속적이며 게임 데이터의 비축성이 높다. 영속성에 따라 데이터를 어떠한 형식으로,

어떠한 미디어에 보존할 것이며, 그것을 어떻게 이용할 것인가 등의 차이가 난다.

온 메모리on Memory

CPU가 수 클럭, 즉 수 나노초~수백 나노초 사이에 정보를 취득할 수 있는 거리인

메모리에 데이터가 올라가 있는 상태.

캐시Cache

데이터를 고속으로 꺼내오기 위해 일시적으로 다른 장소에 보존해 두는 것. 예를

들어 디스크 액세스는 느리기 때문에 파일의 내용을 메모리상에 배치해 두면(캐시

해 두면), 고속으로 데이터를 꺼낼 수 있다. CPU 캐시, 캐시 메모리, 브라우저 캐

시, 캐시 서버 등 여러 가지 레이어에서 활용되고 있는 장치.

경합 상태Race Condition

하나의 자원(메모리 등)을 둘 이상의 이용자(처리, 프로세스 등)가 동시에 이용하

려 할 때 발생하는 프로그램의 상태를 가리킨다. 데드락(Dead Lock, 처리결과를

서로 기다리는 고착 상태) 등의 문제를 야기한다.

공유 메모리Shared Memory

메모리 내용을 복수의 프로세스가 공유한다. 구체적으로는 움직이는 물체의 좌표

나, 이동 방향 등의 상태를 공유.

기본 용어 정리

Page 34: 온라인 게임을 지탱하는 기술

클라우드Cloud

클라우드 컴퓨팅(Cloud Computing)에서 주로 서버 측 컴퓨터 망을 말한다. 단

순한 서버 머신의 호스팅 서비스뿐 아니라 스토리지나 부하 분산, 과금 시스템, 로

그 분석 등 서버 구축에 필요한 모든 컴퓨터 관련 리소스를 필요 시에 유연하며 빠

르게 조달할 수 있다. 매우 편리하지만, 중요한 기밀정보나 개인정보를 클라우드

운영회사에 건네줘야 한다는 단점이 있다.

게임 클라이언트Game Client

플레이어가 소유한 PC나 게임기 등에서 플레이어에 의해 기동되어 게임의 묘사

나 입출력 처리를 수행하는 소프트웨어. 고성능의 묘사나 입출력을 필요로 하는

ARPG, 또는 3D 표현을 처리하는 MMORPG 등의 온라인 게임에서는 전용 게임

클라이언트를 개발한다. 게임 단말 소프트웨어 짧게 단말 소프트웨어라고도 불린

다. 「브라우저」 참조

게임 로직Game Logic

웹 애플리케이션의 비즈니스 로직에 해당됨. 게임 진행 정보 및 유저인터페이스

정보들을 서로 연결하는 알고리즘을 가리킨다.

다중화Redundancy, 리던던시

예비로 여러 개를 준비하는 것. 게임 데이터의 다중화란 데이터를 가까운 곳과 먼

곳, 복수의 장소에 복사하여 보관하는 것을 말한다(마스터, 복사본의 관계).

스케일러블Scalable

시스템의 성능 확장이 가능한 상태. 온라인 게임에서는 플레이어의 증가나 포화

상태에 대비하여 손쉽게 성능이나 기능을 확장할 수 있는 것이 바람직하다.

스케일업/스케일아웃Scale-up/Scale-out

스케일업이란 메모리의 증설과 CPU의 교환 등 1대의 서버를 강화하는 것으로 시

스템의 성능을 올리는 방법. 스케일아웃이란 서버의 대수를 늘려서 시스템의 성능

을 올리는 방법을 말한다. 단일 서버의 성능에는 한계가 있기 마련이므로 대규모

온라인 게임에서는 서버의 대수를 늘리는 스케일아웃 구성이 바람직하다.

기본 용어 정리

Page 35: 온라인 게임을 지탱하는 기술

스프라이트Sprite

비디오 게임에서 작은 이미지를 고속으로 표시하기 위한 방법. 플레이어 캐릭터의

이동 등을 위해 작은 이미지를 준비하고 표시 위치를 지정하여 화면상에 묘사한다.

스루풋Throughput

시스템이 일정시간 수행할 수 있는 처리량. 예를 들어, 1초에 1000의 처리를 수행할

수 있는 시스템은 100밖에 처리할 수 없는 시스템보다 스루풋이 높다고 말한다.

스레드Thread

프로세스에 의해 세분화된 프로그램의 실행 단위. 리소스 공유에 있어 대개의 경

우 프로세스 간보다 스레드 간의 연계처리가 더 쉽다. 단일 스레드를 가지고 처리

를 수행하는 방법을 싱글 스레드(Single Thread), 복수의 스레드를 동시에 사용

하여 처리를 수행하는 방법을 멀티 스레드(Multi Thread)라고 부른다.

소켓 APISocket API

네트워크에 관련된 파일 디스크립터(file descriptor)인 소켓을 다루는 API. 개별

함수/시스템 콜(socket, connect, accept) 등에 관해서는 제0장을 참조한다.

대역Bandwidth

온라인 게임 개발에서 네트워크를 경유하여 데이터 전송을 수행하는 전송률을 가

리킨다. 대역폭(밴드폭)이라고도 함.

데이터 센터Data Center

서비스를 제공하기 위한 서버 기기 등을 수용하는 시설. 서버 보관 유지에 필요한

전원, 적당한 온도 및 습도, 천재지변에 대한 대책이 마련되어 있다.

디플로이Deploy

애플리케이션 프로그램의 배치. 서버 디플로이먼트는 다른 버전의 서버 프로그램

을 각 서버 머신에 인스톨하여 버전을 변경하는 일련의 작업을 말한다.

기본 용어 정리

Page 36: 온라인 게임을 지탱하는 기술

동시 접속수Number of Simultaneous Connections

서비스에 동시 접속 가능한 사용자 수. 게임의 기획 단계에서는 최대치로서의 동

시 접속수를 산출해 둔다. 한편, 운용 중에는 주로 접속수의 스냅샷을 가리킨다.

네트워크 접속에서 말하는 커넥션(connection) 수와는 구별된다.

네트워크 토폴로지Network Topology

네트워크에 포함되어 있는 각 컴퓨터가 어떠한 구조로 배치되어 있는지를 나타내

는 개념. 컴퓨터는 노드, 접속은 엣지라고 부른다. 스타형, 버스형, 링형 등의 각종

구조에 명칭을 부여하고 네트워크 구조 분석에 사용할 수 있으며 네트워크의 구조

설계를 돕는다.

패킷Packet

데이터의 전송 단위. 패킷 통신의 원리는 데이터를 분할하고 제어 정보 등을 부가

하여 전송하는 것이다. TCP에서 데이터 송신 단위는 세그먼트(Segment)이고,

UDP/IP에서는 데이터그램(Datagram)으로 불리기도 한다. 온라인 게임 개발은

결국 네트워크 패킷 지연과의 싸움이다.

파일 디스크립터File Descripter

유닉스 운영체제에서는 파일뿐 아니라 네트워크나 블록 디바이스 등 OS하에 입출

력 가능한 다양한 리소스를 파일처럼 취급한다. 프로그램에서는 파일 디스크립터

로서 정수(C 언어에서는 int형)를 할당 사용하여 데이터의 입출력을 실시한다. 파

일 디스크립터를 통해서 파일의 입출력과 같은 방법으로 네트워크의 입출력도 행

해진다. 파일 기술자라고도 불린다.

부하Load

CPU나 네트워크 등에 걸리는 일의 양. 예를 들어, 복잡한 계산을 대량으로 실시

하는 처리는 CPU의 부하가 높다. 대량의 데이터를 송수신하는 처리도 마찬가지

다. CPU 부하, I/O 부하, 서버 부하 등 다양한 상황에서 사용된다.

기본 용어 정리

Page 37: 온라인 게임을 지탱하는 기술

부하 분산Load Balancing

부하를 분산시키는 것. 예를 들어, 한 대의 데이터 베이스 서버로 처리하지 못하는

부하는 여러 대로 분산시켜 대응한다.

브라우저Browser

열람을 위한 소프트웨어. 서버 측에서 관리되고 있는 게임의 진행 정보를 플레이

어가 열람하는 소프트웨어다. 예를 들면, 3D 게임을 위해 C++ 등의 언어를 이용

해 개발된 전용 애플리케이션이나 플래시 게임을 위해 구글 크롬 등의 웹 브라우저

상에서 동작하는 애플리케이션을 가리킨다. 웹 서버로부터 보내오는 데이터를 열

람하기 위한 일반적인 웹 브라우저와는 다른 것이다. 「게임 클라이언트」 참조.

프로세스Process

OS에서 움직이고 있는 프로그램은 프로세스라고 하는 개념에 의해 다른 프로그램

과 분리되어 독립적으로 움직인다. 각 프로세스들이 관장하는 리소스(메모리나 소

켓 등)는 서로 분리되어 있다.

프로세스 간 통신Inter-Process Communication

복수의 프로세스 간에 통신하는 것. 각 프로세스가 할당된 어드레스 공간을 넘어

서, 다른 프로세스와 데이터를 교환하거나 공유하는 구조.

블로킹/논블로킹Blocking / Non-Blocking

블로킹이란 처리가 끝날 때까지 기다리는 것을 말한다. 예를 들어, 데이터가 들어

올 때까지 기다리는 프로그램(블록하는 프로그램)에서는 그 사이에 다른 처리를

수행할 수 없다. 이 문제를 해결하기 위해서는 논블로킹(계속 기다리지 않는다)으

로 하면 된다. 동기적 호출, 비동기적 호출로 불리기도 한다.

병렬Parallel

물리적으로 처리를 병렬화하여 복수의 처리를 동시에 실시하는 것. 덧붙여 병행

(Concurrent)이란 시분할방식 등을 이용하여 처리가 병렬로 이루어지고 있는 것

처럼 보이게 하는 것까지도 포함한다. 병렬화에 의한 속도 향상은 어렵기 때문에

기본 용어 정리

Page 38: 온라인 게임을 지탱하는 기술

기본적으로 프로세서의 계산 능력을 고려하여 기획 내용 자체를 재검토하거나 알

고리즘의 개선을 통해 계산량을 줄이는 것이 중요하다.

보조 시스템Additional System

게임 내용과 다른 보조적인 기능을 제공하는 시스템. 플레이어 매칭, 플레이 실적

관리(스코어 관리), 랭킹, 커뮤니케이션 기능 등이 있다. 대부분 서드파티 제공의

패키지 및 서비스를 이용할 수 있다.

보틀넥Bottleneck

시스템에서 제일 약점이 되는 부분. 다른 부분이 아무리 빨라도 하나의 늦은 부분

(보틀넥)이 있는 것만으로 전체가 느려지는 경우도 있다.

폴링Polling

데이터의 송신과 이벤트의 유무를 확인하는 것. 폴링을 너무 많이 하면 CPU에 불

필요한 부하가 걸린다.

멀티프로세스 프로그래밍Multi-Process Programming

복수의 프로세스를 활용한 프로그래밍. 복수의 프로세스를 동시에 실행함으로 멀

티 코어 CPU의 처리 능력을 유효하게 활용할 수 있다.

미들웨어Middleware

애플리케이션에서 사용하는 범용적인 기능을 집약하여 특화한 패키지 소프트웨

어. 통신 등의 유연성과 성능이 요구되는 처리를 패키지화하는 것으로, 개별 작업

의 번거로움을 줄이고 API를 통해 고도의 기능을 이용할 수 있게 한다.

레이턴시Latency

처리 소요 시간. 예를 들어, 플레이어가 키를 누르고 그 조작이 화면에 반영될 때

까지 1초나 걸리는 게임은 레이턴시가 나쁜 것이라 할 수 있다. 다양한 상황에서

사용되는 용어이며, 대체로 CPU 액세스 레이턴시는 나노초, 메모리 액세스는 수

십~수백 나노초, SSD 액세스는 수백 마이크로초, 하드 디스크 액세스는 수십 밀

리초, 네트워크는 밀리초~초 단위이다.

기본 용어 정리

Page 39: 온라인 게임을 지탱하는 기술

39

제 0 장

[속성] 온라인 게임 프로그래밍네트워크와 게임 프로그래밍 기술의 기초

Page 40: 온라인 게임을 지탱하는 기술

온라인 게임 구현을 위해서는 크게 아래의 두 가지 스킬이 필요합니다. 아무리 분업 체제로

이루어져 있다고 해도 양쪽 모두를 어느 정도 이해해 두는 것이 바람직합니다.

• 네트워크 프로그래밍(Network Programming)1

• 게임 프로그래밍(Game Programming)

제0장에서는 본편의 이해를 돕기 위해 온라인 게임 개발에 필요한 「네트워크 프로그래밍」

및 「게임 프로그래밍」의 기초 개념을 설명합니다. 이 장의 순서는 아래와 같습니다.

• 온라인 게임 프로그래머를 위한 네트워크 프로그래밍의 기초

• 소켓 프로그래밍 입문

• RPC의 공략

• 게임 프로그래밍의 기초

이 장의 0.1~0.3절은 네트워크 프로그래밍을 다루고 있습니다. 네트워크 프로그래밍 요점

을 정리한 것이 그림 0.A입니다. 우선 그림 0.A의 요점을 머릿속에 잘 새겨두기 바랍니다.

자, 그럼 다음 페이지로 넘어가 보겠습니다.

그림 0.A 온라인 게임 시스템의 레이어

레이어 7애플리케이션 층

레이어 6프레젠테이션 층

레이어 5세션 층

레이어 4트랜스포트 층

레이어 3네트워크 층

레이어 2데이터링 층

레이어 1물리층

게임 통신 프로토콜 전체

(RPC로 전송하는) 게임 데이터의직렬화 방식

통신이 중단되면 재접속한다

TCP(UDP)

IP

무선 LAN, 기가비트이더넷(Gbit Ethernet)

안테나 및 트위스티드페어 케이블(twisted-pair cable)

제4장, 제5장에서 해설

소켓 프로그래밍(이 장 전반부)

레이어 4이하의 처리/조작은 기본적으로 OS에 맡긴다.

1 「온라인 프로그래밍」이라고 부르지는 않습니다.

Page 41: 온라인 게임을 지탱하는 기술

0.1 네트워크 프로그래밍의 기초 41

0.1

[온라인 게임 프로그래밍을 위한]

네트워크 프로그래밍의 기초

우선 온라인 게임 프로그래밍에 필요한 네트워크 프로그래밍의 기초 지식을 살펴봅니다.

네트워크 프로그래밍은 필수(!)

온라인 게임 구현에서는 네트워크를 통해 상대방(호스트)과 데이터를 주고 받는 처리가 중요

합니다. 통신, 즉 「원격지 간의 데이터 입출력」을 위한 네트워크 프로그래밍이 필수입니다.

온라인 게임용 통신 미들웨어(네트워크 미들웨어)를 이용하면 번거로운 작업은 많이 줄어

듭니다. 그러나 그 내부를 이해하고 있어야만 미들웨어의 기능을 활용하여 디버깅 효율을

높일 수 있습니다. 따라서 네트워크 프로그램을 직접 작성하지는 않더라도 이해는 해 둘 필

요가 있습니다. 또한 기초 기술을 숙지하고 있는 편이 이 책의 내용을 이해하는 데 도움될

것입니다.

하지만 온라인 게임에 직접 적용할 수 있을 정도의 네트워크 프로그래밍의 기본적인 부분

을 다루고 있는 책은 시중에서 잘 찾아 볼 수 없었습니다. 이 장에서는 온라인 게임에 필요

한 부분에 초점을 맞추고 네트워크 프로그래밍의 기초적인 지식을 다루겠습니다. 이 분야

는 기초를 잘 알아두면 응용도 가능하므로 정확하게 이해하고 넘어갑시다.

네트워크 프로그래밍, 인터넷 프로그래밍

네트워크 프로그래밍은 2대 이상의 독립된 머신상에서 실행되는 프로세스들 간의 통신을

수행하기 위한 프로그래밍 기법을 말합니다.

한마디로 네트워크 프로그래밍은 무척이나 폭넓은 내용을 포함합니다.

예를 들어 USB를 사용하여 외장 HDD(Hard Disk Drive, 하드디스크 드라이브)를 PC에

연결한 경우에도, PC에서 동작하고 있는 프로세스와 HDD의 컨트롤러상에서 동작하고

Page 42: 온라인 게임을 지탱하는 기술

42 제0장 _ [속성] 온라인 게임 프로그래밍

있는 프로세스끼리 통신하고 있는 셈입니다. 따라서 네트워크 프로그래밍이 필요합니다.

SCSI(Small Computer System Interface), 적외선 통신, 에어컨의 리모콘에 이르기까지

폭넓은 네트워크 프로그래밍이 존재합니다.

온라인 게임에서는 닌텐도 DS끼리 유선으로 연결하는 경우 등을 제외하고는 네트워크 프

로그래밍 중 인터넷과 관련한 것만 사용합니다. 이러한 인터넷의 통신 프로그래밍은 「인터

넷 프로그래밍(Internet Programming)」이라고 불리며, 해외에서는 서적 등의 참고 정보

를 접할 수 있습니다.

불특정다수가 참가하는 온라인 게임은 인터넷 이용을 전제로 하기 때문에 이 책에서도 인

터넷 프로그래밍에 초점을 둔 네트워크 프로그래밍만을 다루겠습니다.

인터넷 프로그래밍의 역사와 사상

인터넷 통신 방식의 주류인 IP(Internet Protocol), TCP(Transmission Control

Protocol), UDP(User Datagram Protocol) 등의 프로토콜(Protocol, 통신규약)이 정

의되고 난 후 30년 동안 기본적 통신방식은 변하지 않았습니다. IP를 시작으로 인터넷을

안전/쾌적하게 이용하기 위한 프로토콜은 기술표준화단체(IETF, Internet Engineering

Task Force)가 발간하는 RFC(Request For Comments, 인터넷 RFC)2에 기초하고 있습

니다. 이것에는 법적 강제성은 없습니다. 규약을 엄수하는 것이 경제적인 이익과 연결되므

로 많은 사람들이 그것을 따르게 된 것입니다.

RFC에는 번호가 매겨져 있습니다. 예를 들어 TCP의 구현은 RFC 793, DNS(Domain

Name System)의 구현은 RFC 1123, HTTP(HyperText Transfer Protocol)의 구현은

HTTP/1.0이 RFC 1945에 정의돼 있으며 버전이 올라갈 때마다 RFC 번호도 갱신됩니다.

이 책의 집필 시점(2010년9월)에는 그 수가 6000을 넘었습니다.3

IETF의 RFC는 통신 형식이나 프로토콜의 사양을 공유하기 위한 것입니다. 실제의 프로그

래밍 인터페이스 정의와는 관계없으므로, 네트워크 프로그래밍을 시작하기 위해서는 더 많

은 기초 지식이 필요합니다.

2  URL http://www.ietf.org/rfc.html

3  즉, RFC 1( URL http://www.rfc-editor.org/rfc/rfc1.txt)은 단 2개의 호스트 사이를 시리얼 케이블로 연결하는 단순한 것인데, 이것이 인터넷

의 시작점이라는 생각이 듭니다.

Page 43: 온라인 게임을 지탱하는 기술

0.1 네트워크 프로그래밍의 기초 43

OSI 참조 모델

규격이나 하드웨어의 변경을 투과적으로 처리하고 싶다

가령 좀더 고속인 1Tbit(Terabit) 이더넷이라는 새로운 규격이 등장하는 경우, 그때마다 애

플리케이션을 다시 프로그래밍하는 것은 너무 번거롭습니다. 네트워크 전체에서 방대한 종

류의 기기가 사용되기 때문에 가능한 투과적으로(차이를 흡수한 형태로) 처리하고 싶다는

요구가 생겨납니다.

과거에는 이러한 변경에 대응하기 위해 매번 프로그램을 수정했습니다. 그러나 네트워크에

참가하는 호스트 수가 늘어남에 따라 1980년대 미국에서 비용을 줄이기 위해 표준화된 모

델을 정의하자는 운동이 일어났습니다.

그 성과가 OSI 참조 모델(OSI Reference Model)입니다. OSI 참조 모델을 기반으로 해서

설계를 해 두면 규격이나 하드웨어가 변경되어도 그것보다 높은 상위 레이어(Layer, 층)는

크게 수정할 필요가 없다는 장점이 있습니다. 통신 시스템은 「상대방이 있는」 시스템이므로

가능한 한 상대방에게 영향을 주지 않고 자기 자신만을 수정할 수 있는 설계가 필요합니다.

OSI 참조 모델로 일곱 계층의 모델을 제시하여 각 기능을 설명하겠습니다.

레이어7: 애플리케이션층

구체적인 통신 서비스(파일/메일의 전송, 원격 데이터베이스 액세스 등)을 제공. HTTP나 FTP(File

Transfer Protocol) 프로토콜 등이 있다.

레이어6: 프레젠테이션층

데이터의 표현 방법을 정함(예를 들어 EBCDIC4의 텍스트 파일을 ASCII 코드의 파일로 변환하는

것 등)

레이어5: 세션층

통신 프로그램 간의 통신 개시부터 종료까지의 순서를 정함(접속이 도중에 끊어진 경우 접속 회복을

시도한다).

레이어4: 전송층

네트워크의 끝에서 끝까지 통신 관리를 한다(에러 정정, 재송신 제어 등).

4 Extended Binary Coded Decimal Interchange Code. 메인 프레임에서 사용되는 문자 코드

Page 44: 온라인 게임을 지탱하는 기술

44 제0장 _ [속성] 온라인 게임 프로그래밍

레이어3: 네트워크층

네트워크 통신 경로의 선택(라우팅). 데이터 중계

레이어2: 데이터 링크층

직접적(인접적)으로 접속되어 있는 통신 기기 간의 신호를 전달

레이어1: 물리층

물리적 접속을 정함. 커넥터의 핀 수, 커넥터 형태의 규격 등. 구리선, 광케이블 간의 전기신호의 변

환 등

OSI 참조 모델은 기술 표준으로서의 구속력은 없지만, 기술자의 이해를 돕기 위한 지침이

됩니다. 기술자와 기업에 있어 OSI 참조 모델에 의거해 제품을 설계하는 것이 이익이 되는

경우도 있었기 때문에 자연적으로 보급되었습니다.

OSI 참조 모델과 같이 상위 계층과 하위 계층에 같은 인터페이스를 제공하는 한, 그 사이

의 요소를 교환한다고 해도 시스템은 지금처럼 동작할 것입니다.

온라인 게임 시스템과 레이어

이 장 첫머리의 그림 0.A(40쪽)를 한 번 더 살펴보기 바랍니다. 온라인 게임 시스템을 OSI

참조 모델을 참고로 정리하면 그림0.A와 같은 레이어로 나눌 수 있습니다.

레이어4는 대부분의 경우 TCP를 사용하고,

레이어3 이하는 직접적인 조정이 필요 없음

인터넷상에서 애플리케이션끼리 통신하기 위한 레이어4(트랜스포트층)의 프로토콜은 TCP

와 UDP가 사실상의 표준입니다. 송수신의 순서나 정확성을 실현하기 위해서는 TCP를, 그

러한 기능이 필요 없는 경우는 UDP를 이용합니다.

한편 온라인 게임에서는 꼭 필요한 경우만 UDP를, 「그 외의 경우는 모두 TCP」를 사용합니

다. TCP와 UDP의 기능이 있으면 그 이상의 섬세한 작업을 할 필요성이 없어지기 때문에

레이어4보다 하위 레이어(3~1)를 직접 조정하지 않아도 되고, 운영체제에 맡겨버릴 수도

있으므로 문제가 생기지 않습니다.

다만 성능을 최대한 높이고자 할 때 레이어3 이하 레이어에서 몇 가지 주의해야 할 점이 있

는데, 그것은 다음 절 후반부에서 다루겠습니다.

Page 45: 온라인 게임을 지탱하는 기술

0.1 네트워크 프로그래밍의 기초 45

레이어5 이상은 게임단에서 구현한다

온라인 게임에 있어서는 레이어5나 레이어6의 사실상의 표준과 맞바꿀 만한 프로토콜이 존

재하지 않습니다. 따라서 일반적으로 레이어5 이상은 온라인 게임의 개발자가 모두 구현해

야만 합니다. 아직 일반화되지 않는 이유는 게임 장르나 기획 내용에 따라 요구되는 부분이

미묘하게 다르기 때문입니다. 단, 온라인 게임용의 통신 미들웨어를 사용하면 처음부터 모

든 것을 개발하지 않아도 되기 때문에 많은 수고를 줄일 수 있습니다.

이후에서는 소켓 API나 소켓 프로그래밍의 기본, 소켓 API를 사용한 게임 전용 통신 미들

웨어의 구현을 소개하겠습니다.

소켓 API의 기초 지식

BSD 소켓 API(소켓 API)5는 인터넷 접속을 위한 API로, 임베디드 기기를 포함한 모든

OS 중 첫 번째 후보입니다. TCP/IP를 사용하기 위한(BSD 소켓은 아님) API는 셀 수 없을

만큼 많지만, 현재 온라인 게임에서 제공되는 환경(게임기를 포함)에서는 모두 소켓 API를

이용할 수 있습니다.

C 언어의 인터페이스가 표준화되어 있고, 자바나 루비, Perl, C# 언어 등도 API를 이용할

수 있습니다.6 소켓 API의 사용이 일반화된 것은 1980년대이고 그 이후에도 소켓 API의

사양은 기본적으로 변하지 않았습니다. 따라서 그 무렵에 만들어진 프로그램이 아직 작동

하고 있습니다.

지면이 부족한 관계로 소켓 API에 대해 반드시 필요한 부분만 기술해 놓았습니다. 자세히

알고 싶은 분들은 인터넷이나 시중의 책을 참고해 주십시오.7 추천 도서로는 앞서 기술한

IETF의 인터넷 사양, OSI 참조 모델 그리고 소켓 API 등 인터넷 여명기에서부터의 역사나

통신의 기초적인 이론까지를 총 망라한 네트워크 프로그래밍에 관한 바이블인 「UNIX 네트

워크 프로그래밍」 시리즈가 있습니다.8 이 책은 소켓 API의 샘플도 충실하게 수록되어 있

고 그 내용도 온라인 게임에서 실제 사용되고 있는 것입니다. 대부분의 온라인 게임 개발

팀의 책장에 꽂혀있는 책이라고 해도 과언이 아닐 것입니다.

5 ‘버클리 소켓’, 그냥 ‘소켓’ 등으로 불립니다.

6 C 언어가 아닌 언어(자바나 액션스크립트)는 소켓 API를 직접 호출하는 것은 아니지만, 소켓의 동작을 모방한 API를 이용하게끔 되어 있습니다.

7  URL http://x68000.q-e-d.net/~68user/net/, URL http://www.few.vu.nl/~jms/socket-info.html

8 「Unix Network Programming 3ed」(W. Richard Stevens 저, Addison-Wesley, 2003) 참고

Page 46: 온라인 게임을 지탱하는 기술

46 제0장 _ [속성] 온라인 게임 프로그래밍

온라인 게임과 소켓 API레이어4의 소켓 API를 사용한다

소켓 API를 사용하면 임의의 레이어1~2(물리층~데이터링크층)의 위에 구현된 IP와 한 단

계 더 위에 구현된 UDP, TCP, ICMP(Internet Control Message Protocol) 등 레이어4

의 상위 프로토콜을 제어할 수 있습니다. 소켓 API에는 IP를 직접 조작하는 레이어3의 API

와 TCP를 사용하는 레이어4의 API가 있습니다. 온라인 게임에서 사용하는 것은 「레이어4

의 소켓 API」뿐입니다.

커넥션 지향(스트림형), 커넥션리스 지향(데이터그램형)

인터넷의 기초인 레이어3 IP는 네트워크 경로를 타고 패킷이 중계되는 도중, 라우터의 처

리 능력 부족이나 통신 폭주 등으로 패킷이 사라져 버린 경우라도 패킷을 재발송하지 않습

니다. 그렇기 때문에 신뢰성이 없습니다. 또 패킷의 도착 순서도 보증하지 않습니다. 단, 패

킷 수신에 성공했다면 그 내용이 달라지는 경우는 없습니다.9

이렇듯 신뢰성이 보장되지 않는 레이어3 위에서 레이어4인 소켓 API을 사용하면, 호스트

와 호스트 사이에서 지속적인 통신로를 유지하며 통신을 계속하는 「커넥션 지향」(스트림형,

STREAM)의 통신과 1회의 패킷 데이터 교환만을 실행하고 통신로를 유지하지 않는 「커넥

션리스 지향」(데이터그램형, DGRAM)의 통신이 가능합니다.

IP상에 구현되어 있는 커넥션 지향(스트림형)의 프로토콜은 TCP이며, 이 TCP를 사용하는 상

위 애플리케이션으로 대표적인 것이 HTTP나 SSH(Secure Shell)입니다. HTTP나 SSH는 장시

간에 걸쳐서 순서가 보증되는, 확실성이 높은 데이터 통신이 필요하기 때문입니다.10

한편 커넥션리스 지향(데이터그램형)의 대표적인 프로토콜은 UDP입니다. 이것은 IP의 패

킷 하나의 사이즈보다 큰 단위의 데이터그램이 송신되면 분할 송신을 실시하고 수신하는

쪽에서 그것을 복원하는 기능만을 가지고 있습니다. 하지만 데이터그램의 도착 순서나 확

실한 도착을 보증하지 않는다는 점에서 IP와 기능 차이가 거의 없습니다. UDP를 이용하는

대표적인 애플리케이션으로서 DNS 질의가 있습니다.

9 오류 정정은 레이어2 이하에서 보증되고 있기 때문입니다.

10 만약 HTML(HyperText Markup Language)의 순서가 변하면 태그의 전후 관계가 엉망이 되고 맙니다.

Page 47: 온라인 게임을 지탱하는 기술

0.1 네트워크 프로그래밍의 기초 47

● ● ●

온라인 게임에서는 TCP도 UDP도 모두 사용하지만 「게임에 참가하는 호스트끼리 계속 통

신」을 하기 위해 기본적으로 커넥션지향 프로토콜인 TCP를 사용합니다.11 앞으로의 설명

에서도 TCP를 전제로 한 소켓 통신 프로그램으로 예를 들겠습니다.

Column

특성과 게임 형식의 관계 서버, 클라이언트에 요구되는 성능/기능

어떠한 네트워크 프로그래밍 기술이 필요한지 알기 위해서 네트워크 프로그래밍의 특성과 게임 형식의 관

계를 간단하게 살펴보겠습니다. 필요한 네트워크 프로그래밍의 특성은 게임 형식마다 다릅니다. 예습도 겸

해 제2장에서 소개할 「C/S MMO」 「C/S MO」 「P2P MO」를 예로 들어봅시다(위의 구분에 대해서는 159쪽

의 표 2.4를 참조).12 각각 다음과 같은 차이가 있습니다.

C/S형 게임(C/S MMO, C/S MO)

고성능/고기능 서버 프로그래밍×일반적 클라이언트 프로그래밍. 서버에서 모든 처리를 하고, 한 대의 서

버 머신으로 가능한 많은 유저를 받아 들일 필요가 있다. 그 반면, 클라이언트 측의 통신은 단순하다.

P2P형 게임(P2P MO)

일반적(웹) 서버 프로그래밍×고성능/고기능 클라이언트 프로그래밍

보조적인 기능 이외의 게임을 처리하는 서버는 필요 없지만, 클라이언트가 서버를 겸하기 때문에 많은 기

능을 클라이언트에 구현해야 한다.

C/S형 게임의 구현을 위해서는 「서버 측에 고성능 프로그램의 구축이 필요」하고 P2P형은 「클라이언트 측

에 고성능의 프로그램이 필요」합니다.

어찌됐건 이 책에서 다루고 있는 리얼타임 게임의 경우, 서버나 클라이언트에 고성능, 고기능의 네트워크

프로그래밍이 필요합니다.

고성능/고기능 서버의 특성 - 온라인 게임 서버에 요구되는 요소

C/S MMO, C/S MO 게임에서 요구되는 고성능/고기능 서버는 다음과 같은 특성이 있습니다.

11 NAT 트래버설(NAT Traversal, 5.6절에서 기술) 등 특수한 경우는 제외합니다.

12  나중에 기술하겠지만 C/S형 게임은 클라이언트/서버(Client/Server)형의 게임, P2P MO형의 게임은 P2P(Peer to Peer) 통신을 이용하는 게

임입니다. MMO(Massively Multiplayer Online)는 다수의 유저가 즐기는 타입의 멀티플레이어 게임, MO(Multiplayer Online)는 비교적 소

수의 유저가 즐기는 타입의 멀티플레이어 게임입니다.

Page 48: 온라인 게임을 지탱하는 기술

48 제0장 _ [속성] 온라인 게임 프로그래밍

소대역

매초 몇 차례~20회 정도, 수백 바이트까지 계속 통신하여 접속을,

극히 다수

서버 한 대당 수천~수만의 접속을 유지한 채로,

저지연

수 밀리초~20밀리초 정도에 처리하여 결과를 반환한다.

스테이트풀

서버는 상태를 유지하고 있으며(Stateful), 적의 움직임과 같은 동작을 온 메모리 상태로 리얼타임으로 계

속해서 처리하고 있다.

서버의 특성이 웹 서버와는 완전히 다름을 알 수 있습니다. 따라서 일반적인 웹 시스템에서 사용하고 있는

프로그래밍 방식을 이용할 수 없습니다. 이 책에서는 그 차이점도 다루겠습니다.

고성능/고기능 클라이언트의 특성 - 온라인 게임 클라이언트에 요구되는 요소

한편 P2P형 게임(P2P MO 게임)에서 요구되는 고성능/고기능 클라이언트의 특성은 다음과 같습니다.

소대역

매초 몇 차례~20회 정도, 수백 바이트까지 계속 통신하여 접속을,

소수

클라이언트 하나당 몇 개까지,

저지연

수 밀리초~20밀리초 정도에 처리하여 결과를 반환한다.

스테이트풀

클라이언트는 상태를 유지하고 있고 적의 움직임과 같은 동작을 온 메모리 상태로 리얼타임으로 계속해서

처리하고 있다. 또 화면 표시 처리 등의 매우 무거운 처리도 동시에 실시해야 할 필요성이 있다.

다양성

클라이언트의 네트워크 상황의 다양성에 대응해야 한다.

서버와 비교하면 클라이언트는 의 접속 수는 적지만 에서 화면 표시 처리와 같은 극히 무거운 처리를

수행하면서도 지연 없이 통신해야 하며, 의 다양성13에도 대응할 필요가 있는 등, 성능면에서도 기능

면에서도 일반적인 웹 서비스에는 없는 것들이 필요합니다.

13 방화벽(fire wall)이나 각 ISP(Internet Service Provider) 방침의 차이 등.

Page 49: 온라인 게임을 지탱하는 기술

0.2 복수의 동시 접속을 처리, 성능을 추구한다 49

0.2

소켓 프로그래밍 입문

복수의 동시 접속을 처리, 성능을 추구한다

이 절에서는 「소켓 프로그래밍 입문」이라는 제목으로 C 언어를 흉내 낸 가상의 코드로, 레이어 4의 TCP상

에서 소켓 API를 통해 통신하는 방법에 대해 구체적으로 설명하겠습니다. 우선은 통신의 시작이라고 할 수

있는 「통신로의 특정」 및 「소켓 API의 기본」 「복수의 동시 접속을 처리하기 위한 전략」(동기적 호출, 비동기

호출), 그리고 「성능 및 개발 효율 관련의 급소」의 순서로 그 요점에 대해 살펴봅니다.

통신로의 특정

TCP 통신로(커넥션 지향의 통신로)가 자연적으로 생기는 경우는 없습니다. 누군가가 「접속

하고 싶다」고 하면, 또 다른 누군가가 그것을 받아들임으로 성립되는 것입니다. 「접속하고

싶다」고 하는 것을 「클라이언트」(Client), 수용하는 쪽을 「서버」(Server)라고 부릅니다. 서버

는 받아들이기 전에 사전 준비가 필요합니다.

IP에서는 하나의 IP 어드레스(32비트값)와 하나의 포트 번호(16비트값)로 통신로의 양 끝

점을 특정할 수 있습니다.14 IP 어드레스와 포트 번호, 합계 48비트의 정보가 통신로 양쪽

끝점에 하나씩 있으므로 96 비트로 인터넷의 통신로를 특정할 수 있습니다(그림 0.1 ).

그림 0.1 IP어드레스+포트 번호에 의한 통신로의 특정

통신로

IP 주소

포트 번호

IP 주소

포트 번호

끝점1 끝점2

끝점1 끝점2

통신로8.10.124.68

45152

210.255.111.222

8080

32비트 →

16비트 →

14  이 책에서는 32비트의 IPv4를 예로 설명하겠습니다. 단, 현재 IP 어드레스의 고갈이 문제되어, 128비트로의 확장을 위해 IPv6의 채용이 필요하다는

주장이 있습니다. 기술적인 준비는 거의 갖추어진 단계에 와 있습니다.

Page 50: 온라인 게임을 지탱하는 기술

50 제0장 _ [속성] 온라인 게임 프로그래밍

IP 어드레스」는 32비트이며 십진수를 사용하여 0.0.0.0~255.255.255.255까지의 값입니다

(그림 0.1 ), 인터넷에 접속된 웹 서버에 이 고유의 값을 할당하며, 국제적 약정하에 번호

를 취득합니다.

한편, 16비트의 값인 「포트 번호」는 서버를 구현하는 사람의 재량으로 결정할 수 있습니

다. 다만, HTTP에서의 80번 포트처럼 WELLKNOWN PORT NUMBERS(자주 사용되

는 포트번호)나, REGISTERED PORT NUMBERS(등록된 포트번호)도 있는데 그 번호는

IANA(Internet Assigned Numbers Authority)의 포트 번호표15에서 확인할 수 있습니

다. 또, 리눅스나 FreeBSD, 맥 OS X 등의 유닉스 계열 시스템에서는 /etc/services 파일

에 그 서브셋이 존재합니다. 따라서

shell> telnet localhost http � telnet localhost 80과 같다

라는 식으로 문자열을 사용하여 포트 번호를 지정할 수 있으며, 사람이 알기 쉬운 커맨드

라인으로 표현할 수 있습니다.

덧붙여서, 앞서 기술한 IANA의 포트 번호표에서는 MMORPG 게임인 「월드 오브 워크래

프트」(WoW, 나중에 설명)의 포트 번호도 기재되어 있었습니다.

blizwow 3724/tcp World of Warcraft

blizwow 3724/udp World of Warcraft

소켓 API의 기본

단순한 ECHO 서버, ECHO 클라이언트의 예

소켓 API의 동작은 서버와 클라이언트 양측이 다릅니다. 구체적인 애플리케이션인 「ECHO

서버」16를 예를 들어 설명하겠습니다.

우선, 리스트 0.1에서 ECHO 서버 동작을 살펴보겠습니다. 이것은 단순합니다. 각 함수에

대해서는 리스트의 코멘트/주석에 정리해 두었으므로 참조하기 바랍니다. 여기서 살펴볼

곳은 다음 페이지에 나오는 리스트 0.1 중, sock와 별개로 accept( ) 함수에 의해 new_

15  URL http://www.iana.org/assignments/port-numbers

16 ECHO 서버는 「어떠한 데이터를 수신하면, 그 데이터를 그대로 반환하는 서버를 말하며, 소켓 API의 설명을 위한 좋은 예입니다.

Page 51: 온라인 게임을 지탱하는 기술

0.2 복수의 동시 접속을 처리, 성능을 추구한다 51

sock이 갑자기 발생하는 곳입니다. 최초 socket( ) 함수에 의해 작성된 소켓은 엄밀히 통

신로가 아님에도 불구하고, 소켓과 같은 명칭을 사용하고 있기 때문입니다. 리스트 0.1의

서버를 작동시킨 후, 포트에 대해 telnet 커맨드(클라이언트 역할)로 접속하여 적당한 데이

터를 보내면, 데이터가 다시 되돌아 오는 것을 확인할 수 있습니다. 시험해 보십시요.

리스트 0.1 _ ECHO 서버의 동작

int sock = socket(PF_INET, SOCK_STREAM);

� 종류를 지정하여 리슨용 소켓(파일 디스크립터)을 작성한다 �

bind(sock, addr); � 리슨 포트 번호를 설정한다

listen(sock); � 리슨 개시

while (1) {

int new_sock = accept(sock, &addr);

� 신규 접속 요구가 있을 때까지

"기다린다"(블록). 요구가 오면 새로운 소켓을 반환하여 접속을 확립

char buf[100];

size_t size = read(new_sock, buf, 100);

� 최대 100바이트를 읽을 때까지

"기다린다"(데이터가 올 때까지 또는 접속이 끊길 때까지 블록) �

if (size == 0){ � read 함수의 반환값이 0이라면, EOF를 수신 �

close(new_sock); � EOF를 수신했다면 닫는다

} else {

write(new_sock, buf, size); � EOF가 아닌 경우는 size 바이트를 작성한다

}

}

� 여기서는 네트워크 인터페이스/프로토콜 패밀리의 종류(여기서는 「PF_INET」로 IPv4를 설

정하였다. 참고로 AF_INET라고 해도 동작은 변하지 않다. IPv6는 PF_INET6라고 한다)와

소켓의 종류(여기서는 「SOCK_STREAM」이며 스트림형의 TCP/IP를 설정하였다. 참고로

SOCK_DGRAM이라면 UDP를 지정한 것이다)를 지정하고 있다.

소켓에 어드레스를 연결시킨다. 기다리기 위한 포트 번호를 설정한다.

� 그 소켓에 대한 입출력을 실시하는 것으로, 클라이언트와 데이터의 송수신을 실행한다.

� 간단하게 하기 위해, 100바이트라는 고정값을 사용하고 있다.

� EOF는 End Of File의 줄임말. 스트림의 종료(데이터가 더 이상 오지 않음)를 말한다.

Page 52: 온라인 게임을 지탱하는 기술

52 제0장 _ [속성] 온라인 게임 프로그래밍

리스트 0.2의 ECHO 클라이언트는 서버보다 더 단순합니다. socket( ) 함수로 소켓을 작

성하고 나서 지정한 어드레스에 대해 connect, write한 후, 데이터가 돌아오는 것을 기다

렸다가 read할 뿐입니다. 이 read와 write는 영원히 반복됩니다.

리스트 0.2 _ ECHO 클라이언트

int sock = socket(PF_INET, SOCK_STREAM);

� 새로운 소켓(파일 디스크립터)을 작성

connect(sock, addr);

� 작성한 소켓을 사용하여, 지정한 어드레스와 포트(를 가지는 호스트)에 대해서 접속한다. 접속 완료까지 기다린다

whiel (1) {

write(sock, "ping"); � 데이터를 쓰기 처리한다(여기서는"ping")

char buf[100];

read(sock, buf, 100);

� 읽어 들일 때까지 기다린다. 데이터("ping")이 돌아오는 것을 기대한다

} �영원히 통신을 반복

● ● ●

위의 예에서 알 수 있듯이 통신로로서의 새로운 소켓을 만들려면(접속을 확립하려면)

socket( )와 accept( )의 두 가지 함수를 사용합니다.

TCP 통신로의 상태 전이와 소켓 API리스트 0.1, 리스트 0.2와 TCP 통신로의 관계에 대해 좀 더 자세히 살펴봅시다. TCP의 통

신로는 그림 0.2와 같이 상태 전이를 합니다.17

「소켓 API의 어떤 함수를 호출하면 어느 상태로 바뀌는 것인가」가 이해의 포인트입니다. 이

것에 대해 설명할 기회는 좀처럼 없습니다만, 그 이유는 TCP라는 프로토콜 자체가 그것의

조작을 위한 API와는 완전히 독립되어 있기 때문일 것입니다. 이 책에서는 소켓 API를 중

심으로 설명할 것이므로 아래에서 소켓 API의 함수와 TCP 통신로 상태의 대응 관계를 확

실히 기억해두기 바랍니다.

17 각각의 통신로의 상태는 netstat 커맨드로 확인할 수 있습니다.

Page 53: 온라인 게임을 지탱하는 기술

0.2 복수의 동시 접속을 처리, 성능을 추구한다 53

그림 0.2 TCP 통신로 상태 전이※

CLOSED

CLOSING

TIME_WAIT

CLOSE_WAIT

LAST_ACK

FIN_WAIT_1

CLOSED

LISTEN

ESTABLISHED

FIN_WAIT_2

SYN_RECEIVED SYN_SENT

❶ 패시브 오픈

❸ 통신 확립

❹ 액티브 클로즈 ❺ 패시브 클로즈

❷ 액티브 오픈

패시브 오픈액티브 오픈

(SYN의 송신)

ACK의 수신

클로즈(FIN의 송신)

FIN의 수신(ACK의 송신)

FIN의 수신(ACK의 송신)

FIN의 수신(ACK의 송신)

FIN ACK의 수신

FIN ACK의 수신

클로즈(FIN의 송신)

FIN ACK의 수신

SYN의 수신(SYN/ACK의 송신)

SYN/ACK의 수신(ACK의 송신)

타임 아웃 대기

socket()

새로운 TCP 접속이 가능한 것이 아니므로 TCP 접속은 상태를 가지지 않는다

connect()

connect() 함수는 그림 0.2의 「액티브 오픈」을 개시한다. 클라이언트가 connect()를 호출하여 접속

을 능동적으로 개시하는 것을 「액티브 오픈」, 그것을 받아들여 서버 측에서 접속이 수동적으로 열리는

것을 「패시브 오픈」이라고 부른다. 클라이언트가 connect()를 호출한 순간, SYN가 송신되어 클라이

언트에서는 SYN_SENT 상태, 서버에서는 SYN_RECEIVED(SYN_RCVD) 상태가 된다. 서버 측

의 OS는 이것을 수신하면 SYN/ACK를 반환하며, 클라이언트가 그 SYN/ACK를 수신하고 ACK

를 돌려주면 클라이언트는 ESTABLISHED(접속 확립) 상태가 되고, 서버가 ACK를 수신하면 서버

도 ESTABLISHED가 된다. 이처럼 액티브 오픈에서는 SYN→SYN/ACK→ACK라는 3개의 커맨

드를 송수신하기 때문에 「3웨이 핸드 쉐이크」(Three-way handshake)라고 불린다.

bind()

새로운 TCP 접속이 가능한 것은 아니며, 로컬에 작성한 소켓의 리슨 포트 번호를 설정할 뿐이므로

TCP 접속은 상태를 가지지 않는다

listen()

그림 0.2 의 패시브 오픈을 개시한다. 패시브 오픈이란 액티브 오픈을 서버로부터 바라보았을 경

우를 말하며, 실제 패킷의 순서는 액티브 오픈과 완전히 같다. 패시브 오픈했다면 소켓은 서버가 되어

출전:디지털 어드밴티지 저 「연재:기초부터 배우는 Windows

네트워크 - 2. TCP 상태 전이도」 URL http://www.atmarkit.

co.jp/fwin2k/network/baswinlan016/baswinlan016_03.html

Page 54: 온라인 게임을 지탱하는 기술

54 제0장 _ [속성] 온라인 게임 프로그래밍

LISTEN(대기) 상태로 바뀐다. 서버가 LISTEN 상태가 되어 있으면 클라이언트로부터 SYN 패킷을

수신했을 때 새로운 소켓을 작성하는 기능이 기동된다.

accept()

OS(리눅스 커널)가 ESTABLISHED 상태가 된 새로운 통신로로서의 TCP 접속을 기다리는 경우,

그것을 애플리케이션에서 새로운 소켓으로서 취득한다. 통신로로서의 TCP 상태에 변화는 없지만

read(), write() 함수를 이용하여 소켓을 통해 다음 번 데이터를 송수신하기 위한 파일 디스크립터를

취득하기 위한 필수 함수이다

앞의 기사에 나와있는 그림은 여러 TCP 상태 전이도 중에서도 각 상태가 그룹화되어 있어

매우 알기 쉽다.

read() / write() / send() / recv() / sendto() / recvfrom()

실제 데이터를 송수신하기 위한 함수군은 ESTABLISHED 상태에서 사용할 수 있다. 그 이외의 경

우에 호출한다면 에러가 나온다.

shutdown()

더 이상의 읽기 처리나 쓰기 처리를 하지 않을 것임을 OS에게 알린다. 인수에 SHUT_RD를 지정하

여 읽기 처리를 멈춘 경우, 이것은 로컬의 상태 변화이므로 세션 상태에 변화는 없다. 하지만 SHUT_

WR를 지정하여 더 이상 보낼 것(쓰기 처리=write)이 없다는 것을 OS에게 알린 경우에는 소켓을 닫

은 것이 되므로 그림 0.2의 액티브 클로즈를 개시한다. 액티브 클로즈는 액티브 오픈과 달리 서버

는 물론 클라이언트에서도 개시하는 것이 가능하다. 이것은 한 번이라도 ESTABLISHED 상태가 되

었다면 클라이언트도 서버도 동등한 상태가 되기 때문이다.

액티브 클로즈는 SHUT_WR 한 쪽에서 우선 FIN 패킷을 송신한다. 그것을 수신한 쪽(패시브 클로

즈)은 곧바로 FIN를 돌려주고 CLOSE_WAIT 상태로 변한다. SHUT_WR 한 쪽은 그 FIN을 받아

FIN/ACK를 송신하고 통신로를 삭제한다. 패시브 측은 FIN/ACK를 받으면 같은 방법으로 통신로를

닫는다. 통신로를 닫는 경우도 3웨이 핸드 쉐이크를 실시하는 것이 특징이다.

close()

shutdown(SHUT_RD | SHUT_WR)처럼 읽기 쓰기의 양쪽 모두를 동시에 닫은 것과 같은 동작을

한다.

TCP 상태 전이에 영향을 주는 소켓 API의 함수에 대해서는 이상으로 설명을 마치겠습니다.

Page 55: 온라인 게임을 지탱하는 기술

0.2 복수의 동시 접속을 처리, 성능을 추구한다 55

복수의 동시 접속을 처리한다

비동기 소켓 API로 향하는 길

여기서부터가 본론입니다. 리스트 0.1의 ECHO 서버는 중대한 결함이 있습니다. accept( )

함수가 「새로운 접속 요구가 있을 때까지 대기」하므로, 두 번째 read( ) 함수는 새로운 접속

요구가 있기 전에는 호출되지 않습니다. 이대로라면 read( ) 함수의 호출을 위해 매번 새로

운 접속을 받아들여야 한다는 것입니다.18

게다가 문제가 한 가지 더 있습니다. read 함수가 클라이언트에서 데이터가 올 때까지 기

다리기 때문에 read할 때까지는 두 번째의 accept 함수를 호출하는 것이 불가능합니다.

즉, 클라이언트로부터의 신규 접속을 받아 들인 후 데이터가 도착할 때까지는 새로운 접속

을 받아들일 수 없다는 것입니다.

복수의 클라이언트에 대해 동시 서비스를 제공하는 온라인 게임은 이런 방식이라면 성립될

수 없습니다. 복수의 동시 접속을 처리할 필요가 있고, 그러기 위해서는 복수의 소켓을 동

시에 다룰 수 있어야 합니다. 이를 해결하기 위한 방법을 크게 나누면,

각 접속마다 프로세스를 1개씩 기동한다.

비동기적으로 입출력을 다중화(I/O 다중화)한다.

스레드를 사용해 동기적인 처리를 병렬화한다.

등이 있습니다. 의 방법은 inetd(인터넷 슈퍼 서버)나, 옛날부터 웹에서 사용되고 있는

CGI(Common Gateway Interface) 등에서 이용하지만, 온라인 게임에서는 복수의 유저

(접속)가 하나의 게임 상태를 리얼타임으로 공유해야 하기 때문에 의 방식은 사용하지 않

습니다. 나 중에서 선택해야 합니다.

동기적 호출(블로킹)과 스레드

소켓 API의 connect( )/accept( )/read( ) 함수는 처리가 성공할 때까지 영원히 기다

립니다. 그 이외의 함수는 기다리는 것 없이 즉각(마이크로초 이내) 반환됩니다. 이러한

18 보통 ECHO 서버에 한 번 접속을 했다면 몇 번이라도 메시지의 송수신이 가능합니다. 일반적인 ECHO 서버라면 accept한 후

read→write→read→write...가 계속될 것입니다. 그러나 리스트 0.1대로라면 accept한 후 read→write, 그 다음 accept이므로 클라이언트가 접속

한 후 단 한 번밖에 메시지 교환을 할 수 없습니다. 이것은 일반적인 의미의 ECHO 서버라고 말할 수 없습니다.

Page 56: 온라인 게임을 지탱하는 기술

56 제0장 _ [속성] 온라인 게임 프로그래밍

connect 함수, accept 함수, read 함수와 같이 「영원히 기다린다」는 동작을 일반적으로 동

기적 호출(동기적 함수 호출), 또는 블로킹(Blocking) 등으로 부릅니다.

영원히 기다린다는 동기적인 처리를 동시에 복수로 처리하고 싶은 경우는 스레드(thread)

를 이용하는 것이 일반적입니다. 스레드를 사용하는 방법은 리스트 0.3과 같습니다. 리스

트 0.1에서 변경된 부분은 리스트 0.3에서 read와 write의 반복을 create_thread()로 병

렬화한 부분입니다.19

리스트 0.3과 같이 멀티스레드화를 통해 여러 클라이언트에 대해 동시에 서비스를 제공하

는 서버를 구현할 수 있습니다. 스레드를 사용하면 「영원히 기다린다」는 처리를 동시에 여

러 개 수행할 수 있습니다. 그 원리는 복수의 스레드로 「동기적 호출」을 병렬로 실시한다는

것입니다.

리스트 0.3 _ ECHO 서버(스레드 버전, 블로킹)

int sock = socket(PF_INET, SOCK_STREAM);

bind(sock, addr);

listen(sock);

while (1) {

int new_sock = accept(sock, &addr);

create_thread( { � 병렬 처리를 시작한다.

char buf[100];

size_t size = read(new_sock, buf, 100);

if (size == 0) {

close(new_sock);

} else {

write(new_sock, buf, size);

}

} );

}

19  C 언어는 Ruby 등과 달리, 리스트 0.3과 같이 코드 블록을 함수의 인수로 사용하는 코딩은 불가능하므로 여기서 제시된 코드는 단지 설명을 위한

예입니다. 주어진 블록을 각각의 스레드로 실행시킨다고 생각하면 됩니다. 유닉스 계열의 경우, 실제로는 fork 함수를 사용하여 프로세스를 기동하

거나, pthread_create 등의 스레드 라이브러리를 사용하는 등의 다양한 방법이 있습니다.

Page 57: 온라인 게임을 지탱하는 기술

0.2 복수의 동시 접속을 처리, 성능을 추구한다 57

스레드 방식의 처리 부하 문제

스레드를 이용하는 방식의 온라인 게임 서버에서는 「처리 부하」의 문제가 일어납니다. create_

thread를 할 때마다 OS의 스레드나 프로세스가 하나 만들어진다면, 동시 접속이 3000인 경우

3000개의 스레드가 동시에 기동하게 되지만, 3000개라는 것은 현재의 머신으로는 프로세서

에 비해 너무 많은 수이므로 서버 퍼포먼스의 대폭적인 저하로 이어집니다.

처리가 활발한 프로세스는 대체로 OS가 동시에 실행할 수 있는 프로세서/스레드 수의

4~10배의 범위여야 합니다. 그렇지 않으면 OS 내부의 스레드 전환에 의한 코스트가 커집

니다. 예를 들면 4코어 머신의 최적 스레드 수는 수십 스레드 정도입니다. 여기에 3000스

레드라는 것은 너무 많지만, 비용을 생각한다면 머신 하나당 동시 접속수 3000까지는 대응

해야만 하는 숫자입니다.

싱글 스레드, 논블록킹, 이벤트 구동

select 함수로 폴링

그런데 select라는 함수20를 이용하여 read 함수나 accept 함수를 호출하기 전, 이들 함수가 기

다리고 있는 것(데이터나 접속 요구)이 이미 도착했는지를 미리 조사하는 방법이 있습니다.

이처럼 미리 확인하는 처리 방식을 「폴링」(Polling)이라고 부릅니다. OS 버전에 따라, poll 함

수나 그 고속 버전인 epoll 등 여러 가지 인터페이스에 의해 실현시킬 수 있습니다.

리스트 0.4는 select를 사용하는 서버 코드를 나타냅니다. 실제 서버에서 동작하는 코드에

서는 플래그 설정이나 구조체 정의 등 몇 가지 일반적인 처리가 필요하지만, 기본적으로 논

리 구성은 같습니다. 리스트 0.4에서는 accept( )나 read( )의 호출 전에, 그 소켓에 무엇

인가 처리해야 하는 이벤트(데이터)가 있는지 조사하기 위해 select( )를 호출하고 있습니

다. 이렇게 하면 read( )나 accept( )는 수 마이크로초의 속도로 반환되어 데이터를 얻습니

다. 실제로는 select 함수를 이렇게 여러 번 호출하지는 않으며, 한 번의 함수 호출로 수천

개의 소켓을 한꺼번에 확인할 수 있습니다.

20  select는 입출력의 완료를 기다리는(읽기, 쓰기가 가능해질 때까지 대기) 함수입니다. 비동기 처리에 의해 입출력의 다중화를 실현합니다. 앞서 언

급한 「UNIX 네트워크 프로그래밍」에 자세하게 설명되어 있습니다.

Page 58: 온라인 게임을 지탱하는 기술

58 제0장 _ [속성] 온라인 게임 프로그래밍

리스트 0.4(select 버전)와 리스트 0.3(스레드 버전)의 차이는 스레드를 만들지 않고(싱글

스레드로) 복수의 클라이언트에 대해 다중화를 통해 서비스를 제공할 수 있다는 점입니다.

리스트 0.4와 같은 구현방법을 비동기 호출, 또는 논블록킹(Non-blocking)이라고 합니

다. 또 리스트 0.4의 예는 데이터가 도착했다는 이벤트의 유무를 미리 조사하고 나서 함수

를 호출하므로 이벤트 구동(Event-driven) 방식이라고 부릅니다.

리스트 0.4 _ ECHO 서버(select 버전, 논블록킹, 이벤트 구동)

int sock = socket(PF_INET, SOCK_STREAM);

bind(sock, addr);

listen(sock);

allsock.add(sock); � allsock 배열에 sock를 등록한다

while (1) {

result = select(sock) � select를 사이에 두어 미리 체크

if (result > 0) {

int new_sock = accept(sock, &addr);

allsock.add(new_sock); � allsock에 새로운 접속을 등록한다

}

foreach (sock = allsock) {

result = select(sock); � select를 사이에 두어 미리 체크

if (result > 0) {

char buf[100];

size_t size = read(new_sock, buf, 100);

if (size == 0) {

close(new_sock);

} else {

write(new_sock, buf, size);

}

}

}

}

온라인 게임에서의 입출력 구현의 특징

싱글 스레드, 이벤트 구동, 논블록킹

게임 프로그래밍에서는 빠른 처리가 필요한 가동물이 수천 개가 동시에 등장하는 것이 보

통이므로, 같은 맥락에서 「1개의 스레드를 사용하여 수천 개의 소켓을 취급한다」는 것에 익

Page 59: 온라인 게임을 지탱하는 기술

0.2 복수의 동시 접속을 처리, 성능을 추구한다 59

숙합니다. 그래서인지 온라인 게임에서는 클라이언트도 서버도 대개는 이 select 함수(혹은

poll/epoll 함수)를 사용하는 극히 단순한 싱글 스레드 이벤트 구동형 논블록킹 방식을 사

용하는 것이 기본입니다.

온라인 게임과 구현 언어

온라인 게임의 서버에서 가장 많이 사용되는 구현 언어는 C/C++이며 그 다음이 자바와

기타 언어입니다. 단, 스크립트 언어는 서버 프로세스에 섞어 넣는 방식으로 병용합니다.

병행하여 사용되는 언어는 루아(Lua)나 스퀴럴(Squirrel)이 대표적이며, 최근에는 루비

(Ruby)나 자바스크립트(JavaScript) 등도 늘고 있는 듯합니다. 루아나 스퀴럴은 사용 메모

리가 극히 적어 초기화 코스트가 낮기 때문에 게임에서는 자주 사용합니다.

서버 측에서 사용되는 언어로는 C 언어, C++, 자바, 루비, 파이썬(Python), 펄(Perl)이 대

표적입니다. 이 모든 언어로 select 함수를 이용한 이벤트 구동/논블록킹을 구현할 수 있습

니다.

클라이언트 측에서 사용되는 언어는 C, C++, 자바, Objective-C, 플래시(Flash)/액션스

크립트3(ActionScript3), 자바스크립트가 대표적입니다. 플래시/액션스크립트3, 자바스크

립트에서는 소켓은 이벤트 구동 API를 이용하는 것이 기본이며 RPC(Remote Procedure

Call, 나중에 설명)와 궁합이 좋습니다.

성능의 최대화 & 개발 효율 향상

구현 언어와 낮은 레이어까지

여기서부터는 성능의 최대화 및 개발 효율 향상에 대해 살펴보도록 합시다. 먼저 구현 언어

와 그 다음 레이어3 이하의 낮은 레이어에서 주의할 점을 살펴보겠습니다.

현재 온라인 게임 서버에서 대부분의 게임 타이틀이 C/C++을 사용하지만, 코딩 작업의 코

스트가 높다는 점 때문에 어떻게든 게임 개발 기간을 줄여야만 하는 지금에는 가비지 컬렉

션(garbage collection)이 가능한 자바나 C#, 혹은 스크립트 언어를 사용할 수 있을지를

각 회사에서 검토하고 있습니다. 필자도 사실 C++의 속도로 동작하는 서버를 루비로 작성

할 수 있다면 좋겠다고 생각한 적이 있습니다.

Page 60: 온라인 게임을 지탱하는 기술

60 제0장 _ [속성] 온라인 게임 프로그래밍

현재로서는 서버의 성능을 희생한다면 개발 효율은 높일 수 있습니다. 이것은 트레이드

오프(trade off)의 관계에 있습니다. 주요 언어를 예로 들어 표 0.1에서 간단하게 정리했습

니다.

표 0.1에서 보듯이 스루풋(Throughput, 단위시간당 처리량)은 C/C++와 루비가 1000배

나 차이가 납니다. 서버 대수는 처리 성능에 반비례하여 필요하므로, 1000배나 차이가 난

다면 필요한 서버 숫자는 극단적으로 달라지게 됩니다.

표 0.1 주요 언어와 스루풋

언어 스루풋 특성

C/C++ 100 정적 언어, 네이티브 코드

Java/ C# 1~10 정적 언어, VM, 바이트 코드

Ruby/Python 0.1~1 동적 언어

현재 많은 유저를 가지고 있는 게임은 대개 C/C++로 작성돼 있기 때문에 비슷한 내용의

게임을 가지고 시장에 뛰어들고자 한다면 C/C++를 사용해야만 가격 경쟁에서 이길 수 있

다는 뜻입니다.

온라인 게임 고유의 특성에 의한 언어별 성능 차이

표 0.1에서 자바의 스루풋이 C/C++에 비해 10배나 낮은 것은 온라인 게임 고유의 특성

때문입니다. 일반적으로 JIT(Just In Time) 컴파일러를 갖추고 있는 가상 머신(Virtual

Machine, VM)21에서는 자바의 실행속도가 JIT 컴파일의 효과로 인해 빨라지며, 경우에

따라서는 C 언어보다 빠릅니다.

단, 그 효과는 처리 내용이 CPU 센트릭(centric)22한 것에 한하며, OS와의 입출력

이 빈번한 애플리케이션에서는 미미합니다. 예를 들어 100MB(Megabyte)의 파일을

1KB(Kilobyte)씩 읽고 행수를 카운트하는 프로그램은 자바보다 C 언어 쪽이 10배 빠른

경우도 있습니다. 이것은 자바 VM이 시스템 콜의 호출 전후에, 버퍼 오버플로우(Buffer

21 지금은 대개 갖추고 있습니다.

22 CPU를 주로 사용하는 처리를 말합니다. 한편, I/O 센트릭은 입출력의 비중이 높은 처리를 말합니다.

Page 61: 온라인 게임을 지탱하는 기술

0.2 복수의 동시 접속을 처리, 성능을 추구한다 61

Overflow)의 체크나 예외 오브젝트 처리 등을 매번 실시하기 때문입니다. 이런 것들은 생

략할 수 없는 처리이므로 가상머신을 사용하는 처리계열에서는 한계가 있습니다. 온라인

게임의 서버에서는 네트워크 입출력이 매초 수만 회 이상 발생하므로 자바와 C 언어와의

속도 차가 생기는 전형적인 이유인 것입니다. 아파치(Apache)나 MySQL 등의 서버 소프

트웨어가 C/C++로 쓰여져 있는 것도 같은 이유입니다.

다음으로 동적 언어의 스루풋이 자바보다 10~100배 낮은 이유는 어떠한 처리를 할 때마다

오브젝트가 가지고 있는 메서드의 변동을 매번 확인할 필요가 있기 때문입니다.

덧붙여서, 구글의 Go 언어는 정적 언어로 네이티브 실행이지만, 가비지 컬렉션이 있으며

그 청소의 강도를 코드마다 프로그래머가 선택할 수 있다는 신개념의 언어이며 서버 성능

을 희생하지 않고 개발 효율을 높일 수 있을 가능성이 있어, 개인적으로 기대하고 있습니

다. 구글은 서버 개발에 대해 정말 잘 알고 있구나, 라는 느낌이 들 때가 많습니다.

멀티코어 서버의 성능을 끌어낸다

그런데 싱글 스레드+이벤트 구동+논블록킹인 구현에서도 멀티코어 서버 머신의 성능을

끌어 내는 것은 가능합니다.

예를 들어 CPU의 실행 코어가 한 개뿐인 경우, 복수의 스레드나 프로세스는 동시에 진행

되고 있는 것이 아니라 아주 짧은 시간을 구간으로 나누어 교대로 실행되고 있습니다. 예를

들어 1밀리초 슬립할 뿐인 아래와 같은 프로그램

while (1) {

usleep(1000);

}

을 동시에 실행한다면 1초간 1000번 교대해야 합니다. 프로세스 A에서 B로의 전환과 B에

서 A로의 전환으로 총 2000회가 매초 발생합니다. 이 횟수는 리눅스에서는 vmstat 커맨드

로 확인할 수 있습니다.23

23 vmstat에 대해서는 제7장에서 다루고 있습니다.

Page 62: 온라인 게임을 지탱하는 기술

62 제0장 _ [속성] 온라인 게임 프로그래밍

Column

입출력의 구현에 대한 지침과 향후의 성능 향상 가능성

이상과 같이 네트워크 프로그래밍에서 입출력 구현 방침은 매우 심오한 문제이므로, 머신의 성능을 100%

활용하기 위한 다양한 아이디어가 나와 있습니다.

일례로 스레드를 몇 개쯤 풀링(pooling)해 두고 이벤트 구동과 병행하여 사용하면 성능을 올릴 수 있

지 않을까와 같은 논의입니다.24 또한 필자도 앞으로 애플의 그랜드 센트럴 디스패치(Grand Central

Dispatch)25와 같은 병렬 동작 방식이나, 구글의 Go 언어인 고루틴26과 같은 방식으로 소에너지화와

고성능화를 동시에 실현할 수 있으리라 기대하고 있습니다.

컨텍스트 스위치 - CPU의 설정 상태를 일시적으로 보관해 둔다

위와 같은 전환을 컨텍스트 스위치(Context Switch)라고 말하며, 이것이 일어날 때 레지

스터(Register)나 가상 메모리(Virtual Storage)의 관리 테이블을 일시 보관하거나 보안 설

정의 전환 등이 커널 내부에서 실행됩니다. 컨텍스트 스위치는 리눅스에서 CPU 코어 하나

당 대략 1초에 10~20만회 실시할 수 있습니다. 이것은 CPU 캐시 메모리의 내용 등 애플리

케이션의 실행 상황에 따라 달라지므로 주의해야 합니다만, 일반적인 기준으로 앞서의 1밀

리초 슬립하는 프로그램이 200개 정도 움직인다면, 컨텍스트 스위치만으로 최대 CPU 성

능을 넘어서게 되어 sy시간(vmstat의 CPU 통계 시스템 시간)은 100%가 됩니다.

컨텍스트 스위치는 CPU 설정 상태를 일시적으로 따로 보관해 두는 처리이기 때문에 CPU

코어가 많다면 1초의 시간 동안 시스템 전체에서 실행할 수 있는 횟수가 그만큼 늘어납니

다. 예를 들어 CPU 코어가 10개 있는 머신이라면 대개 100~200만 회 정도 컨텍스트 스위

치를 할 수 있습니다.27

코어 하나당 처리 능력은 한계점에 도달했으며, 커널의 처리는 이미 최적화되어 있습니다.

따라서 앞으로도 코어 하나당 컨텍스트 스위치가 가능한 횟수는 위의 수치에서 그다지 변

하지 않을 가능성이 높습니다.

24 다음 페이지가 참고가 될 것입니다. URL http://d.hatena.ne.jp/sdyuki/20090624/1245845216

25 맥 OS X v10.6(Snow Leopard)에 탑재된 신기능의 하나로, 멀티코어에서의 병렬 프로그래밍을 간단하게 할 수 있는 방법.

26  URL http://golang.jp/2010/03/1260

27  필자는 100코어, 1000코어라는 방대한 코어를 가지는 매니코어 머신을 다루어 본 적은 없지만, 그러한 머신에서는 또 다른 동작을 보여줄지도 모릅

니다.

Page 63: 온라인 게임을 지탱하는 기술

0.2 복수의 동시 접속을 처리, 성능을 추구한다 63

멀티코어 머신이며 서버 프로세스 수를 너무 늘리지만 않으면 OK

온라인 게임 서버를 싱글 스레드+이벤트 구동+논블록킹으로 구현하는 경우 머신의 코어

하나당 하나의 프로세스가 구동되도록 조절하면 멀티코어 머신의 성능을 100%로 활용할

수 있습니다.

컨텍스트 스위치는 네트워크에 입출력을 할 때에도 필요합니다. 하나의 코어에서 만약 10

만 회의 컨텍스트 스위치가 생긴다면 10만 회의 네트워크 입출력이 가능하다는 뜻입니다.

동시 접속수가 코어당 1000이라면 매초 100회의 입출력을 할 수 있는 셈이므로 보통 매초

수 회 정도이므로 충분히 여유가 있습니다. 따라서 멀티코어 머신이며 서버 프로세스의 수

를 너무 늘리지만 않는다면 문제는 없습니다.

멀티코어 머신과 네트워크의 스루풋

온라인 게임과 작은 패킷

서버는 통상 이더넷(Ethernet), 아마 1Gbit(Gigabit) 이더넷을 이용하여 데이터센터 내의

네트워크에 접속돼 있을 것입니다. 리눅스 서버의 경우 이더넷은 이름만큼의 속도가 나옵

니다. 즉, 1Gbit 이더넷이면 1Gbit의 통신 속도가 나옵니다. 스위칭 허브도 문제 없이 이

속도에 대응 가능합니다.

다만 온라인 게임에서 작은 패킷을 대량으로 송신할 때 기대한 것만큼의 통신 속도가 나오

지 않을 수 있습니다. 이 점에 대해서도 알아봅시다.

이더넷 프레임

이더넷은 IP 패킷 송신을 할 때 IP 데이터 이외의 다양한 추가 정보를 매번 패킷에 실어 보

냅니다. 이 추가 정보를 포함한 종합적인 대역폭을 「1Gbps」라고 하는데, 실제로 애플리케

이션이 사용할 수 있는 대역은 이것보다 작아집니다

예를 들어, 윈도우에서 telnet 명령어로 TCP 서버에 접속하고 A키를 누르면 “a”라는 1바이

트의 데이터가 송신됩니다. 이때 실제로는 이더넷에서 어느 정도의 대역을 소비하고 있는

것일까요? 일반적인 사양의 이더넷에서 패킷을 송신하는 경우, 그림 0.3과 같은 정보를 보

냅니다.

Page 64: 온라인 게임을 지탱하는 기술

64 제0장 _ [속성] 온라인 게임 프로그래밍

그림 0.3에서 예를 들어 의 (7)은 7옥텟(octet)을 나타냅니다. 「옥텟」이란 「8비트의 세트」

라는 의미입니다. 드물지만 「1바이트가 8비트가 아닌 머신」도 있습니다. 「비트」는 더 이상

나누는 것이 불가능하므로, 통신 사양에 대한 정확한 정의를 내릴 경우 「옥텟」을 사용합니

다.

“a”라는 한 개의 문자는 1옥텟으로 표현할 수 있습니다. “a”는 16진수로 0x61, 2진수에서는

011000001로 표시되는 8비트 문자입니다.

그림 0.3 가장 전형적인 이더넷 프레임(IEEE802.3)

❶ ❷ ❸ ❹ ❺ ❻ ❼

프리앰블(7)

SFD(1)

받는 주소(6)

길이/타입(2)

데이터/LLC(46∼1500)

FCS(4)

보내는 주소(6)

그림 0.3 7옥텟의 맨 처음인 「프리앰블」(Preamble, 동기신호)과 다음인 1옥텟 「SFD」

(Start Frame Delimiter)은 항상 고정되어 있으며 다음과 같습니다(맨 마지막은 1이 2번

연속됩니다).

1010101010101010101010101010101010101010101010101010101010101011

이것은 전선을 흐르는 노이즈에서 통신 신호를 찾아내기 위한 고정 신호입니다. 이것이 64

비트라는 긴 시간(마이크로초 이하 단위입니다만…) 동안 이어지고 있어, 이더넷의 스위치

는 노이즈와 신호를 구분할 수 있습니다.

그림 0.3 , 의 보내는 곳, 받는 곳의 MAC 어드레스가 각각 6옥텟씩으로, 합계 12옥텟

이 됩니다. MAC 어드레스는 이더넷에 연결되는 모든 디바이스에 부여되는 값으로, 디바이

스 제작사에 따라 블록으로 할당되어 있습니다. 예를 들어 윈도우에서는 ipconfig/all 커맨

드로 출력이 가능하며 04-A3-43-5 F-43-23로 표현됩니다.28

계속해서 의 데이터의 길이/타입이 2옥텟으로 지정되며, 그 다음 의 본 데이터가 이어

지며, 마지막에 의 4옥텟의 FCS(Frame Check Sequence, 신호 오류 정정용 체크섬)이

붙습니다.

28 리눅스에서는 ifconfig 커맨드로 조사할 수 있습니다.

Page 65: 온라인 게임을 지탱하는 기술

0.2 복수의 동시 접속을 처리, 성능을 추구한다 65

네트워크 계층별 헤더

TCP를 이용하여 데이터를 송신하면 이더넷의 헤더(header) 이외에도 더 많은 헤더를 동

시에 송신하게 됩니다. TCP상에서 “a”라는 1옥텟의 데이터를 보내더라도 OSI 참조 모델의

계층 구조에서 다음의 4가지 하위 시스템을 사용하는 셈입니다.

• 레이어4(트랜스포트층):TCP

• 레이어3(네트워크층):IP

• 레이어2(데이터링크층):이더넷 프로토콜

• 레이어1(물리층):트위스티드 페어 케이블

계층 구조를 채용하고 이더넷을 「직접」 이용하지 않게 하여 Wi-Fi나 3G 네트워크29와 같

은 다른 물리 미디어를 이용한 통신을 할 때, 보다 상위의 시스템에서 프로그램 수정은 필

요로 하지 않습니다. 이런 이점을 누리고자 각 레이어마다 헤더를 추가하는 것입니다.

구체적으로 레이어4의 TCP 헤더(20옥텟)와 레이어3의 IP 헤더(20옥텟), 이더넷의 헤더나

푸터(22옥텟)가 이에 해당합니다.

TCP 헤더는 그림 0.4에 표시한 것처럼 송신 어드레스의 포트 번호(16비트, 2 옥텟), 수신

어드레스의 포트 번호(16비트, 2옥텟), 시퀀스 번호(32비트, 4옥텟), ACK 시퀀스 번호(32

비트, 4옥텟), 플래그(코드 비트), 윈도우 사이즈, (데이터의) 체크섬, 긴급 포인터까지의

20옥텟이 필수입니다.

그림 0.4 TCP 헤더

0 16 31

수신 포트 번호(16)

송신 포트 번호(16)

시퀀스 번호(32)

확인 응답 번호(32)

헤더길이(4)

예약완료(6)

플래그(각 1비트)

URG

ACK

PSH

RST

SYN

FIN

윈도우 서비스(16)

체크섬(16)

긴급 포인터(16)

데이터 본체

패딩(PADDING)옵션

29 3rd Generation Network. 제3세대 휴대 전화 통신 네트워크.

Page 66: 온라인 게임을 지탱하는 기술

66 제0장 _ [속성] 온라인 게임 프로그래밍

그림 0.5 IP 헤더(IPv4)

0 168 31

버전 번호(4)

헤더 길이(4)

서비스 타입(8) 패킷 길이(16)

식별자(16) 플래그(3) 프래그먼트 오프셋(13)

헤더 체크섬(16)TTL(유효기간)(8) 상위 프로토콜(8)

송신 IP 주소(32)

수신 IP 주소(32)

옵션(32×n)

패딩(가변길이)

데이터 본체

IP 헤더는 그림 0.5에 나타나 있는 대로입니다. 그림 0.5의 위에서부터 세줄(× 4 = 12옥

텟)은 버전 번호(4비트), 헤더 길이 (4비트), 서비스 타입(8비트), 패킷 길이(16비트) 등 각종

통신 설정을 나타냅니다. 그 다음 32비트의 송신 IP 어드레스와 수신 IP 어드레스가 붙습

니다. 여기 다섯 행까지 IP를 위해서 20옥텟이 필요합니다. 그림 0.5 「데이터 본체」의 부분

에 TCP 헤더를 포함한 데이터가 들어가며, TCP 데이터 본체 속에 “a”라고 하는, 애플리케

이션에서 보내려 하는 데이터가 포함됩니다. “a”라는 1옥텟의 데이터를 보내기 위해서는,

TCP:합계 21옥텟

헤더:20옥텟

데이터 “a”:1옥텟

IP:합계 41옥텟

헤더:20옥텟

데이터(TCP 분량 ):21옥텟

이더넷:합계 67옥텟

프리앰블:7옥텟

SFD:1옥텟

송신 IP 어드레스:6옥텟

수신 IP 어드레스:6옥텟

길이:2옥텟

데이터:41옥텟(IP 분량)

FCS:4옥텟

Page 67: 온라인 게임을 지탱하는 기술

0.2 복수의 동시 접속을 처리, 성능을 추구한다 67

이상으로 1옥텟의 애플리케이션 데이터(“a”)를 보내려면 총 67옥텟이 필요합니다. 만약

1Gbps 이더넷에서 애플리케이션이 1바이트씩만 송신한다고 가정하면, 실제 이용 가능한

대역폭은 1Gbps의 67분의 1이 됩니다. 이것은 약 1.5 Mbps 정도입니다.

멀티코어 머신의 송신 능력

위와 같이 OSI 참조 모델을 이용하여 아주 작은 데이터로 잘게 나누어 송신한다면 헤더가

차지하는 분량이 많아져 물리층의 부담이 매우 커집니다. 반대로 1400바이트 정도의 큰 데

이터 단위로 보낼 수 있다면, 각종 헤더가 차지하는 비율이 낮아지므로 거의 이론상의 통신

속도가 나오게 됩니다.

온라인 게임에서는 애플리케이션의 데이터 단위가 20바이트 정도로 작은 경우도 있으므로

이론상 수치의 몇 분의 1의 속도밖에 나오지 않는 경우가 많습니다. 일반적으로 10Mbit 이

더넷은 가장 작은 데이터를 매초 14881회, 100Mbit 이더넷은 148810회, 1Gbit 이더넷은

1488100회 송신할 수 있다고 합니다.

개인적 경험이지만 이론상 수치의 10분의 1을 기준으로 하여 1Gbit 이더넷은 100Mbytes

를 매초 송신할 수 있고, 송신 가능한 패킷의 수는 매초 10~15만이 한계라고 보면 됩니다

(리눅스의 경우).

만약 10코어 머신에서 1Gbit 이더넷을 사용한다면 한 코어당 패킷 수는 약 1만이 되기 때문

에, 동시 접속수가 코어 하나당 1000이라면 접속 하나당 매초 10번의 송신으로 그치는 설

계를 해야 할 것입니다. 혹은 복수의 NIC(Network Interface Card)를 장착할 수 있는 서

버라면 LAN(Local Area Network) 케이블을 4개 연결하여 4배의 스루풋이 가능하도록 하

는 방법도 있습니다.

덧붙여 10Gbit 이더넷은 스위칭 허브가 아직 비싸므로 비용에 민감한 온라인 게임 현장에

서는 아직 사용되고 있지 않습니다. 가까운 장래에 저렴한 제품이 나와 현실적인 선택을 할

수 있게 되기를 기대해 봅니다.

Page 68: 온라인 게임을 지탱하는 기술

68 제0장 _ [속성] 온라인 게임 프로그래밍

서버 구현의 간소화

libevent

마지막으로 간소화에 대해 살펴봅시다. 「싱글 스레드+이벤트 구동+논블록킹 호출」 모델로

서버를 구현하는 경우에 최적인 라이브러리로 libevent가 있습니다.30 libevent는 파일

공유 소프트 Tor31로부터 파생된 라이브러리로 memcached32 등에서도 사용되고 있으

며, 온라인 게임의 서버, 클라이언트 수준의 성능이 요구되는 경우 자주 사용되는 네트워크

서버 소프트웨어 라이브러리로, 5년이라는 장기간에 걸친 실적을 가지고 있습니다.

libevent는 전 세계 사이트에서 운용되고 있으며 성능과 안정성을 인정받고 있습니다. 그

렇다고는 해도 실제로 libevent를 상용 서비스에서 사용하려면 게임 서버 구현 후, 독자적

인 게임 내용에 맞춘 부하 테스트를 실시해야 합니다.

libevent의 특징

libevent의 사용할 때의 핵심 포인트는 아래와 같습니다.

• 특정 소켓이 지정한 상태(write 가능, read 가능, accept 가능)가 되면 앞서 지정했던 함수를 호출하

도록 설정한다.

• libevent 라이브러리는 각 OS에 대해 가장 효율적인 방법을 자동으로 선택하여(리눅스에서 소켓의

수가 많을 때는 epoll을 선택하는 등) 소켓의 현재 상태를 폴링한다.

• 애플리케이션은 그 결과를 미리 설정한 함수의 호출(이것을 콜백 함수라고 한다)로 수신하며 그 콜백

함수 안에서 read나 accept 등의, 원래는 기다리고 있었을, 처리를 실행한다.

libevent의 최대 특징은 스레드를 많이 만들어 read 등의 시스템 콜을 호출한 상태에서 기

다리고 있는 것이 아니라, 「스레드를 만들지 않고, 미리 알려줬으면 하는 각 이벤트마다 콜

백 함수를 등록해 두어 이벤트가 발생했을 때 한 번만 함수를 호출한다」는 것입니다.

30  URL http://monkey.org/~provos/libevent/

덧붙여서, libevent의 후계로서 한층 더 고속화된 라이브러인 libev도 있습니다.

URL http://software.schmorp.de/pkg/libev.html

31  URL http://www.torproject.org/

32  memcached( URL http://memcached.org/)는 매우 많은 웹 서비스에서 사용되고 있으며 mixi나 livedoor, 하테나 등 수많은 대규모 서

비스에서 서버 처리 성능 향상을 위해서 이용되고 있습니다. 2010년 여름에는 mixi에서 사용되던 memcached가 장애를 일으켰습니다만, 그때

mixi Engineers'Blog에서 신속히 상세한 해명 기사가 공개되었습니다. 특정 하드웨어 설정 상태에서 극히 대량의 접속이 발생했을 때만 일어나

는 버그가 발생했다는 것이었습니다.

URL http://alpha.mixi.co.jp/blog/?cat=34

Page 69: 온라인 게임을 지탱하는 기술

0.3 RPC 공략 최소 기능의 통신 미들웨어 69

스레드를 전혀 만들지 않으며, 매우 가볍고 빠른 동작이 가능하므로 통신처리 등 데이터의

입출력이 주가 되는 병렬 처리를 구현하는 데 알맞습니다.

libevent는 매우 단순하며 빨라서 많은 시스템에서 사용되고 있습니다. 필자도 실제로 온

라인 게임의 서버 시스템을 만들 때 사용하여 충분한 성능이 나왔습니다. 리눅스, 맥 OS X,

솔라리스, 윈도우 등 주요 운영체제에서 사용할 수 있으며, 소스 레벨의 호환성이 있다는

것도 큰 매력입니다.

libevent를 사용하면 싱글 프로세스+이벤트 구동+논블록킹 호출 시스템 개발을 간소화

하는 것이 가능합니다.

0.3

RPC 공략

최소 기능의 통신 미들웨어

이 절에서는 원격 절차 호출(Remote procedure call)이라고도 불리는 「RPC」를 설명합니다. RPC는 통신에

관한 자잘한 번거로운 작업을 줄이고 통상의 함수 호출과 같은 식으로 리모트 호스트와의 통신을 간단하

고도 안전하게 실시할 수 있는 방법의 하나입니다. RPC 라이브러리를 사용하면 BSD 소켓의 API를 직접

사용하지 않고서도 통신 프로그램을 개발할 수 있습니다.

통신 라이브러리의 필요성

앞 절에서 레이어4(TCP) 소켓 프로그래밍의 기본 사항을 중심으로 설명하였습니다. 그러

나 실제 게임에서는 (BSD) 소켓 API 함수를 직접 호출하는 것은 피하고, 더욱 상위의 API

로 감싼(Wrap) 통신 라이브러리를 준비하여 그것으로 애플리케이션을 개발하여야 합니다.

그 이유는 BSD 소켓의 라이브러리는 네트워크의 상황에 따라 다음과 같은 동작을 하기 때

문입니다.

• 희망하는 사이즈 그대로 송신/수신에 성공한다는 보장이 없기 때문에 나중에 재호출할 필요가 있다.

• 에러가 발생할 수 있다.

Page 70: 온라인 게임을 지탱하는 기술

70 제0장 _ [속성] 온라인 게임 프로그래밍

• 송신 버퍼가 넘칠 때는 write() 함수가 기다리게 된다.33

파일에 쓰기 처리하는 것과 네트워크에 쓰기 처리하는 것을 비교해 보면, 네트워크는 상대

가 떨어져 있으므로 상태에 대해 확실히 알 수 없습니다. 따라서 비록 지금 실패해도 나중

에 성공할지도 모르기 때문에 단순히 에러로 처리할 수 없습니다. 네트워크의 기본적인 특

성은 「상태가 유동적」이라는 것입니다. 파일은 지금 디스크가 꽉 찼다면 곧바로 실패로 처

리한다 해도 아마 상관없을 것입니다.

여기서, 클라이언트 코드의 나쁜 예를 살펴봅시다(리스트 0.5). send는 네트워크 상태에

따라서,

대기하게 ‘될지도’

송신에 실패 ‘할지도’

4바이트 보내고 싶은데, 1바이트밖에 보낼 수 ‘없을지도’

모르므로, “키보드를 연타했더니 3번째가 송신되지 않았다”는 상황도 발생할 수 있습니다.

리스트 0.5 _ 클라이언트의 코드의 나쁜 예

void keyDownHandler(KeyboardEvent e) { � 클라이언트에서 키를 눌렀다

send(sock, e.keycode);

}

void mouseDownHandler(MouseEvent e) { � 클라이언트에서 마우스를 눌렀다

send(sock, e.buttonCode);

}

그렇다고 해도 이러한 함수 안에서 송신에 성공할 때까지 블록시키거나 할 수는 없는 노릇

이며, 에러 처리를 매번 일일이 작성하는 것은 코드의 중복이 많아져 실수의 원인이 되어

버립니다.

따라서, 이러한 일을 도맡아 처리해 주는 라이브러리가 필요합니다. 이러한 통신 라이브러리

는 네트워크에 대한 입출력 요구를 일단 버퍼에 싣고, 차후에 하나씩 꺼내어 확실히 실행시키

도록 해줍니다. 후에 데이터가 완전히 모두 보내질 때까지 송신을 시도하며, 일정 시간 안에

송신이 완료되지 않으면 에러를 반환하는 등의 시간적 요소에 의해 성공 실패를 구별합니다.

33 라이브러리 내부에 버퍼링하여 쓰기 처리가 가능해졌을 때 다시 한번 송신하는 것으로 해결합니다.

Page 71: 온라인 게임을 지탱하는 기술

0.3 RPC 공략 최소 기능의 통신 미들웨어 71

리스트 0.6의 예에서 send( ) 대신 wrapperSend 함수를 호출하고 있습니다.

wrapperSend 함수는 블록하지 않고, 메모리가 부족해서 동작할 수 없는 경우 이외에는

에러를 반환하지 않으며 반드시 성공합니다. 하는 일이란, 내부의 버퍼에 송신 예정인 데이

터를 쌓는 것뿐입니다. 이것과 같은 작업을 하기 위한 네트워크 통신 라이브러리 중 유명한

것은 boost::asio가 있습니다.

리스트 0.6 _ wrapperSend 함수의 사용

void keyDownHandler(KeyboardEvent e) { � 클라이언트에서 키를 눌렀다

wrapperSend(sock, e.keycode); �

}

void mouseDownHandler(MouseEvent e) { � 클라이언트에서 마우스를 눌렀다

wrapperSend(sock, e.buttonCode);

}

포맷을 결정하고 송수신한다

이어서 위의 리스트 0.6의 예에서는 생략했습니다만, 실제로 데이터를 보내는 방

법에 대해 조금 더 깊이 살펴보겠습니다. 리스트 0.6 에서는 키가 눌린 사실을

wrapperSend(sock, e.keycode);와 같이 송신하였습니다. 이 코드는 추상적입니다만,

구체적으로 어떤 비트를 송신하고 있는 것일까요?

가령 X 키를 눌렀고 그 키의 코드가 16진수로 0x78이라고 합시다. TCP는 커넥션 지향이며

스트림 프로토콜이므로 각 송신을 구분하지 않습니다. 따라서 리스트 0.6 의 코드로 TCP

스트림에 대해 0x78이라는 1바이트를 보냈다고 해도, 그 전에 보낸 데이터의 이어지는 부

분인지 아닌지 알 수 없습니다.

예를 들어 마우스가 움직였을 때 그 좌표를 wrapperSend(sock, e.mouseX); 와 같은 정

보로 송신하고 싶다고 합시다. 만약 x좌표가 16진수로 0x78이라면 키보드가 눌러졌는지,

마우스가 이동했는지, 수신한 측에서는 판단이 서지 않습니다.

따라서 다음과 같은 포맷을 정하여 송수신을 할 필요가 생깁니다.

[정보의 종류별 코드 1바이트] [정보의 내용]

Page 72: 온라인 게임을 지탱하는 기술

72 제0장 _ [속성] 온라인 게임 프로그래밍

온라인 게임에서 사용하는 RPC의 전체적인 모습

위의 포맷을 발전시킨 끝에 나온 것이 RPC라고 불리는 개념입니다. 리모트(다른 프로세스)

에 대한 함수 호출을 스트림에 실을 수 있는 형태로 인코딩하여 송신하고, 그것을 리모트에

서 수신하고 디코딩하여 함수를 호출하는 것입니다. 포인터 이외의 데이터라면 이것으로

문제없이 송신할 수 있습니다.

온라인 게임에서 사용하는 RPC의 전체적인 모습은 그림 0.6과 같습니다. 가장 아래가 물

리층이고 위로 갈수록 상위 계층입니다.

그림 0.6의 왼쪽이 RPC를 호출하는 쪽, 오른쪽이 RPC를 수신하는 쪽이며 그 어느 쪽도 클

라이언트도 서버도 될 수 있습니다.

우선 그림 0.6 에서 호출하는 쪽의 애플리케이션은 프로그램 내에서 attackAtEnemy라

는 함수를 호출합니다. 이 함수는 「RPC 스터브 코드」라고 하는 소스 파일에 작성합니다.

RPC 스터브 코드를 함수마다 각각 작성하는 것은 매우 번거로우므로 툴에 의해서 자동으로

생성합니다. 스터브 파일 안에서는 소켓 라이브러리에 대해 2바이트의 send( )를 행합니다.

그림 0.6 온라인 게임에서 사용하는 RPC의 모식도

애플리케이션 코드

int main()

{

attackAtEnemy(99);

}

RPC스터브 코드(자동 생성)

void attackAtEnemy(byte id)

{

// 소켓으로 송신

send(socket, 123);

send(socket, id);

}

소켓 라이브러리void send() {

OS의 시스템 콜을 호출한다

소켓 라이브러리void recv() {

OS의 시스템 콜을 호출한다}

인터넷

OS이더넷 하드웨어에 데이터를 송신

하드웨어(네트워크 인터페이스)전기신호를 발생 하드웨어(네트워크 인터페이스)

전기신호를 수신

OS이더넷 하드웨어에서 데이터를 수신

RPC 스터브 코드(자동 생성)

void doPolling()

{

recv(buffer); //소켓으로부터 수신

if (buffer[0] == 123) {

int id = buffer[1];

attackAtEnemy(id);

}

}

애플리케이션 코드int main()

{

while(1) {doPolling();} ();} //영원히 반복한다

}

int attackAtEnemy(byte id)

{

printf("%d\n", id); ); //99가 출력된다

}

물리층

데이터 링크층

네트워크층

트랜스포트층

세션 층

프레젠테이션층

애플리케이션층

RPC를 호출하는 쪽

RPC를 수신하는 쪽

}

Page 73: 온라인 게임을 지탱하는 기술

0.3 RPC 공략 최소 기능의 통신 미들웨어 73

그림 0.6의 스터브로부터 호출된 소켓 라이브러리의 send 함수는 내부에서 OS의 시스템

콜을 호출하고(그림 0.6 ), OS는 하드웨어를 작동시키며, 하드웨어는 전기신호를 발생

(그림 0.6 )시키고, 전기신호는 인터넷를 통해 전송됩니다(그림 0.6 ).

수신하는 쪽에서는 받은 전기신호를 하드웨어에서 OS에 전송하여(그림 0.6 ), 프로그램

에서 이용 가능한 상태로 만듭니다. OS는 수신한 데이터를 소켓 라이브러리에 전달합니다

(그림 0.6 ).

수신하는 쪽의 애플리케이션은 메인 루프 안에서 doPolling이라는 함수를 실행하고 있고

(그림 0.6 ), 그 안에서 데이터를 수신합니다(그림 0.6 ).

수신한 데이터에는 1 바이트째에 함수의 종류를 나타내는 고정값인 123이 포함되어 있기

때문에, 조건분기(conditional branch)를 하여 수신 측 애플리케이션에 정의되어 있는

attackAtEnemy 함수를 호출합니다. 또 호출하는 쪽에 인수로서 부여되어 있던 값인 99도

2바이트째에서 꺼내어 attackAtEnemy 함수에 인수로 넣습니다.

● ● ●

이상과 같이, 통신에 관한 세세한 사항을 무시하고 함수 호출이라고 하는 컴파일러에서도

이해 가능한 방법을 통해 안전하게 통신 프로그램을 구성할 수 있습니다. 두 개의 프로세스

가 복잡한 통신을 실행하는 애플리케이션인 경우 구성 시 RPC를 이용하는 것은 일반적인

방법입니다.

RPC 스터브 코드를 자동 생성하는 RPC 툴

RPC 스터브 코드 파일은 호출하는 쪽 함수의 인수열의 내용과 호출되는 쪽 함수의 인수열

의 내용이 반드시 일치해야만 합니다. 그러나 수많은 함수에 대해 이러한 정의를 일일이 수

작업으로 작성해 나가는 것은 분명 작업상 실수의 원인이 되어 극히 수정하기 어려운 버그

를 낳게 됩니다. 보통은 이러한 수작업을 줄이기 위한 전용 프로그램을 준비하여, 호출하는

쪽과 수신하는 쪽의 함수 정의를 동시에 자동 생성합니다. 이러한 전용 프로그램을 RPC 툴

이라고 부릅니다.

일반적으로 루비나 파이썬 등 DSL(Domein Specific Language)은 다루기 쉬운 언어를

사용하여 IDL(Interface Description Language)을 설계하고, 그 스크립트를 실행하여 송

수신용 스터브 함수의 소스 코드, 헤더를 자동 생성하여 프로젝트에 링크하여 사용합니다.

Page 74: 온라인 게임을 지탱하는 기술

74 제0장 _ [속성] 온라인 게임 프로그래밍

IDL이란 두 개의 프로그램 사이의 대화에 필요한 인터페이스를 정의하는 전용 언어를 말

합니다. 보통은 IDL은 대화할 필요가 있는 두 개 이상의 프로그램이 각각 다른 언어로 작

성되어 있거나 서로 다른 머신상에서 작동하고 있는 경우, 서로 다른 타이밍에 작동하고 있

는 경우 등 보통의 함수 호출 방식을 사용할 수 없을 때 필요합니다. 이러한 특수한 상황에

서는 머신마다 서로 다른 바이너리 형식으로 변환하거나 영속화하는 등의 기능이 필요하기

때문입니다.

IDL은 대화하고 싶은 프로그램 언어와 같은 언어, 혹은 가독성이 높은 제3의 프로그램 언

어나 설정 파일 등을 이용하여 작성하는 것이 일반적입니다. 현재는 IDL을 직접 제작할 때

루비의 ERB나 파이썬의 장고(Django) 등의 우수한 웹용 템플릿 엔진을 이용할 수 있으므

로 그것을 사용하여 소스 코드를 생성하는 것이 편리할 것입니다.

RPC 툴로 소스를 자동 생성하면 정수, 문자열, 배열, 리스트, 구조체나 클래스 등을 직접

보내거나, 머신마다 서로 다를 가능성이 있는 2바이트 이상의 값을 송수신할 때 발생하는

바이트 오더 문제에 대처하거나, 두 가지 이상의 언어를 대상으로 소스를 출력하는 등 개발

에서 필요한 자잘한 작업을 자동화할 수 있습니다.

단, 기능이 복잡하여 처리 속도가 늦다면 게임에서는 사용할 수 없을 것입니다. 예를 들

어, XMLRPC로 불리는 XML(Extensible Markup Language)을 베이스로 한 RPC 기구는

송수신의 포맷으로 XML을 사용하기 때문에 사람이 읽기 쉬우며 디버그 효율도 좋습니다.

하지만 온라인 게임에서 매초 수만이라는 수의 RPC를 1 코어로 처리하기에는 너무 무겁습

니다.

온라인 게임과 바이너리 데이터 교환 포맷/라이브러리

온라인 게임에서는 복잡한 계층 구조를 가진 데이터를 보낼 필요가 없으므로 바이너

리 포맷은 단순한 것으로 충분합니다. 구글은 회사 내의 필요성에 의해 프로토콜 버퍼스

(Protocol Buffers)라는 데이터 교환 포맷을 오픈소스로 내놓았습니다.34 페이스북도 같

은 맥락으로 스리프트(Thrift)라는 라이브러리를 릴리즈하여, 지금은 아파치 소프트웨어 재

34  URL http://code.google.com/intl/ja-JP/apis/protocolbuffers/

Page 75: 온라인 게임을 지탱하는 기술

0.3 RPC 공략 최소 기능의 통신 미들웨어 75

단(Apache Software Foundation)에 호스팅되어 있습니다.35 필자는 이용한 적이 없습

니다만, 일본산 라이브러리인 메시지 팩(Message Pack)은 빠른 처리 속도를 내세우고 있

습니다.

프로토콜 버퍼스, 스리프트, 메시지 팩 모두 구조체나 열거체를 지원하고 있습니다. 정의

파일과 출력되는 코드의 지원에 관해서는 각각의 튜토리얼(tutorial)을 참조하기 바랍니다.

이러한 웹 기업에서 유래된 툴은 파이썬 등의 스크립트 언어로 구현되기 때문에 사용하기

쉽고, 바이너리 포맷도 지원하고 있으므로 온라인 게임에서도 사용 가능합니다. 아마도 전

세계의 다양한 온라인 게임에서 사용되고 있을 것입니다. 만약 이러한 툴에 불필요한 기능

이 많고 쓸데없는 처리가 많다고 느낀다면, 이 툴들을 참고로 하여 직접 제작해 보는 것도

그다지 어려운 일은 아닐 것입니다.

● ● ●

이상으로 이 절에서 설명한 「RPC 기능」과 앞서 소개한 libevent의 「소켓 API의 논블록화를

위한 API」를 조합한다면, 온라인 게임의 통신 미들웨어로서 최소한의 기능을 갖출 것입

니다.

[보충] UDP의 이용

앞 절과 이 절에서는 TCP를 중심으로 설명하였으며 UDP에 대해서는 일단 보류했습니다.

여기서 간략하게 살펴보자면, 온라인 게임에서 UDP를 사용하는 목적은 주로 아래와 같은

두 가지로 나눌 수 있습니다.

신뢰성보다 도달 속도가 중요한 데이터의 송신을 위해

NAT 트래버설(traversal) 기능을 구현하기 위해

은 예를 들어 FPS(First Person Shooter) 장르에서 캐릭터의 이동 정보를 가장 빠르게

보내기 위해서 사용합니다. TCP를 사용하는 경우 데이터 패킷이 도중에 손실되면 재전송

처리가 실행되는데 그것이 종료될 때까지는 그 다음 데이터는 전송되지 않으므로 통신 지

연이 발생합니다. 그러나 UDP는 재전송하지 않고, 다음 패킷을 전송합니다. 윈도우나 게

35  URL http://incubator.apache.org/thrift/

Page 76: 온라인 게임을 지탱하는 기술

76 제0장 _ [속성] 온라인 게임 프로그래밍

임기 등 유닉스 계열이 아닌 호스트(기본적으로 모든 클라이언트라고 보면 됨)상에서 동작

하는 소프트웨어이면서, 특히 CPU를 많이 사용하는 소프트웨어는 (윈도우 내부에서) 패킷

이 자주 사라지기 때문에 UDP를 이용하여 그 악영향을 최소화하려고 합니다.

는 P2P MO, C/S MO 게임에서 사용하는 방법으로 제5장에서 자세하게 설명하겠습니다.

0.4

게임 프로그래밍의 기초

네트워크 프로그래밍에 이어 이 절에서는 일반적인(고전적인) 게임 프로그래밍의 기초를 소개합니다.

게임 프로그래밍의 역사

1970년대 타이토의 「스페이스 인베이더」 시대부터 게임 프로그래밍 방법은 기본적으로는

전혀 변화가 없습니다.

사용하는 언어도 당대의 어셈블리 언어에서부터 C, C++, Objective-C까지 근본적으로

그다지 변한 것은 아닙니다. 인터넷 프로그래밍의 역사처럼 대부분의 게임이 기본적으로는

같은 방법으로 만들어져 왔습니다.

게임 프로그래밍은 한 대의 머신 내부에서 완결되기 때문에 그 처리 절차에 관해 국제적인

표준화 운동이 있었던 적은 없으며, 소켓 API와 같은 일반적 표준의 라이브러리 등도 없습

니다. 각 게임 장르마다, 그리고 하드웨어 플랫폼마다 여러 가지 툴이 난립하고 있으며, 각

각의 기업이 저마다의 방식으로 용도를 구분 지어 사용하고 있는 것이 현실입니다.36 이

하에서 온라인 게임 구현의 이해를 위하여 게임 프로그래밍의 기본적인 처리 로직에 초점

을 맞춰 설명하겠습니다.

36  예외적으로 3D 폴리 곤(polygon)의 파일 보존 형식 등 조직간/기업간의 교환이 빈번한 부분에 대해서 COLLADA(http://www.khronos.org/

collada/) 등의 표준화 운동이 일어난 적은 있습니다.

Page 77: 온라인 게임을 지탱하는 기술

0.4 게임 프로그래밍의 기초 77

「점만 찍을 수 있다면 게임은 만들 수 있다」 인베이더 게임

GPU(Graphics Processing Unit)나 고도의 화면 표시 처리용 라이브러리 등은 온라인 게

임에 필수는 아니며, 이러한 것을 고려하면 이야기가 복잡해지므로 게임 프로그래밍의 기

초 해설의 지름길인 「화면에 점만 찍을 수 있다면 게임은 만들 수 있다」라는 개념을 가지고

만들어봅시다.37 다음과 같은 기능을 가진 하드웨어를 이용한다는 전제로 이야기를 진행

해 나가겠습니다.

• getKey() 함수를 호출하면 키보드가 눌린 것을 알 수 있다

반환 값의 첫 비트가 (왼쪽 화살표) 키, 두 번째 비트가 (오른쪽 화살표) 키, 세 번째 비트가

키라는 것을 판별할 수 있다.

• 화면 사이즈는 256×256

• point(10, 10, 3) 함수로 화면의 (10, 10)라는 위치에 “3”의 색으로 화면 표시 처리를 할 수 있다. 색

은 0:흑색, 1:흰색, 2:적색, 3:녹색

이것을 가지고 그림 0.7과 같은 인베이더와 비슷한 게임을 만들 수 있습니다. 이것이 현재

의 게임 개발과 동떨어진 것인가 하면 실제로 그렇지는 않습니다. 「STAR STRIKE HD」38

와 같은 게임을 실현할 수 있는 PlayStation 3이라도, GPU나 멀티코어 프로세서 등의 힘

을 빌려 위와 같은 처리를 초고속으로 하고 있을 뿐입니다. 일단 처리 속도는 무시하고 생

각하기로 합시다.

그림 0.7 「스페이스 인베이더」(인베이더 게임의 예)※

37 「게임 프로그래머가 되기 전에 기억해야 할 기술」(히라야마 히사시 저, 秀和시스템, 2008)에 자세히 설명되어 있습니다. 반드시 참고해 주세요.

38 대량의 오브젝트를 고속으로 화면 처리하는 대표적인 360 ̊슈팅 게임의 하나

©TAITO CORPORATION 1978, 2011

©2010 SQUARE ENIX CO., LTD. All Rights

Reserved.

화면 제공:(주)타이토. 「스페이스 인베이더」는 1978년

에 처음으로 등장한 인베이더 게임의 원조다. 위 화면은

이 책의 집필 시점에서의 최신판 「스페이스 인베이더 인

피니티 진」( URL http://infinitygene.net/)에서 발췌했

다. 화면 윗부분이 인베이더(적 캐릭터), 아랫부분이 이동

포대(플레이어)이다. 화면 중앙에 짧은 직선이 탄알이며

인베이더를 공격한다. 화면 중앙에 보이는 지그재그선은

적의 탄알이다. 참고로 이 절 이후에 나오는 인베이더 게

임 샘플의 화면 사이즈는 256×256이다.

Page 78: 온라인 게임을 지탱하는 기술

78 제0장 _ [속성] 온라인 게임 프로그래밍

가상의 코드로 알 수 있다! 게임 프로그램의 기본 해부

앞서 서술한 것처럼 게임 프로그램 전체의 모습은 모두 합해도 디스플레이 몇 화면 정도에

모두 들어갑니다. 이것을 C 언어 스타일의 가상의 코드로 표현해 보겠습니다. 이 가상의 코

드는 실제로 동작하는 코드와 매우 비슷합니다.

그럼 코드를 살펴봅시다. 다음에서 보는 그대로입니다. MYSHIP은 플레이어의 기체,

INVADER는 적 인베이더, MISSILE은 플레이어의 탄알(플레이어의 기체가 쏜 미사일)이

며, 화면의 위 방향으로 날아 갑니다. BULLET은 적이 쏜 탄알이며 화면의 아래 방향으로

날아 옵니다.

� 화면 사이즈를 정의

#define WIDTH 256

#define HEIGHT 256

� 등장하는 것의 이미지 번호(종류별 ID)를 정의

enum {

MYSHIP = 0, � 플레이어의 비행기

INVADER = 1, � 침략자

MISSILE = 2, � 플레이어의 탄알

BULLET = 3, � 적의 탄알

}; � 이하 이어짐...

화면에 보이는 물체(가동물)는 스프라이트(Sprite)라는 클래스(Class)로 정의했습니다. 스

프라이트는 이미지 번호(img), 좌표(x,y), 진행 방향(dx,dy)을 가지는데, move( )하면 진

행 방향으로 1스텝 이동합니다. new한 직후의 상태에서 진행 방향은 (0,0)이므로 이동하지

않습니다. hit( ) 함수에 다른 스프라이트를 부여하면 충돌했는지(8픽셀 폭의 사각형 영역

이 겹쳤는지 아닌지)를 판정합니다.

class Sprite

{

public:

int img; � 이미지 번호 (MYSHIP, INVADER, MISSILE, BULLET 중 어느 것인지)

int x,y; � 현재 위치의 좌표 (단위=픽셀)

int dx, dy; � 진행 방향, 1프레임에 진행되는 속도 (단위=픽셀)

Page 79: 온라인 게임을 지탱하는 기술

0.4 게임 프로그래밍의 기초 79

� 생성자(constructor)

Sprite(int x, int y, int img) {

this->x = x;

this->y = y;

this->img = img;

this->dx = this->dy = 0;

}

� 1스텝 움직인다

void move() {

this->x += this->dx;

this->y += this->dy;

}

� 충돌 판정의 사이즈는 8

bool hit(Sprite *sp) {

if (!sp) return false;

return (this->x+8 > sp->x && this->y+8 > sp->y

&& sp->x+8 > this->x && sp->y+8 > this->y);

}

}; � 이하 이어짐...

위의 프로그램에는 스프라이트 클래스밖에 없습니다. 다음에는 메인 루틴을 개시합니다.

메인 루틴은,

초기화

무한 루프

로 구성됩니다. 이것은 어떠한 게임 프로그램에서도 같습니다.

초기화

초기화에 대해 살펴봅시다. 이하의 , '에서 플레이어의 기체를 화면 아래쪽에 등장시

킵니다. MYSHIP이라는 정수를 주어 이미지 번호를 지정합니다. 게임 시작 시에 플레이어

기체의 미사일은 등장하지 않기 때문에 new하지 않습니다().

에서 게임 시작 시 인베이더는 12열×5행 배치되어 있기 때문에 그것을 모두 new합니

다. 스프라이트 클래스의 인스턴스가 단번에 60개 증가하는 셈입니다. new하여 생긴 스프

라이트의 포인터는 invaders라는 배열에 넣어 둡니다.

Page 80: 온라인 게임을 지탱하는 기술

80 제0장 _ [속성] 온라인 게임 프로그래밍

를 봅시다. 인베이더도 탄알을 쏩니다만, 게임 시작 시에는 적의 탄알은 존재하지 않으

므로 모두 0으로 초기화해 둡니다. 적의 탄알도 이와 같이 여러 개가 동시에 존재하므로

bullets라는 배열에 넣어 둡니다.

int main()

{

int i,j;

� 플레이어의 기체를 등장시킨다

Sprite *myship = new Sprite(WIDTH/2, HEIGHT*0.8, MYSHIP);

� '화면 아래 쪽의 정가운데

Sprite *missile = 0; � 플레이어 기체의 미사일

� 인베이더를 등장시킨다

#define NUM_INVADERS (12 * 5)

Sprite *invaders[NUM_INVADERS];

for (i=0; i<5; i++) {

for (j=0; j<12; j++) {

invaders[i*12+j] = new Sprite((WIDTH / 12) * j, (HEIGHT / 10) * i);

}

}

� 인베이더가 쏘는 탄알은 동시에 최대 10개까지

#define NUM_BULLETS 10

Sprite *bullets[NUM_BULLETS];

for (i=0; i<NUM_BULLETS; i++) {

bullets[i] = 0;

} � 이하 이어짐...

이것으로 초기화가 끝났습니다.

무한 루프

다음은 무한 루프입니다. 아래의 은 while (1)이라는 밑도 끝도 없는 코드로 되어 있습니

다만, PC 게임은 키 등으로 종료하는 경우도 있습니다.

처음은 키 입력을 가져오는 것입니다. 에서 getKey 함수를 이용해 키보드 상태를 가져오

고 있습니다. 윈도우의 애플리케이션은 메시지 루프 안에서 윈도우로부터의 메시지를 받아

조건 분기를 합니다. 게임기에서는 아래와 같은 단순한 함수를 호출하는 경우가 많습니다.

Page 81: 온라인 게임을 지탱하는 기술

0.4 게임 프로그래밍의 기초 81

이 인베이더 스타일의 예제 게임에서 플레이어가 작동시킬 수 있는 것은 플레이어의 기체

뿐입니다. 따라서 키 입력을 판정하여 직접 myship의 dx(진행 방향)를 변경하고 있습니다.

이 게임에서는 진행 방향에 수정을 가하고 있으므로 키를 입력하면 그 방향으로 계속 진행

하게 됩니다.

키를 눌렀을 때는 플레이어의 기체가 미사일을 쏘므로, MISSILE의 이미지 번호

를 지정하여 플레이어의 기체와 같은 좌표에서 new합니다. dy를 -1로 하여 화면 위 방향

으로 나아가도록 설정하고 있습니다.

while (1) { �

int key = getKey(); �

if (key & 0x1) { � (→ 오른쪽 화살표) 키

myship->dx = 1;

} else if (key & 0x2) { � (� 왼쪽 화살표) 키

myship->dx = -1;

} else if (key & 0x4) { � 키

if (missile == 0) {

missile = new Sprite(myship->x, myship->y, MISSILE);

missile->dy = -1;

} else { � 아무 키도 눌려지지 않았다면

myship->dx = 0;

myship->dy = 0;

}

} � 이하 이어짐…

각 스프라이트의 동작 - 게임 로직의 본체

이상으로 메인 루프로 키 입력이 끝났다면 다음은 각 스프라이트의 동작입니다. 이 부분은

게임 기획 내용을 실현시키기 위한 게임 로직의 본체이므로 해설이 약간 깁니다.

아래의 에서 move 함수로 플레이어의 기체를 진행 방향으로 1스텝 이동시킵니다. 위에

서 1인지, -1인지를 지정하고 있으므로 1루프당 1픽셀이 움직입니다. 1초에 60프레임의 경

우 60픽셀 움직입니다. 상용 게임에서는 게임이 너무 빠른 경우는 빈 루프를 돌려 조절하

거나 하드웨어의 타이머 기능 등을 이용해 대기하는 처리를 추가합니다.

Page 82: 온라인 게임을 지탱하는 기술

82 제0장 _ [속성] 온라인 게임 프로그래밍

� 플레이어의 기체, 미사일, 적탄, 적을 이동시키며 충돌 판정도 한다

myship->move(); �

if (missile) { �

missile->move();

if (missile->y < 0) { � 미사일이 화면 범위를 벗어났다면 지운다

delete missile;

missile = 0;

}

}

for (i=0; i<NUM_BULLETS; i++) { � 적의 미사일을 이동시킨다

if (bullets[i]) {

bullets[i]->move();

if (bullets[i]->hit(myship)) exit(0); � 맞았다. 게임 오버!

if (bullets[i]->y > HEIGHT) { � 화면 범위 아래로 벗어났다면 지운다

delete bullets[i];

bullets[i]=0;

}

}

}

for (i=0; i<NUM_INVADERS; i++) { � � 인베이더를 이동시킨다.

if (invaders[i]) {

invaders[i]->move();

if (invaders[i]->hit(missile)) { �인베이더를 쓰러뜨렸다!

delete invaders[i];

invaders[i]=0;

}

if ((random() % 10000) == 0) { �적이 가끔씩 미사일을 쏜다

for (int k=0; k<NUM_BULLETS; k++) {

if (bullets[k] == 0) {

bullets[k] = new Sprite(invaders[i]->x, invaders[i]->y,

BULLET);

bullets[k]->dy = 1;

break;

}

}

}

}

} � 이하 이어짐...

Page 83: 온라인 게임을 지탱하는 기술

0.4 게임 프로그래밍의 기초 83

에서는 플레이어 기체가 쏜 미사일이 존재한다면 move 함수로 이동시키고 있습니다.

myship과는 달리 미사일은 존재하지 않는 상태가 있으므로, if(missile)의 조건 분기가 필

요합니다. 미사일이 화면상에서 벗어나면 delete하여 메모리를 비웁니다.

메인 루프는 이어집니다. 에서 적의 미사일 모두를 move( ) 함수로 이동시키고 있습니

다. 중요한 것은 충돌 판정입니다. 적탄이 플레이어의 기체에 충돌하면 게임 오버이므로,

모든 탄알은 myship에 대해서 hit( )를 호출하여 판정하고, 충돌했다면 exit( )하고 있습니

다(난폭하네요!). 또한 적탄 역시 플레이어의 기체가 쏜 미사일처럼 화면 밑으로 벗어났다

면 delete하여 메모리를 비우고 있습니다. 그것과 동시에 배열 요소를 0으로 하여 다시금

초기화하고 있습니다.

에서는 인베이더를 이동시키고 있습니다. 상용의 인베이더 게임에서는 인베이더는 파도

치는 것과 비슷한 독특한 움직임을 하지만 이 책에서는 너무 복잡해지므로 생략하였습니

다. 여기서의 모든 인베이더는 플레이어의 미사일에 맞으면 사라지므로 hit(missile)해서

결과가 참이라면 delete 하고 있습니다. 또한 난수를 이용한 일정한 확률로 적탄을 쏩니다.

적탄을 쏜다는 것은 스프라이트를 new한다는 것입니다. bullets 배열에 빈 곳(값이 0인 요

소)이 있는가를 for 루프로 검색하고, 빈 곳이 있다면 new합니다. 화면에 NUM_BULLETS

개 (NUM_BULLETS는 적탄의 최대 개수)의 미사일이 있다면 이 루프는 아무것도 하지 않

고 빠져나옵니다. 이와 같은 제한이 없다면 메모리가 부족하게 될 가능성이 있습니다.

화면 표시

메인 루프로 가동물을 움직였다면 마지막으로 화면 표시 처리를 합니다. 아래의 에서 일

단 모두 지우고 있습니다. 「무엇인가를 화면에 표시하여 모두 지운 후, 조금 어긋난 위치에

다시 화면에 표시하면 그것이 움직이는 것처럼 보인다」라는 인간의 눈의 특성을 이용하는

것입니다. 단, 애니메이션과 마찬가지로 그것을 실현시키기 위해서는 일정 이상의 빈도로

갱신해야 할 필요가 있습니다.

에서는 drawSprite 함수에 스프라이트 클래스의 참조를 전달하여 myship, missile,

bullets, invaders를 화면 표시 처리하고 있습니다. 이 화면 표시 처리 순서를 변경하면 상

위에 표시되는 것을 조정할 수 있습니다. 플레이어의 기체를 부수는 것은 적탄뿐이며, 중요

하므로 가장 마지막에 표시하도록 하였습니다.

Page 84: 온라인 게임을 지탱하는 기술

84 제0장 _ [속성] 온라인 게임 프로그래밍

� 일단 모두 지우고 나서 모두를 화면에 표시한다

clearScreen(); �

drawSprite( myship ); �

drawSprite( missile );

for (i=0; i<NUM_INVADERS; i++) {

drawSprite(invaders[i]);

}

for (i=0; i<NUM_BULLETS; i++){

drawSprite(bullets[i]);

}

} � 앞서 나온 while 무한 루프의 마지막

} � 앞서 나온 main 함수의 마지막

이것으로 메인 루프(while 무한 루프)가 끝나며 main 함수도 끝입니다.

서브루틴

이후는 서브루틴입니다. 우선 아래에서는 화면 표시 처리의 그래픽 패턴을 정의하고 있습

니다. 1개의 스프라이트당 64개의 픽셀로 구성하고 있습니다. 예를 들어 탄알의 경우 다음

과 같이 됩니다. 8×8회 루프를 돌리면 화면에 탄알다운 물체가 출현한다는 것입니다.

00000000

00011000

00011000

00011000

00011000

00011000

00011000

00000000

우선 imageData로 64문자로 이루어진 문자열을 4개(myship, invader, missile, bullet)

정의합니다. 실제로 이것이 얼마나 매력적인 것이 될지는 그래픽 디자이너에게 달려 있습

니다. 또한 마찬가지로 imageColor로 각각의 그림의 표시색을 정의합니다

� 스프라이트의 사이즈는 8×8로 해본다. 64문자로 그림의 패턴을 정의할 수 있다

char imageData[BULLET+1][] =

{

Page 85: 온라인 게임을 지탱하는 기술

0.4 게임 프로그래밍의 기초 85

"0001010010010101010101100001000010111110101110110101011010101111", � myship

"1111010101110101111010010100010101010001010101010100101110101010", � invader

"0000000000011000000110000001100000011000000110000001100000000000", � missile

"0000000000011000000110000001100000011000000110000001100000000000", � bullet

};

int imageColor[BULLET+1] =

{

3, � myship는 녹색

1, � invader는 흰색

1, � missile는 흰색

1 � bullet는 흰색

};

이 로직를 담고 있는 것이 이하의 drawSprite입니다. 우선 패턴과 색을 스프라이트 클

래스의 img 멤버 변수로부터 결정합니다. 그 후 에서 루프를 8×8회 돌리고 point( ) 함

수를 부릅니다. 각 스프라이트의 좌표로부터의 상대 좌표에 표시하는 것이 포인트입니다.

의 clearScreen은 화면 전체를 흑색으로 채우는 함수입니다.

void drawSprite(Sprite *sp) �

{

int i,j;

if (!sp) return;

char *toDraw = imageData[sp->img]; � 화면 표시 패턴을 결정

int col = imageColor[sp->img]; � 화면 표시 색을 결정

for (i=0; i<8; i++) { �

for (j=0; j<8; j++) {

point(sp->x + j, sp->y + i, toDraw[ i*8 + j ] * co l ) ;

� 각 색으로 점을 찍는다

}

}

}

void clearScreen() �

{

int i,j;

for (i=0; i<WIDTH; i++) {

for (j=0; j<HEIGHT; j++) {

Page 86: 온라인 게임을 지탱하는 기술

86 제0장 _ [속성] 온라인 게임 프로그래밍

point(i, j, 0);

� 흑색으로 점을 찍는다(WIDTH * HEIGHT회, point를 호출한다)

}

}

}

이상으로 인베이더 게임의 구현은 끝입니다.

게임 프로그래밍의 비결

스레드를 사용하지 않는 「task system」

여기서 설명한 구현 방법은 30년 전의 인베이더 게임에서부터 현대의 iPhone용 게임과

MMORPG에 이르기까지 거의 변한 것이 없습니다.

위의 예를 통해 가장 중요한 것은 「많은 물체가 동시에 따로 움직이는 것처럼 보이고 있지

만, 실제로는 스레드를 사용하지 않고 구현되었다」는 점입니다. 게임 로직은 스레드를 사용

하지 않고 전체를 조금씩 순차 처리(serial processing)하는 것입니다.

만약 이 인베이더 게임에서 여러 물체를 스레드를 사용하여 구현한다면 어떻게 될까요? 예

를 들어 스프라이트 1개당 1개의 스레드를 사용하는 경우를 생각할 수 있습니다. OS가 제

공하는 스레드를 그대로 사용하면 굉장히 곤란한 상황이 벌어집니다.

• 적의 모든 미사일이 완전히 같은 속도로 움직이지 않을지도 모른다. 그렇게 되면 게임 밸런스를 잡을

수 없다.

• 두 개 이상의 물체에 동시에 맞는 경우가 있을 수 있으므로 미사일과 적의 충돌 판정을 위해 배타제어

가 필요하다.

• CPU 코어 수에 비해 스레드 수가 훨씬 많아져서 성능이 저하된다.

이와 같이 게임의 기획 내용을 세밀하게 구현하려면 스레드의 작동 타이밍이나 스케줄링,

배타제어를 정확하게 제어해야만 하는 등 다양한 문제가 발생합니다. 이것은 스레드의 수

가 증가하면 극단적으로 처리 부하가 높아지기 때문입니다.

Page 87: 온라인 게임을 지탱하는 기술

0.4 게임 프로그래밍의 기초 87

따라서 게임 프로그래밍에서는 보통 스레드를 사용하지 않고 복수의 적탄을 동작시킵니다.

이러한 방법을 업계 용어로 「태스크 시스템」(Task system)이라고 부릅니다. 태스크 시스템

이란, libevent의 설명 부분에서 「콜백 함수」를 소개한 것처럼 「한 개의 미사일을 한 프레임

만큼만 진행시킨다」라는 매우 작은 단위의 처리를 하나의 함수로서 정의하고, 그것을 미사

일의 수만큼 한 프레임 안에서 모두를 순서대로 호출함으로써 실질적인 병렬처리를 실현하

는 방법입니다. OS의 네이티브 스레드를 사용하지 않고 처리를 전환하기 때문에 고속으로

동작합니다.

단, 현재의 CPU 능력을 최대한 활용하기 위해서 사운드 처리, AI, 네트워크, 메인, 화면 표

시 처리 등 용도마다 3~5개 정도의 스레드를 사용하는 경우는 있습니다. 또한 앞으로 멀티

코어 머신이 일반화된다 하더라도 물리 시뮬레이션이나 화면 표시처리에만 다수의 코어를

사용하는 등 그 용도는 한정될 것입니다. 게임의 처리 로직을 다수의 스레드를 사용하여 구

현하는 것은 어렵습니다.

두 가지 프로그래밍 기법의 유사성

스레드를 사용하지 않는다

위와 같이 스레드를 사용하지 않는다는 점은 앞서 설명한 네트워크 프로그래밍에서 나온

서버를 만드는 방식과 같다는 것을 눈치 채셨는지요? 각각을 비교해 보면 다음과 같은 비

슷한 점이 있습니다.

네트워크 프로그래밍

모든 소켓에 대해 select()를 호출하고 폴링하여 처리가 필요한 것에 대해서 read나 write를 하고, 콜

백 함수를 호출하여 조금씩 실행한다.

게임 프로그래밍

모든 가동물(여기서는 스프라이트 클래스의 인스턴스)에 대해서 매 프레임마다 폴링하고, 처리가 필요

한 것에 대해서는 콜백 함수로 조금씩 동작시킨다(move나 hit한다).

병렬로 작동시키고 싶은 물체의 수가 프로세서 코어 수의 수십 배 이상이거나, 처리순서를

엄밀하게 제어해야 할 때는 스레드를 사용한 구현은 불가능할지도 모릅니다.

Page 88: 온라인 게임을 지탱하는 기술

88 제0장 _ [속성] 온라인 게임 프로그래밍

0.5

요약

이상으로 간단하게나마 일반적인 게임 프로그래밍과 네트워크 프로그래밍 기법의 기초를 소개하였습니

다. 어느 정도의 기초 기술이 필요한 것인지 감이 오나요? 이 장의 기초지식을 근거로 다음 장부터는 온라

인 게임의 상세한 내용을 파헤쳐 봅시다.

Column

개발 효율과 플랫폼 간의 이식성 확보

클라우드 인프라 서비스(IaaS, Infrastructureas a Service)가 리눅스 서버를 주요 타켓으로 하는 경우가

많으므로, 온라인 게임의 개발에서 상용 서버의 운용 환경 플랫폼은 리눅스계인 레드 햇 리눅스(Red Hat

Linux)39나 CentOS계40가 주류가 되어가고 있습니다. 한편 클라이언트의 플랫폼 환경은 아이폰, 웹

브라우저, 윈도우, 안드로이드, 휴대 전화, 게임기 등으로 다양성이 유지되고 있습니다.

개발 효율을 높이기 위하여

따라서, 개발 효율을 높이기 위한 플랫폼에 관한 주된 요구 사항으로 두 가지를 들 수 있을 것입니다.

• 상용 서버의 OS는 리눅스로 하고 싶지만, 개발 환경은 윈도우에서 비주얼 스튜디오(Visual Studio)를

사용하여 효율적으로 개발을 하고 싶다.

• 서버 측과 클라이언트 측에서 동일한 게임 처리 코드를 사용하고 싶다.

두 가지 모두 「같은 프로그램을 서로 다른 OS상에서 작동시키고 싶다=이식성의 확보」라는 요구 사항으로

이어집니다.

덧붙이자면 이러한 요구사항은 C/S MMO이면서, 서버와 클라이언트에서 같은 프로그래밍 언어를 이용

하는 경우에 한정된 이야기입니다. 즉 클라이언트와 서버 양쪽 모두를 C/C++/자바로 작성하는 경우입니

다. 참고로 서버와 클라이언트를 동일한 언어로 작성하기 위한 선택지로는 현실적으로 C/C++/자바밖에

39  URL http://www.jp.redhat.com/

40  URL URL http://www.centos.org/

Page 89: 온라인 게임을 지탱하는 기술

0.5 요약 89

없습니다. 하지만 앞으로는 C#나 Objective-C, Go 언어 등이 대안이 될 가능성이 높으며, 스크립트 언어

도 포함한다면 node.js41 등의 유력한 후보가 있습니다.

P2P MO는 서버를 가지지 않기 때문에 이러한 요구사항은 기본적으로 발생하지 않습니다.

래퍼(Wrapper)를 준비하여 소스 레벨에서 호환성을 유지한다

화면 표시 처리, 음성 출력, 키보드나 마우스의 입력, 화면 터치, 비디오 출력 등 클라이언트 측에서 유저의

체험을 실현하기 위한 기능을 제외한다면, C/C++를 이용하는 경우 현재는 간단한 래퍼를 준비하는 것으

로 소스 코드 레벨에서의 호환성을 유지할 수 있습니다. 이 래퍼는 통신 미들웨어 계층에서 실현하는 것이

일반적입니다.

OS의 차이를 포용하는 래퍼의 일

OS의 차이를 포용하는 래퍼는 다음과 같은 것을 랩(Wrap)할 필요가 있습니다.

메모리 관리

malloc은 대부분의 시스템에서 이용 가능하므로 랩하는 것은 간단하다.

소켓 API윈도우와 유닉스계(iOS 포함)에서는 소켓 API의 사양이 다르므로, 함수군을 모두 한번 랩할 필요가 있다.

스레드

POSIX 스레드(pthread)의 기본적인 API를 랩한다면 충분할 것이다. 스레드를 사용하는 부분은 클라이

언트에 한정시키도록 한다. 스케줄링의 플래그 등 세세한 부분에 대해서는 OS마다 호환성이 없지만, 이

책에서 추천하고 있는 것처럼 다수의 스레드를 구사하지 않고 싱글 스레드로 서버를 구현하는 방식이라면

문제가 되지 않는다. 전혀 스레드를 사용하지 않는 경우는 서버 측과 소스를 공유할 필요가 없으므로 랩할

필요는 없다.

시그널

서버를 원격에서 관리하는 경우 시그널을 사용하는 경우에는 필요하지만, 시그널은 이식성이 낮은 방법이

므로 추천하지 않는다. TCP상에 관리용 HTTP 서버 등을 구현하여 소켓을 통해 서버를 정지하도록 구

현하는 편이 이식성은 높아진다.

이벤트와 타이머

이 책에서 소개한 libevent을 사용하면 효과적으로 랩할 수 있어 문제없이 빠르다.

기본적으로는 POSIX의 표준에 가까운 인터페이스가 되도록 랩하면 전체의 작업량이 적어집니다.

41  URL URL http://nodejs.org/

Page 90: 온라인 게임을 지탱하는 기술

90 제0장 _ [속성] 온라인 게임 프로그래밍

이상과 같은 OS의 차이를 포용하기 위한 래퍼로서 Qt42나 Boost43와 같은 범용(대규모) 라이브러리

를 사용하는 것에 익숙해진 기술자도 많을 것입니다. 캡콤사 등 사내에서 독자적으로 개발한 라이브러리

를 사용하는 기업도 많습니다. 자신이 익숙한 라이브러리가 대상 플랫폼에서 이용 가능하다면 당연히 그

것을 사용하는 것이 좋을 것입니다.

42 큐트라고 불립니다. URL U] http://qt.nokia.com/title-jp/

43  URL [URL]http://www.boost.org/