[부록] Boost.Asio 비동기 네트워크 코어 엔지니어링 바이블 및 전사 레퍼런스

부록: Boost.Asio 비동기 네트워크 코어
엔지니어링 바이블 및 전사 레퍼런스 사전
- Reactor vs Proactor 아키텍처, run/poll/run_one 스케줄링, post/dispatch/defer 큐잉, make_work_guard 생명선, asio::strand 직렬화 원리, any_io_executor 다형성, system_executor 오프로딩, 풀 모델 비교, restart/stop, 5대 고장 진단 치트시트
• Appendix B. TCP & UDP 고성능 소켓 네트워킹 핵심 패턴 사전 (10 Pages)
- 소켓 생명주기 완벽 해부, Partial Send와 async_write, 스트림 경계와 transfer_exactly, streambuf 제로카피 파이프라인, 4대 필수 소켓 옵션, UDP 데이터그램과 1472B MTU, 브로드캐스트/멀티캐스트 로비 탐색, UDP 비동기 송신 큐, DNS 듀얼스택, 와이어샤크 덤프 치트시트
• Appendix C ~ G. 코루틴, MySQL, 커널 백서, 프로토콜 바이블, 찾아보기 (10 Pages)
- C++20 코루틴 비동기 코어, cancellation_signal 취소 가드, Boost.MySQL 핵심 API, SQLite3 7대 PRAGMA 튜닝표, C100K 커널 파라미터 백서, systemd 무인 서비스 유닛 규격, NetDebugger 8바이트 헤더 & 패킷 ID 바이블, Fletcher-16 알고리즘 백서, A to Z 용어 사전, 본서 찾아보기(Index)
io_context 핵심 수명주기 및 엔진 제어 API 완제표
Boost.Asio 비동기 I/O의 코어 엔진인 io_context 클래스의 초기화, 실행자 획득, 멀티프로세스 fork 통지 등 핵심 라이프사이클 관리 함수의 시그니처와 매개변수, 10만 동접 실전 팁을 상세히 정리한 레퍼런스입니다.
| 함수명 및 시그니처 | 매개변수 및 반환형 | 핵심 동작 및 내부 메커니즘 | 10만 동접 실전 주의사항 |
|---|---|---|---|
io_context() |
반환: 없음 (생성자) | 기본 동시성 힌트로 비동기 엔진을 초기화합니다. OS 기본 epoll/kqueue/IOCP 인스턴스를 내부 커널에 생성합니다. | 스레드 풀 환경에서는 아래의 동시성 힌트 오버로드를 사용하는 것이 CPU 캐시 경합을 줄이는 데 유리합니다. |
io_context(int concurrency_hint) |
int concurrency_hint반환: 없음 |
스레드 풀 크기를 힌트로 제공하여 내부 작업 큐 락 경합(Lock Contention)을 최소화하도록 커널 디스패처를 최적화합니다. | 1인 경우 락을 완전히 생략하는 단일 스레드 최적화가 적용됩니다. std::thread::hardware_concurrency()를 전달하십시오. |
executor_type get_executor() noexcept |
매개변수: 없음 반환: io_context::executor_type |
본 io_context 인스턴스를 가리키는 경량 실행자(Executor) 객체를 반환합니다. |
비동기 함수나 코루틴에서 co_await asio::post(ioc.get_executor(), ...) 형태로 스케줄링 시 필수 사용됩니다. |
void notify_fork(fork_event event) |
fork_event event반환: void |
리눅스 환경에서 fork() 호출 시 부모와 자식 간 파일 디스크립터 충돌을 방지하기 위해 epoll 인스턴스를 재생성합니다. |
이벤트 순서: fork_prepare(포크 직전) → fork_parent(부모) → fork_child(자식). 누락 시 자식 프로세스 epoll 먹통 발생. |
~io_context() |
반환: 없음 (소멸자) | 엔진을 파괴하고 등록된 모든 I/O 서비스와 OS 디스크립터를 해제합니다. | 반드시 모든 워커 스레드가 join()되고 모든 비동기 작업이 취소/완료된 후에 소멸해야 합니다. 미준수 시 크래시(SIGSEGV). |
io_context는 프로세스 수명주기 동안 싱글톤 또는 명시적 관리 하에 단 1개(또는 코어 수만큼의 풀)로 운용되어야 하며, 핸들러 콜백 내부에서 객체가 임의 파괴되지 않도록 shared_ptr로 수명을 철저히 보존해야 합니다.
run(), poll(), run_one() 스케줄링 및 루프 제어 API 완제표
이벤트 루프의 실행, 블로킹/논블로킹 제어, 타임아웃 실행 및 루프 재시작을 관장하는 핵심 멤버 함수의 전수 레퍼런스입니다.
| 함수명 및 시그니처 | 매개변수 및 반환형 | 동작 특성 및 블로킹 여부 | 10만 동접 실전 주의사항 |
|---|---|---|---|
count_type run() |
반환: count_type (실행 완료된 핸들러 수) |
모든 작업이 소진되거나 stop()될 때까지 블로킹 상태로 대기하며 I/O 이벤트를 처리합니다. |
미완료 작업(Work)이 없으면 즉시 0을 반환하고 종료되므로 반드시 make_work_guard와 병행해야 합니다. |
count_type run_one() |
반환: count_type (0 또는 1) |
대기 중인 이벤트 중 단 1개의 핸들러만 실행하고 즉시 반환합니다. 작업이 없으면 블로킹 대기합니다. | 단계별 디버깅이나 단일 스레드 UI 이벤트 루프와 Asio를 연동할 때 1회씩 펌핑하는 용도로 적합합니다. |
count_type run_for(rel_time) |
chrono::duration rel_time반환: count_type |
지정된 상대 시간(예: 10ms) 동안만 블로킹 실행 후 반환합니다. 작업이 소진되면 조기 반환합니다. | 게임 서버의 60Hz 틱 루프에서 잔여 프레임 시간(Frame Budget) 동안만 네트워크를 처리할 때 유용합니다. |
count_type poll() |
반환: count_type (실행된 핸들러 수) |
전혀 블로킹되지 않으며, 현재 호출 시점에 완료 준비된 모든 핸들러를 일괄 실행 후 즉시 반환합니다. | 루프가 비어있을 때 CPU 100% 점유율(Busy-Wait)을 초래하므로 타이머 인터벌이나 sleep 없이 무한루프 호출 금지. |
count_type poll_one() |
반환: count_type (0 또는 1) |
논블로킹으로 준비된 핸들러 1개만 실행 후 즉시 리턴합니다. | 초당 100만 건 이상의 고빈도 트레이딩(HFT) 엔진에서 폴링 기반 마이크로 스케줄링 시 사용됩니다. |
void stop() |
반환: void |
실행 중인 run() 루프를 강제 중단시킵니다. 대기 중인 잔여 작업은 실행되지 않고 무시됩니다. |
모든 워커 스레드의 run()이 즉각 빠져나옵니다. 안전한 셧다운을 위해서는 소켓을 먼저 닫아야 합니다. |
void restart() |
반환: void |
중단(stopped) 상태의 io_context를 리셋하여 다시 run()을 호출할 수 있는 상태로 만듭니다. |
run()이 정상 또는 강제 종료된 후 동일 인스턴스를 재사용하려면 반드시 먼저 restart()를 호출해야 함. |
ioc.run()을 걸어두는 블로킹 모델이 가장 효율적이며, 게임 엔진 클라이언트에서는 프레임 렌더링 루프마다 ioc.poll()을 펌핑하는 방식이 정석입니다.
post(), dispatch(), defer() 핸들러 큐잉 및 바인딩 API 완제표
비동기 작업의 실행 순서, 스레드 전환 및 핸들러와 실행자 간의 결합을 관장하는 무료 함수(Free Functions)의 시그니처와 뉘앙스 비교표입니다.
| 함수명 및 시그니처 | 매개변수 및 반환형 | 동작 원리 및 스케줄링 시점 | 10만 동접 실전 주의사항 |
|---|---|---|---|
post(executor, handler) |
Executor ex, Handler h반환: void |
현재 호출 스레드와 무관하게 핸들러를 무조건 큐의 후미에 적재하여 다음 이벤트 루프 턴에 실행합니다. | 스택 오버플로우를 100% 방지하므로 재귀적 비동기 체인이나 타 스레드로 작업을 완전히 넘길 때 최우선 선택입니다. |
dispatch(executor, handler) |
Executor ex, Handler h반환: void |
현재 호출 스레드가 대상 executor의 스레드와 일치하면 즉시 인라인(Inline) 동기 호출하고, 다르면 큐에 넣습니다. | 큐잉 오버헤드와 컨텍스트 스위칭을 제거하여 극강의 레이턴시 단축을 제공하나, 깊은 재귀 호출 시 콜스택 폭발에 주의하십시오. |
defer(executor, handler) |
Executor ex, Handler h반환: void |
현재 실행 중인 핸들러가 완전히 끝난 직후 동일 스레드에서 가장 빠른 시점에 연속 실행되도록 힌트를 줍니다. | 락 해제 직후 후속 연산을 같은 코어에서 L1 캐시 친화적으로 이어서 처리할 때 매우 유용합니다. |
bind_executor(ex, handler) |
Executor ex, Handler h반환: 래핑된 핸들러 객체 |
핸들러에 특정 strand나 executor를 영구적으로 바인딩하여 어디서 호출되든 해당 컨텍스트에서 실행되도록 강제합니다. | 비동기 I/O 함수(예: async_read)에 strand를 넘길 때 핸들러 인자로 bind_executor(strand, handler)를 전달합니다. |
get_associated_executor(h) |
Handler h반환: 연관 실행자 |
핸들러 객체에 묶여 있는 실행자를 조회합니다. 명시적으로 묶인 것이 없으면 시스템 기본 실행자를 반환합니다. | 자체 비동기 프레임워크나 완성 토큰(Completion Token) 커스텀 어댑터를 제작할 때 핸들러의 실행 환경 보존에 필수적입니다. |
dispatch, 다른 워커 스레드로 작업을 분산하거나 무한 루프 재귀가 우려되는 네트워크 I/O 수신 체인은 post를 사용하는 것이 정석입니다.
make_work_guard 및 executor_work_guard 생명선 수호 API 완제표
비동기 작업이 0개인 유휴 상태에서도 이벤트 루프(run())가 조기 종료되지 않고 영구히 대기하도록 보장하는 워크 가드의 핵심 API입니다.
| 함수명 및 시그니처 | 매개변수 및 반환형 | 동작 원리 및 생명선 역할 | 10만 동접 실전 주의사항 |
|---|---|---|---|
make_work_guard(ioc) |
io_context& ioc반환: executor_work_guard<...> |
I/O 컨텍스트의 내부 작업 카운터를 1 증가시켜 큐에 남은 작업이 없어도 run()이 리턴되지 않도록 묶어둡니다. |
서버 시작 시점에 인스턴스를 생성하여 보관하고, 프로세스 종료 시점에 reset()해야 워커 스레드가 안전하게 종료됩니다. |
make_work_guard(executor) |
Executor ex반환: executor_work_guard<Executor> |
임의의 실행자(strand, thread_pool 등)에 대해 작업 보존 가드를 생성합니다. | 특정 strand에 대기 중인 세션 작업이 간헐적으로 끊길 때 해당 strand 큐의 수명을 유지하는 용도로 활용됩니다. |
void reset() noexcept |
반환: void |
유지 중이던 가드를 해제하여 작업 카운터를 1 감소시킵니다. owns_work()가 false가 됩니다. |
Graceful Shutdown 시 가장 먼저 호출해야 하는 함수입니다. 이를 부르지 않고 스레드 join()을 걸면 무한 데드락에 빠집니다. |
bool owns_work() const noexcept |
반환: bool |
본 가드 객체가 현재 작업을 활성 상태로 보유하고 있는지 확인합니다. | 이중 reset() 호출 방지 및 셧다운 시퀀스의 유효성 검증(Assertion)에 사용됩니다. |
executor_type get_executor() |
반환: 대상 Executor |
가드가 결합되어 있는 대상 실행자 인스턴스를 인출합니다. | 가드를 통해 직접 작업을 스케줄링하거나 소속 I/O 컨텍스트를 역추적할 때 사용됩니다. |
acceptor.close()로 신규 접속 차단 → 2단계: work_guard.reset()으로 생명선 해제 → 3단계: 기존 세션 패킷 소진 후 워커 스레드 worker_threads.join(). 이 순서를 지켜야 데이터 유실 제로 달성.
asio::strand 동기화 및 핸들러 직렬화 실행자 API 완제표
멀티스레드 환경에서 뮤텍스(Mutex) 없이 원자적이고 순차적인 핸들러 실행을 보장하는 락-프리 직렬화 실행자의 시그니처 레퍼런스입니다.
| 함수명 및 시그니처 | 매개변수 및 반환형 | 동작 원리 및 락-프리 직렬화 | 10만 동접 실전 주의사항 |
|---|---|---|---|
make_strand(ioc) |
io_context& ioc반환: strand<io_context::executor_type> |
지정된 I/O 컨텍스트를 기반으로 동작하는 새로운 strand 직렬화 실행자를 생성합니다. | 게임 세션(TcpSession)마다 독립적인 strand를 1개씩 부여하여 세션별 완전 무경합 병렬 처리를 구축하십시오. |
void execute(Function&& f) |
Function&& f반환: void |
C++20 표준 실행자 인터페이스를 통해 함수 f를 strand의 직렬화 큐를 거쳐 안전하게 실행합니다. | 동일 strand에 제출된 작업은 결코 2개 이상의 스레드에서 동시 실행되지 않으므로 세션 멤버 변수의 데이터 레이스가 0%입니다. |
strand::post(handler) |
Handler h반환: void |
strand 대기열에 핸들러를 비동기 적재합니다. 이전 핸들러가 끝난 뒤 순차 실행됩니다. | 타 스레드에서 특정 세션으로 귓속말이나 공격 판정 패킷을 전달할 때 post(session->strand, ...)로 락 없이 전달합니다. |
strand::dispatch(handler) |
Handler h반환: void |
현재 스레드가 이미 본 strand 내부에서 실행 중인 경우 즉시 인라인 호출하여 큐잉 오버헤드를 건너뜁니다. | 세션 내부에서 연속된 비동기 작업 체이닝 시 컨텍스트 스위칭 비용을 최소화합니다. |
bool running_in_this_thread() |
반환: bool |
현재 코드를 실행 중인 스레드가 본 strand의 보호 영역 내부인지 여부를 판별합니다. | 디버그 빌드 시 assert(strand.running_in_this_thread());를 걸어 스레드 안전성 위반을 런타임에 즉각 적발하십시오. |
any_io_executor 다형성 실행자 및 속성 쿼리 API 완제표
다양한 실행자 타입(io_context, strand, thread_pool)을 템플릿 코드 비대화 없이 단일 인터페이스로 추상화하는 타입 소거(Type Erasure) 래퍼 API입니다.
| 함수명 및 시그니처 | 매개변수 및 반환형 | 핵심 동작 및 타입 소거 메커니즘 | 10만 동접 실전 주의사항 |
|---|---|---|---|
any_io_executor() noexcept |
반환: 없음 (생성자) | 비어있는(nullptr 상태) 다형성 실행자 인스턴스를 생성합니다. | 비어있는 객체에 execute() 호출 시 bad_executor 예외가 발생하므로 사용 전 유효성을 확인해야 합니다. |
any_io_executor(Executor ex) |
Executor ex (임의의 실행자)반환: 없음 |
io_context, strand 등 임의의 구체 실행자를 타입 소거하여 보관합니다. 소형 객체 최적화(SBO)가 지원됩니다. | 네트워크 라이브러리 인터페이스에서 템플릿 대신 any_io_executor를 받으면 헤더 의존성과 빌드 시간을 대폭 절감합니다. |
target<Executor>() noexcept |
템플릿 타입 Executor반환: Executor* (또는 nullptr) |
보관 중인 구체 실행자 포인터를 안전하게 다운캐스팅하여 인출합니다. 타입 불일치 시 nullptr를 반환합니다. | 런타임에 대상이 특정 strand인지 판별하여 특화 처리를 수행할 때 사용됩니다. |
const std::type_info& target_type() |
반환: const std::type_info& |
현재 내부에 보관 중인 실행자의 런타임 타입 정보를 반환합니다. | 로그 기록이나 프레임워크 텔레메트리에서 실행자 바인딩 상태를 디버깅할 때 활용됩니다. |
query(ex, execution::context) |
execution::context_t반환: execution_context& |
실행자가 소속된 최상위 execution_context(예: io_context)의 참조를 인출합니다. |
실행자 객체만 전달받은 하위 함수에서 부모 io_context의 타이머나 서비스를 역조회할 때 필수적입니다. |
any_io_executor가 표준 통일 인터페이스로 확립되었습니다. 소켓 및 코루틴 API의 기본 반환 실행자 타입으로 채택되어 있습니다.
system_executor 및 thread_pool 백그라운드 오프로딩 API 완제표
암호화 연산, 압축 해제, 파일 I/O 등 무거운 CPU 바운드 작업을 메인 네트워크 루프에서 분리하여 백그라운드 풀로 오프로딩하는 실행자 API입니다.
| 함수명 및 시그니처 | 매개변수 및 반환형 | 동작 원리 및 스레드 할당 모델 | 10만 동접 실전 주의사항 |
|---|---|---|---|
system_executor() noexcept |
반환: system_executor |
운영체제 전역 백그라운드 시스템 스레드 풀을 사용하는 글로벌 싱글톤 실행자를 반환합니다. | 별도의 풀 인스턴스 생성 없이 asio::post(system_executor(), fn) 형태로 즉시 CPU 무거운 작업을 던질 수 있습니다. |
thread_pool(std::size_t num_threads) |
size_t num_threads반환: 없음 (생성자) |
지정된 개수의 전용 OS 스레드로 구성된 독립적인 작업자 스레드 풀 인스턴스를 생성합니다. | 패스워드 해싱(Bcrypt), zlib 패킷 압축 등 CPU 집중 전용 풀로 메인 I/O 루프와 분리 격리할 때 최적입니다. |
thread_pool::get_executor() |
반환: thread_pool::executor_type |
해당 스레드 풀로 작업을 발행할 수 있는 전용 실행자 객체를 반환합니다. | 코루틴에서 co_await asio::post(pool.get_executor(), use_awaitable); 형태로 스레드를 원터치 점프할 수 있습니다. |
void thread_pool::join() |
반환: void |
풀 내의 모든 워커 스레드가 큐에 적재된 모든 작업을 완료할 때까지 블로킹 상태로 대기합니다. | 서버 종료 시 잔여 배치 계산이나 DB 비동기 직렬화 작업이 100% 디스크에 커밋되도록 보장합니다. |
void thread_pool::stop() |
반환: void |
풀의 모든 작업을 즉각 중단하고 대기 중인 스레드를 강제 종료합니다. | 긴급 셧다운 시 사용하며, 일반 셧다운 시에는 데이터 유실 방지를 위해 join()을 우선 사용하십시오. |
co_await post(pool.get_executor(), use_awaitable); → 3) 고부하 복호화 연산 수행 (워커 스레드) → 4) co_await post(session_strand, use_awaitable); 세션 스레드로 안전 복귀.
steady_timer 고정밀 타이머 및 클럭 동기화 API 완제표
단조 증가 시계(std::chrono::steady_clock) 기반으로 OS 시간 왜곡 없이 60Hz 틱 루프와 핑 타임아웃을 정밀 계측하는 타이머 API입니다.
| 함수명 및 시그니처 | 매개변수 및 반환형 | 동작 원리 및 정밀도 | 10만 동접 실전 주의사항 |
|---|---|---|---|
steady_timer(ioc) |
io_context& ioc반환: 없음 (생성자) |
지정된 I/O 컨텍스트를 타이머 큐로 삼는 고정밀 비동기 단조 타이머를 생성합니다. | 시스템 시간 변경(NTP 동기화, 윤초)에 영향을 받지 않으므로 주기적 게임 루프에 반드시 사용해야 합니다. |
void expires_after(duration expiry) |
chrono::duration expiry반환: std::size_t (취소된 핸들러 수) |
현재 시점으로부터 상대적 시간(예: 16.666ms, 30s) 이후 만료되도록 설정합니다. 이전 대기 작업은 취소됩니다. | 기존 대기 중이던 비동기 핸들러에는 asio::error::operation_aborted 에러 코드가 전달됩니다. |
void expires_at(time_point expiry) |
chrono::time_point expiry반환: std::size_t (취소된 핸들러 수) |
절대 시점에 만료되도록 설정합니다. 정기적인 정각 이벤트나 누적 오차 없는 고정 주기 루프에 적합합니다. | timer.expires_at(timer.expiry() + 16666us); 패턴을 사용하면 타이머 드리프트(누적 지연)가 0이 됩니다. |
async_wait(handler) |
Handler h(error_code)반환: completion token 반환형 |
타이머 만료 시 비동기로 핸들러나 코루틴을 깨웁니다. | 콜백 내부에서 if (ec == asio::error::operation_aborted) return; 체크를 반드시 수행해야 세션 종료 크래시를 방지함. |
std::size_t cancel() |
반환: std::size_t (취소된 작업 수) |
대기 중인 타이머를 즉시 중단하고 모든 대기 핸들러에 operation_aborted를 전달합니다. |
클라이언트에서 핑 응답 패킷이 도착했을 때 대기 중이던 킵얼라이브 타임아웃 타이머를 해제하는 데 사용됩니다. |
while (!stopped) { auto next = std::chrono::steady_clock::now() + 16666us; UpdateWorld(); timer.expires_at(next); co_await timer.async_wait(use_awaitable); } → 슬립 누적 오차 완전 박멸.
signal_set OS 시그널 처리 및 프로세스 라이프사이클 API 완제표
SIGINT(Ctrl+C), SIGTERM(systemd 종료 신호), SIGHUP(설정 재로드) 등 OS 프로세스 시그널을 비동기로 안전하게 포획하는 API입니다.
| 함수명 및 시그니처 | 매개변수 및 반환형 | 동작 원리 및 비동기 시그널 처리 | 10만 동접 실전 주의사항 |
|---|---|---|---|
signal_set(ioc, signals...) |
io_context& ioc, int...반환: 없음 (생성자) |
생성과 동시에 감시할 시그널 번호들(SIGINT, SIGTERM 등)을 등록하여 Asio 엔진에 바인딩합니다. | 전통적 C 시그널 핸들러의 치명적 한계(비동기 신호 안전 함수만 호출 가능)를 벗어나 모든 C++ 객체를 자유롭게 다룰 수 있습니다. |
void add(int signal_number) |
int signal_number반환: boost::system::error_code |
감시 대상 OS 시그널 번호를 동적으로 추가 등록합니다. | 운영 중 설정 리로드용 SIGHUP이나 로그 파일 로테이션용 SIGUSR1을 추가 등록할 때 사용됩니다. |
void remove(int signal_number) |
int signal_number반환: boost::system::error_code |
등록된 특정 시그널의 감시를 해제하고 기본 OS 동작으로 복원합니다. | 셧다운 절차 진행 중 추가 SIGINT 발생 시 즉각 강제 종료로 전환하도록 핸들러를 해제할 때 활용됩니다. |
void clear() |
반환: boost::system::error_code |
등록된 모든 시그널을 일괄 제거하고 대기 중인 모든 비동기 작업을 취소합니다. | 서비스 종료 마무리 단계에서 시그널 세트 자원을 완전 정리할 때 호출합니다. |
async_wait(handler) |
Handler h(error_code, int sig)반환: completion token 반환형 |
등록된 시그널이 운영체제로부터 수신될 때까지 비동기로 대기하며 핸들러에 수신된 시그널 번호를 전달합니다. | 핸들러가 1회 실행되면 대기가 완료되므로, 지속 감시를 원할 경우 핸들러 내부에서 다시 async_wait를 재등록해야 합니다. |
SIGTERM을 signal_set으로 수신하여 즉각 NetworkService::Stop()을 트리거하면, 10만 동접 플레이어의 DB 상태를 안전하게 저장하고 0초 만에 깨끗이 종료됩니다.
io_context 10대 장애 진단 및 포렌식 치트시트 완제표
실전 게임 서버 운영 중 가장 빈번하게 발생하는 Boost.Asio I/O 코어의 10대 버그와 근본 원인 및 원클릭 해결책 완제표입니다.
| 발생 증상 | 근본 원인 (Root Cause) | 원클릭 해결책 (Fix Code) |
|---|---|---|
| run() 즉시 반환 종료 | 미완료 작업(Work)이 0개인 상태에서 호출됨 | auto guard = asio::make_work_guard(ioc); 추가 |
| 핸들러 미호출 먹통 | 비동기 함수만 예약하고 ioc.run() 스레드를 구동 안 함 |
std::thread([&]{ ioc.run(); }).detach(); 생성 |
| 세션 종료 시 크래시 | 비동기 작업 실행 도중 TcpSession 객체가 파괴됨 |
핸들러 람다에 [self = shared_from_this()] 수명 연장 바인딩 |
| SIGPIPE 크래시 | 상대방이 닫은 소켓에 write() 수행 시 OS 강제 종료 |
소켓 옵션 및 signal(SIGPIPE, SIG_IGN); 커널 신호 무시 |
| CPU 100% 점유 현상 | 유휴 상태에서 poll()을 조건/슬립 없이 무한 루프 호출 |
블로킹 run()으로 교체하거나 최소 1ms 타이머 인터벌 부여 |
| 동시성 데이터 레이스 | 멀티스레드 run() 환경에서 세션 변수를 동기화 없이 접근 |
세션 핸들러를 asio::bind_executor(strand_, handler)로 직렬화 |
| 스택 오버플로우 폭발 | dispatch()를 재귀적으로 무한 호출하여 콜스택 소진 |
비동기 반복 체인 호출 시 asio::post()로 강제 스택 언와인딩 |
| 서버 셧다운 데드락 | work_guard.reset()을 안 하고 워커 스레드 join() 호출 |
guard.reset(); acceptor.close(); 후 join() 실행 |
| 연결 누수 (Too many open files) | 에러 발생 시 소켓 close() 누락으로 FD 고갈 |
error_code 검사 블록에서 반드시 socket_.close(); 호출 |
| 포크 후 자식 프로세스 먹통 | fork() 후 epoll 파일 디스크립터가 부모와 엉킴 |
fork() 직후 ioc.notify_fork(asio::io_context::fork_child); |
lsof -p <PID> | wc -l (FD 누수 실측) → 2) gdb -p <PID> -ex "thread apply all bt" (스레드 교착 상태 역추적) → 3) perf top -p <PID> (CPU 100% 핫스팟 함수 실시간 탐색).
tcp::socket 핵심 수명주기 및 연결 제어 API 완제표
연결 지향형 스트림 통신의 주체인 tcp::socket의 오픈, 바인딩, 연결 수립, 반이중 종료 및 소켓 닫기를 관장하는 핵심 API 레퍼런스입니다.
| 함수명 및 시그니처 | 매개변수 및 반환형 | 동작 원리 및 TCP 상태 전이 | 10만 동접 실전 주의사항 |
|---|---|---|---|
void open(protocol) |
const protocol_type& p반환: void (예외 발생) |
OS 커널에 소켓 파일 디스크립터(IPv4/IPv6 TCP 소켓)를 생성합니다. | 수동 생성 시 사용하며, 통상 acceptor나 async_connect에서 내부 자동 오픈됩니다. |
void close() |
반환: void (또는 error_code) |
소켓 디스크립터를 즉각 닫고 OS 커널 리소스를 반환합니다. 대기 중인 모든 비동기 작업이 취소됩니다. | 반드시 에러 핸들러 내부에서 호출하여 FD 누수를 방지하십시오. 호출 후 is_open()은 false가 됩니다. |
void shutdown(how) |
shutdown_type how반환: void |
TCP FIN 플래그를 전송하여 반이중(Half-close) 종료를 수행합니다: shutdown_send, shutdown_receive, shutdown_both. |
즉시 close()하지 않고 shutdown(shutdown_send)를 먼저 호출하면 잔여 버퍼를 안전하게 밀어낼 수 있습니다. |
void cancel() |
반환: void |
해당 소켓에 걸려있는 모든 미완료 비동기 I/O 작업을 즉시 취소하고 operation_aborted를 트리거합니다. |
타임아웃 발생 시 소켓 자체를 닫지 않고 특정 읽기/쓰기 작업만 중단시키고자 할 때 매우 유용합니다. |
async_connect(ep, h) |
endpoint ep, Handler h반환: completion token 반환형 |
원격 서버 엔드포인트로 3-Way Handshake(SYN)를 비동기로 개시합니다. | 게이트웨이-존 서버 간 분산 IPC 연결 시 재연결 루프와 연동하여 백오프 지연(Exponential Backoff)을 적용하십시오. |
socket.cancel() (미완료 작업 취소) → 2) socket.shutdown(shutdown_both, ec) (FIN 교환) → 3) socket.close(ec) (FD 반환) → 4) session_map.erase(id) (메모리 해제).
tcp::acceptor 접속 리스너 및 3-Way Handshake API 완제표
클라이언트의 인바운드 TCP 연결 요청(SYN)을 대기하고 수락하여 독립 세션 소켓을 생성하는 리스너 API입니다.
| 함수명 및 시그니처 | 매개변수 및 반환형 | 동작 메커니즘 및 커널 백로그 | 10만 동접 실전 주의사항 |
|---|---|---|---|
acceptor(ioc, endpoint) |
io_context&, endpoint반환: 없음 (생성자) |
지정된 IP와 포트로 소켓 오픈, 바인드, 리슨(Listen)을 단일 단계로 원터치 수행합니다. | 기본 백로그 큐 크기(SOMAXCONN)가 적용되므로 10만 동접 환경에서는 아래의 명시적 분할 호출이 유리합니다. |
void listen(int backlog) |
int backlog반환: void |
OS 커널의 TCP 연결 대기 큐 크기를 설정하고 수신 대기 상태로 전환합니다. | 기본 128은 SYN 플러딩에 취약하므로 acceptor.listen(65535);로 최대치로 확장해야 접속 폭주 시 드롭이 없습니다. |
async_accept(peer, handler) |
tcp::socket& peer, Handler h반환: completion token 반환형 |
새로운 클라이언트 연결 수락 시 전달된 peer 소켓에 세션을 바인딩하고 핸들러를 호출합니다. |
핸들러 진입 즉시 다음 클라이언트를 맞이하기 위해 재귀적으로 DoAccept()를 최우선 호출해야 병목이 없습니다. |
async_accept(ioc, handler) |
io_context& ioc, Handler h반환: 신규 tcp::socket |
C++20 현대적 오버로드로, 수락 완료 시 내부에서 생성된 새 소켓 객체를 핸들러의 인자로 이동(Move) 전달합니다. | 코루틴에서 tcp::socket sock = co_await acceptor.async_accept(use_awaitable); 형태로 초간결 작성이 가능합니다. |
endpoint local_endpoint() |
반환: tcp::endpoint |
현재 리스너가 실제로 바인딩된 로컬 IP 주소와 포트 번호를 인출합니다. | 포트 번호 0(OS 동적 임시 포트 자동 할당)으로 바인딩한 후 실제 할당된 포트를 조회할 때 필수적입니다. |
SO_REUSEPORT 옵션을 활성화하면 여러 개의 Acceptor 인스턴스가 동일 포트(예: 8080)를 공유 바인딩하여 커널 레벨에서 CPU 코어별로 커넥션을 완전 무경합 분산합니다.
전역 비동기 스트림 I/O 무료 함수(Free Functions) API 완제표
부분 전송(Partial Send) 문제를 근본적으로 방지하고 지정된 완료 조건까지 자동 반복 루프를 도는 전역 무료 함수의 시그니처 레퍼런스입니다.
| 함수명 및 시그니처 | 매개변수 및 반환형 | 동작 원리 및 완료 조건 | 10만 동접 실전 주의사항 |
|---|---|---|---|
async_read(s, b, handler) |
Stream& s, MutableBuffer b반환: 완료 토큰 반환형 |
버퍼 공간이 100% 완전히 채워질 때까지 내부적으로 async_read_some을 자동 반복 호출합니다. |
고정 8바이트 패킷 헤더 수신 시 transfer_exactly(8) 조건과 결합하여 완벽한 패킷 프레이밍을 보장합니다. |
async_write(s, b, handler) |
Stream& s, ConstBuffer b반환: 완료 토큰 반환형 |
제공된 버퍼의 모든 바이트가 커널 송신 큐에 완전히 기록될 때까지 부분 전송(Partial Write)을 자동 처리합니다. | socket.async_write_some 대신 반드시 본 전역 함수를 사용해야 대용량 브로드캐스트 시 패킷 깨짐을 원천 방지함. |
async_read_until(s, dyn, d) |
Stream&, DynamicBuffer, Delim반환: 완료 토큰 반환형 |
동적 버퍼에 지정된 구분자(예:
또는 정규식)가 출현할 때까지 스트림 데이터를 누적 수신합니다. |
HTTP 게이트웨이 파싱이나 웹소켓 핸드셰이크 헤더 수신 시 구분자 이후의 초과 바이트(Over-read) 보존에 유의하십시오. |
async_read_at(d, off, b, h) |
Device&, uint64_t off, Buf반환: 완료 토큰 반환형 |
랜덤 액세스 지원 디바이스(비동기 파일 I/O 등)의 특정 파일 오프셋에서 데이터를 정확히 읽어들입니다. | 대용량 맵 데이터 비동기 스트리밍이나 리플레이 로그 파일의 특정 틱 구간을 읽을 때 활용됩니다. |
async_write_at(d, off, b, h) |
Device&, uint64_t off, Buf반환: 완료 토큰 반환형 |
랜덤 액세스 디바이스의 특정 오프셋에 버퍼 데이터를 비동기로 기록합니다. | 데이터베이스 트랜잭션 WAL 로그의 특정 슬롯에 제로카피로 고속 덤프할 때 사용됩니다. |
async_write 핸들러가 반환되기 전에 또 다른 async_write를 중복 호출하면 패킷 바이트가 뒤섞여 프로토콜이 파괴됩니다. 반드시 SendQueue를 통해 직렬화해야 합니다.
소켓 멤버 저수준 I/O 및 버퍼 송수신 함수 API 완제표
커널 소켓 버퍼와의 1:1 직접 인터페이스를 수행하는 소켓 멤버 함수들의 시그니처와 플래그 제어 레퍼런스입니다.
| 함수명 및 시그니처 | 매개변수 및 반환형 | 동작 원리 및 1회성 I/O | 10만 동접 실전 주의사항 |
|---|---|---|---|
read_some(buffers) |
MutableBufferSequence반환: size_t (실제 수신량) |
동기 블로킹 방식으로 1바이트라도 데이터가 도착하면 즉시 읽어 반환합니다. | 워커 스레드 블로킹을 방지하기 위해 실시간 서버 메인 루프에서는 사용을 엄격히 금하며 비동기 버전을 사용합니다. |
async_read_some(buf, h) |
MutableBuffer, Handler h반환: 완료 토큰 반환형 |
커널 수신 큐에 도착한 데이터 1회분을 비동기로 읽고 즉시 핸들러를 깨웁니다. (전체 버퍼 채움 미보장) | 자체 링버퍼(RingBuffer)를 소유한 고성능 제로카피 파서에서 데이터 수신 트리거용으로 가장 적합합니다. |
async_write_some(buf, h) |
ConstBuffer, Handler h반환: 완료 토큰 반환형 |
커널 송신 버퍼의 현재 빈 공간만큼만 데이터를 쓰고 실제로 기록된 바이트 수를 즉각 반환합니다. | 요청한 크기보다 적게 써질 수(Partial Write) 있으므로, 잔여 데이터를 추적 재전송하지 않으면 패킷 누락이 발생합니다. |
receive(buf, flags) |
Buffer b, message_flags flags반환: size_t |
플래그를 지원하는 저수준 수신입니다. 예: message_peek 플래그 사용 시 데이터를 큐에서 제거하지 않고 미리 봅니다. |
소켓 내부 헤더를 선검사(Snooping)하여 패킷 위변조를 신속히 사전 차단할 때 유용합니다. |
send(buf, flags) |
Buffer b, message_flags flags반환: size_t |
플래그를 지원하는 저수준 송신입니다. 예: message_out_of_band(긴급 데이터 전송) 지원. |
초긴급 서버 셧다운 경보 신호나 비상 하트비트를 OOB 채널로 즉시 타격할 때 활용됩니다. |
async_read(s, b, transfer_exactly(8)), 대용량 스트림을 링버퍼로 끊김 없이 쭉쭉 퍼담을 때는 s.async_read_some(ring_buf)를 선택하는 것이 최적의 설계입니다.
소켓 4대 필수 옵션 및 커널 파라미터 매핑 API 완제표
10만 동접 대용량 온라인 게임 서버의 초저지연과 고속 재기동을 보장하는 핵심 소켓 옵션 및 OS 시스템 콜 매핑 완제표입니다.
| 옵션 클래스명 | 시스템 콜 매핑 | 동작 원리 및 효과 | 10만 동접 실전 주의사항 |
|---|---|---|---|
tcp::no_delay(true) |
IPPROTO_TCP, TCP_NODELAY |
Nagle 알고리즘을 비활성화하여 작은 크기의 패킷(예: 이동, 공격)도 커널 버퍼링 없이 즉시 전송합니다. | 게임 서버의 1순위 필수 옵션입니다. 미적용 시 40ms~200ms의 치명적 인게임 조작 렉(Latency)이 발생합니다. |
reuse_address(true) |
SOL_SOCKET, SO_REUSEADDR |
서버 비정상 종료 시 포트가 TIME_WAIT 상태에 머물러 있어도 즉각 동일 포트로 재바인딩을 허용합니다. | Acceptor 오픈 직후 bind() 전에 반드시 설정해야 서버 크래시 후 무중단 즉각 재기동이 가능합니다. |
keep_alive(true) |
SOL_SOCKET, SO_KEEPALIVE |
OS 레벨에서 주기적으로 TCP 생존 확인 탐색 패킷(Probe)을 전송하여 고스트 세션을 색출합니다. | 스마트폰 클라이언트의 터널 진입/배터리 방전 등으로 FIN 없이 끊긴 좀비 세션을 커널 차원에서 자동 청소합니다. |
linger(true, 0) |
SOL_SOCKET, SO_LINGER |
소켓을 닫을 때 TIME_WAIT를 거치지 않고 RST 패킷을 즉시 보내며 커널 리소스를 0초 만에 회수합니다. | 악의적 디도스 봇 세션을 강제 축출할 때 커널 FD와 로컬 포트 고갈을 방지하는 강력한 방어 기법입니다. |
receive_buffer_size(N) |
SOL_SOCKET, SO_RCVBUF |
소켓별 OS 커널 수신 버퍼 크기를 지정합니다. (기본값: 보통 64KB~128KB) | 10만 세션 곱하기 128KB는 12.8GB RAM을 소비하므로, 세션당 16KB~32KB로 적정 축소 튜닝하여 메모리를 방어하십시오. |
socket.set_option(tcp::no_delay(true)); socket.set_option(socket_base::keep_alive(true)); socket.non_blocking(true); → 대용량 게임 서버의 절대 3대 불변 세팅.
udp::socket 비연결형 데이터그램 I/O API 완제표
핸드셰이크와 연결 유지 오버헤드 없이 초고속으로 독립 데이터그램을 교환하는 UDP 코어 함수의 시그니처 레퍼런스입니다.
| 함수명 및 시그니처 | 매개변수 및 반환형 | 동작 원리 및 데이터그램 전송 | 10만 동접 실전 주의사항 |
|---|---|---|---|
udp::socket(ioc, ep) |
io_context&, udp::endpoint반환: 없음 (생성자) |
UDP 소켓을 생성하고 지정된 로컬 포트에 바인딩하여 즉시 송수신 가능한 상태로 만듭니다. | TCP와 달리 Listen/Accept 단계가 없으며, 단 1개의 소켓으로 수만 명의 플레이어 패킷을 모두 처리합니다. |
async_send_to(buf, ep, h) |
ConstBuffer, endpoint, Handler반환: 완료 토큰 반환형 |
지정된 원격 목적지 IP/포트로 데이터그램을 비동기 송출합니다. | MTU(1500)를 고려하여 페이로드 크기를 1472바이트(IPv4) 이내로 제한해야 커널 패킷 단편화(Fragmentation)를 막습니다. |
async_receive_from(b, ep, h) |
MutableBuf, endpoint&, Handler반환: 완료 토큰 반환형 |
도착한 데이터그램을 읽고, 송신자의 IP/포트를 전달된 ep 변수에 기록합니다. |
버퍼 크기보다 큰 패킷이 도착하면 초과분이 잘려 유실(Truncation)되므로 최소 2048바이트 버퍼를 제공하십시오. |
std::size_t available() |
반환: std::size_t (바이트 수) |
현재 커널 UDP 수신 버퍼에 도착하여 읽을 수 있는 데이터 바이트 수를 반환합니다. | 0이면 현재 대기 중인 패킷이 없음을 의미하며, 블로킹 없이 패킷 유무를 사전 체크할 때 유용합니다. |
void connect(endpoint) |
const udp::endpoint&반환: void |
UDP 소켓에 기본 목적지 주소를 필터 바인딩합니다. (실제 TCP 핸드셰이크는 없음) | 커널에 대상 주소를 고정하여 send()/receive()를 쓸 수 있게 하며, 타 IP의 스푸핑 패킷을 커널이 자동 드롭합니다. |
UDP 멀티캐스트 & 브로드캐스트 네트워킹 API 완제표
동일 로컬 네트워크(LAN) 내에서 중앙 서버 없이 게임 방(로비)을 자동 탐색하고 동기화하는 멀티캐스트/브로드캐스트 제어 API입니다.
| 옵션 및 API 시그니처 | 소속 네임스페이스 | 동작 원리 및 IGMP 프로토콜 | 10만 동접 실전 주의사항 |
|---|---|---|---|
join_group(multicast_address) |
asio::ip::multicast |
지정된 D클래스 멀티캐스트 그룹(예: 239.255.0.1)에 가입하여 해당 패킷 수신을 커널에 등록합니다. | LAN 스위칭 허브에 IGMP 리포트를 전송하여 해당 그룹 패킷만 선별 수신하므로 네트워크 플러딩을 방지합니다. |
leave_group(multicast_address) |
asio::ip::multicast |
가입되어 있던 멀티캐스트 그룹에서 탈퇴합니다. | 게임 룸 퇴장 시 반드시 탈퇴를 호출해야 불필요한 인게임 동기화 패킷으로 인한 CPU 부하를 차단합니다. |
enable_loopback(bool) |
asio::ip::multicast |
동일 머신 내에서 자신이 전송한 멀티캐스트 패킷을 로컬 루프백으로 다시 수신할지 여부를 제어합니다. | 단일 PC에서 서버와 클라이언트를 동시 구동하여 개발/테스트할 때는 반드시 true로 설정해야 통신이 가능합니다. |
hops(int value) |
asio::ip::multicast |
멀티캐스트 데이터그램의 라우터 통과 제한 홉 수(TTL)를 설정합니다. (기본값: 1) | 1인 경우 로컬 서브넷 밖으로 나가지 못하므로, IDC 내부 사설망 간 통신 시에는 적절히 확장(예: 4~16)해야 합니다. |
socket_base::broadcast(true) |
asio::socket_base |
소켓의 제한 없는 브로드캐스트 패킷(255.255.255.255) 송출 권한을 활성화합니다. | 라우터를 통과할 수 없으므로 오직 동일 L2 스위치 영역 내의 LAN 전용 방 탐색 프로토콜에만 국한하여 사용하십시오. |
239.255.42.99:9000 멀티캐스트 주소로 매초 1회 RoomInfo 패킷을 핑하면, 같은 네트워크 내의 참가자 클라이언트들이 그룹 가입 상태에서 즉각 방 목록을 노출하는 구조가 표준입니다.
DNS 리졸버 & IP 주소 변환 유틸리티 API 완제표
도메인 네임을 IP 엔드포인트 목록으로 비차단 변환하고 IPv4/IPv6 듀얼스택 환경을 원활히 지원하는 리졸버 API입니다.
| 함수명 및 시그니처 | 매개변수 및 반환형 | 동작 원리 및 비동기 DNS 쿼리 | 10만 동접 실전 주의사항 |
|---|---|---|---|
async_resolve(host, svc, h) |
string host, svc, Handler반환: 완료 토큰 반환형 |
OS의 블로킹 getaddrinfo()를 백그라운드 스레드에서 수행하여 메인 루프 멈춤 없이 IP를 해석합니다. |
도메인 조회 지연(최대 수 초) 시 메인 I/O 루프가 동결되는 대재앙을 원천 방지합니다. |
results_type (반환 컨테이너) |
반환: tcp::resolver::results_type |
해석된 IPv4 및 IPv6 다중 엔드포인트 목록을 담고 있는 반복 가능한(Iterable) 범위 객체입니다. | asio::async_connect(sock, results, ...)와 연동하면 첫 번째 IP 실패 시 다음 IP로 자동 폴백 연결됩니다. |
void cancel() |
반환: void |
진행 중인 비동기 DNS 쿼리 작업을 즉시 중단시킵니다. | 클라이언트가 접속 시도 중 취소 버튼을 누르거나 연결 타임아웃 발생 시 불필요한 백그라운드 스레드 작업을 정리합니다. |
make_address(string_view) |
string_view str반환: asio::ip::address |
문자열 형태의 IP(예: "127.0.0.1", "::1")를 OS 주소 바이너리 객체로 고속 파싱합니다. | 예외를 던지지 않는 make_address(str, ec) 오버로드를 사용하여 잘못된 입력에 의한 서버 크래시를 방지하십시오. |
bool is_v4() / is_v6() |
반환: bool |
주소 객체가 IPv4 체계인지 IPv6 체계인지 판별합니다. | 애플 앱스토어의 IPv6-only 네트워크 심사 요건을 만족하기 위해 접속 엔드포인트 생성 시 필수로 분기 검사해야 합니다. |
asio::async_connect에 resolver.async_resolve 결과를 넘기면, IPv6 연결을 먼저 시도한 뒤 수십 ms 내 응답이 없으면 즉각 IPv4로 병렬 접속하여 글로벌 모바일 유저의 연결 성공률을 99.9%로 유지합니다.
버퍼 관리 & 제로카피 파이프라인 API 완제표
메모리 복사 비용을 극소화하고 Scatter-Gather I/O를 지원하는 Asio 버퍼 추상화 핵심 함수의 시그니처 레퍼런스입니다.
| 함수명 및 시그니처 | 매개변수 및 반환형 | 동작 원리 및 메모리 제로카피 | 10만 동접 실전 주의사항 |
|---|---|---|---|
buffer(ptr, size_in_bytes) |
void* ptr, size_t size반환: mutable_buffer / const_buffer |
원시 포인터와 길이를 메모리 복사 없이 Asio 표준 경량 버퍼 뷰(View) 객체로 포장합니다. | 데이터 소유권이 없으므로 비동기 I/O가 완료될 때까지 원본 ptr의 메모리가 유효하게 살아있어야 합니다. |
buffer(container) |
std::vector, std::array 등반환: buffer 뷰 |
표준 연속 컨테이너를 데이터 시작 주소와 크기를 자동 추론하여 버퍼 객체로 생성합니다. | 송신 도중 컨테이너에 원소를 추가하여 메모리 재할당(Reallocation)이 발생하면 댕글링 포인터가 되므로 엄격히 금지. |
streambuf::prepare(size_t n) |
size_t n반환: mutable_buffers_type |
수신 데이터를 담기 위해 스트림 버퍼 내부에서 n바이트 공간을 사전 예약(Reserve)합니다. | 네트워크에서 수신할 패킷 페이로드 크기만큼 정확히 공간을 열어 async_read에 넘길 때 사용합니다. |
streambuf::commit(size_t n) |
size_t n반환: void |
실제로 수신 완료된 n바이트를 읽기 가능한 유효 입력 시퀀스로 확정합니다. | prepare 후 commit을 호출하지 않으면 데이터가 버퍼에 존재해도 읽기 스트림에서 보이지 않습니다. |
streambuf::consume(size_t n) |
size_t n반환: void |
파싱이 완료된 n바이트를 버퍼에서 제거하여 앞쪽 메모리 공간을 회수합니다. | 패킷 헤더와 바디 처리가 끝날 때마다 정확한 바이트 수를 consume해야 버퍼 오버플로우가 발생하지 않습니다. |
std::vector<asio::const_buffer> bufs = { asio::buffer(&header, 8), asio::buffer(body) }; asio::async_write(sock, bufs, ...); → 헤더와 바디를 단일 버퍼로 합치는 메모리 복사(memcpy)를 100% 제거하는 최고의 기법.
소켓 네트워크 오류 코드 & 패킷 덤프 치트시트 완제표
실전 운영 중 접하는 대표적 소켓 에러 코드와 Wireshark 패킷 플래그의 상호 연관 분석 및 현장 조치표입니다.
| Boost 에러 상수 | POSIX / Wireshark | 근본 원인 (Root Cause) | 현장 즉각 조치 가이드 |
|---|---|---|---|
error::eof |
0 bytes / [FIN, ACK] |
클라이언트가 정상적으로 close()를 호출하여 TCP 세션을 우아하게 종료함. |
정상 퇴장 절차이므로 에러 로그를 남기지 말고 세션 맵에서 해당 유저를 깔끔하게 해제. |
error::connection_reset |
ECONNRESET / [RST] |
클라이언트 프로세스가 강제 종료(작업관리자 종료, 크래시)되어 OS가 RST 패킷을 발송함. | 비정상 종료이므로 세션 즉시 정리 및 월드 상의 캐릭터를 안전 좌표로 퇴장 처리. |
error::operation_aborted |
ECANCELED / N/A |
타이머 만료, 세션 셧다운 등으로 대기 중이던 비동기 작업이 cancel()됨. |
자연스러운 취소 신호이므로 아무런 에러 처리 없이 핸들러를 조용히 return할 것. |
error::broken_pipe |
EPIPE / [RST] 수신 후 Write |
이미 닫힌 소켓에 데이터를 강제로 쓰려고 시도할 때 발생함. | async_write 호출 전 socket_.is_open() 검사 및 소켓 즉시 소멸. |
error::timed_out |
ETIMEDOUT / SYN 재전송 5회 |
물리적 인터넷 단선 등으로 상대방 호스트로부터 아무런 ACK 응답이 오지 않음. | 하트비트 핑 누락 3회 초과 시 강제 연결 해제(Disconnect) 단행. |
error::connection_refused |
ECONNREFUSED / [RST, ACK] |
목적지 서버의 IP는 존재하나 해당 포트에서 Listen 중인 서버 프로세스가 없음. | 존 서버 데몬 활성화 상태 확인 및 방화벽 인바운드 포트 개방 검사. |
tcpdump -i any -nn port 8080 -w dump.pcap → 저장된 파일을 Wireshark에서 열고 필터에 tcp.flags.reset == 1 입력 시 비정상 종료된 세션의 패킷을 1초 만에 색출 가능.
C++20 코루틴 비동기 코어(ACO) 핵심 함수 전수 테이블
비동기 코루틴(Asio Coroutine Operations, ACO)을 구성하는 핵심 토큰, 스폰 함수 및 병렬 연산자의 시그니처와 상세 동작 완제표입니다.
| 함수 및 토큰 시그니처 | 소속 및 반환형 | 코루틴 중단 및 재개 메커니즘 | 10만 동접 실전 주의사항 |
|---|---|---|---|
co_spawn(ex, coro, token) |
boost::asio::co_spawn반환: completion token 결정형 |
코루틴을 대상 실행자(ex)의 이벤트 루프에 스케줄링하여 최초 실행을 기동(Spawn)합니다. | 세션 코루틴 실행 시 session->strand_를 첫 번째 인자로 전달하여 스레드 안전성을 원천 보장하십시오. |
use_awaitable |
asio::use_awaitable_t글로벌 싱글톤 객체 |
비동기 함수 호출 시 콜백 대신 코루틴 일시 정지(Suspend) 및 I/O 완료 시 재개(Resume)를 지시합니다. | co_await sock.async_read(buf, use_awaitable); 형태로 호출하며, 내부 에러 발생 시 시스템 예외를 throw합니다. |
awaitable<T> |
asio::awaitable<T, Executor>코루틴 반환형 |
C++20 표준 코루틴 프로미스(Promise) 타입을 감싸는 Asio 표준 코루틴 반환 래퍼입니다. | 코루틴 내부에서 co_return value;로 값을 반환하며, void인 경우 co_return;을 호출합니다. |
detached |
asio::detached_t글로벌 완료 토큰 |
결과값이나 완료 통지를 기다리지 않고 백그라운드에서 완전히 독립적으로 동작하도록 위임(Fire-and-Forget)합니다. | 결과 에러가 무시되므로, 코루틴 내부 최상단에 try-catch 블록을 두어 예기치 못한 크래시를 방지해야 합니다. |
redirect_error(token, ec) |
asio::redirect_error_t어댑터 함수 |
비동기 실패 시 C++ 예외(Exception)를 던지지 않고 boost::system::error_code 변수에 에러를 안전하게 수신합니다. |
예외 처리 오버헤드(Stack Unwinding)를 0으로 제거하여 초당 10만 패킷 처리 시 CPU 사용률을 대폭 절감합니다. |
operator&&(awaitable A, B) |
awaitable_operators |
두 비동기 작업을 병렬로 동시 실행하여 둘 다 완료될 때까지 대기하고 결과를 튜플로 반환합니다. | 플레이어의 위치 동기화와 인벤토리 갱신 작업을 비차단 병렬로 동시 수행할 때 매우 효과적입니다. |
operator||(awaitable A, B) |
awaitable_operators |
두 작업 중 먼저 완료되는 쪽을 취하고, 지연된 다른 쪽 작업은 취소 신호로 자동 중단시킵니다. | 소켓 읽기 작업과 타이머를 경쟁시켜 네트워크 타임아웃을 단 1줄로 구현하는 핵심 패턴입니다. |
auto res = co_await (sock.async_read(buf, use_awaitable) || timer.async_wait(use_awaitable)); → 타이머가 먼저 끝나면 소켓 읽기가 자동 취소되어 무응답 프리징 완벽 차단.
코루틴 취소 신호(Cancellation Slots) 및 타임아웃 제어 API 완제표
대기 중인 코루틴이나 비동기 체인에 취소 신호를 주입하여 고스트 세션과 메모리 누수를 방어하는 취소 슬롯 완제표입니다.
| 클래스 및 메서드 시그니처 | 매개변수 및 반환형 | 취소 신호 전파 동작 메커니즘 | 10만 동접 실전 주의사항 |
|---|---|---|---|
cancellation_signal() |
반환: 없음 (생성자) | 취소 이벤트를 방출할 수 있는 신호 송신 객체를 생성합니다. | 세션 객체 내부에 멤버 변수로 보유하여 클라이언트 접속 종료 시 취소 신호를 방출하는 데 사용합니다. |
void emit(cancellation_type) |
cancellation_type type반환: void |
슬롯에 바인딩된 비동기 작업으로 취소 신호를 전파합니다: terminal, partial, total. |
소켓 close() 없이도 대기 중인 모든 async_read가 operation_aborted로 즉각 안전 종료됩니다. |
cancellation_slot slot() |
반환: cancellation_slot |
신호 객체와 결합된 수신용 슬롯을 반환합니다. | bind_cancellation_slot(sig.slot(), handler) 형태로 비동기 핸들러에 전달하여 연결합니다. |
void slot::assign(Handler) |
CancellationHandler h반환: void |
취소 신호가 도달했을 때 실행될 콜백 핸들러를 등록합니다. | 사용자 정의 I/O 파이프라인이나 백그라운드 DB 쿼리 취소 함수를 슬롯에 등록할 때 사용됩니다. |
void slot::clear() |
반환: void |
슬롯에 등록된 취소 핸들러를 안전하게 해제합니다. | 작업이 정상 완료된 후 불필요한 취소 콜백 호출을 차단하기 위해 슬롯을 정리합니다. |
bind_cancellation_slot(s, h) |
cancellation_slot s, Handler h반환: 바인딩된 핸들러 |
취소 슬롯과 대상 핸들러를 결합한 새 완성 토큰 객체를 생성합니다. | C++20 코루틴 co_spawn 호출 시 4번째 인자로 취소 슬롯을 전달하여 코루틴 전체를 원격 취소 가능하게 만듭니다. |
cancel_sig.emit(cancellation_type::terminal) → 대기 중인 모든 읽기/쓰기 코루틴 탈출 → DB 저장 완료 → 소켓 최종 파괴.
Boost.MySQL 핵심 클래스 & 비동기 쿼리 API 완제표
블로킹 없는 비동기 DB 접근을 보장하는 Boost 1.84+ 공식 네트워크 DB 커넥터의 핵심 클래스 및 멤버 함수 완제표입니다.
| 클래스 및 메서드 시그니처 | 매개변수 및 반환형 | 비동기 SQL 실행 메커니즘 | 10만 동접 실전 주의사항 |
|---|---|---|---|
connection_pool(ioc, params) |
pool_params params반환: 없음 (생성자) |
다중 MySQL TCP 커넥션을 관리하는 비동기 커넥션 풀을 생성합니다. | params.max_size = 64; 등으로 적정 풀 크기를 지정하여 DB 서버 커넥션 포화를 방어하십시오. |
async_run(token) |
반환: 완료 토큰 반환형 | 백그라운드에서 주기적 핑, 타임아웃 감지 및 커넥션 자동 재연결 루프를 지속 가동합니다. | 서버 초기화 시 co_spawn(ioc, pool.async_run(use_awaitable), detached);로 무인 가동해야 합니다. |
async_get_connection(token) |
반환: pooled_connection |
풀에서 즉시 사용 가능한 유효한 커넥션을 비차단 방식으로 대여(Checkout)합니다. | RAII 객체이므로 스코프를 벗어나는 즉시 자동으로 커넥션 풀에 반납(Checkin)되어 누수가 0%입니다. |
async_execute(stmt, results, t) |
statement, results&반환: 완료 토큰 반환형 |
SQL 쿼리나 Prepared Statement를 실행하고 결과 행 세트를 비동기로 수신합니다. | with_params("SELECT * FROM user WHERE id = {}", uid)를 사용하여 SQL Injection을 원천 차단하십시오. |
results::rows() const noexcept |
반환: rows_view |
쿼리 실행 결과로 반환된 모든 레코드 행의 뷰(View) 컨테이너를 인출합니다. | 제로카피 뷰이므로 results 객체가 소멸되기 전에 인게임 캐릭터 구조체로 복사 파싱해야 합니다. |
results::affected_rows() |
반환: uint64_t (행 수) |
INSERT, UPDATE, DELETE 문에 의해 실제로 영향받은 행의 개수를 반환합니다. | 아이템 구매나 경험치 갱신 트랜잭션의 성공 여부 검증에 반드시 확인해야 하는 핵심 지표입니다. |
auto conn = co_await pool.async_get_connection(use_awaitable); results res; co_await conn->async_execute(with_params("UPDATE users SET gold=gold-{} WHERE id={}", cost, uid), res, use_awaitable);
AsioNetCore 네트워크 & 세션 엔진 핵심 함수 완제표
본 도서 전반에서 구축한 상용 고성능 게임 서버 프레임워크인 AsioNetCore의 네트워크 및 세션 관리자 핵심 API 완제표입니다.
| 클래스 및 메서드 시그니처 | 매개변수 및 반환형 | 네트워크 엔진 동작 메커니즘 | 10만 동접 실전 주의사항 |
|---|---|---|---|
NetworkService::Start(ip, port, n) |
string ip, uint16 port, int n반환: bool |
I/O 컨텍스트를 가동하고 n개의 OS 워커 스레드를 스폰하며 리스너(Acceptor)를 활성화합니다. | 포트 충돌이나 바인딩 실패 시 false를 즉각 반환하므로 부팅 실패 로그를 남기고 종료해야 합니다. |
NetworkService::Stop() |
반환: void |
Acceptor 닫기, 모든 활성 세션 연결 끊기, 워크 가드 해제 및 워커 스레드 조인을 수행합니다. | 모든 세션 데이터가 DB에 flush된 후 스레드가 종료되므로 안전한 무손실 종료가 보장됩니다. |
NetworkService::Broadcast(pkt) |
const CPacket& pkt반환: void |
접속 중인 모든 세션의 송신 큐(SendQueue)에 패킷을 복제 없이 병렬 분배합니다. | 세션별 strand를 통해 비동기 쓰기를 수행하므로 멀티스레드 락 경합이 0%입니다. |
SessionManager::CreateSession(s) |
tcp::socket s반환: shared_ptr<TcpSession> |
수락된 TCP 소켓에 원자적 고유 64비트 세션 ID를 발급하고 세션 맵에 등록합니다. | 세션 맵은 읽기-쓰기 스핀락(RWLock)으로 보호되어 10만 동접 검색 시 병목이 없습니다. |
SessionManager::CloseSession(id) |
uint64_t session_id반환: void |
세션을 맵에서 안전하게 제거하고 소켓 셧다운 및 자원 반환을 트리거합니다. | 이미 닫힌 세션에 대한 중복 호출을 원자적 플래그(CAS)로 철저히 방어합니다. |
TcpSession::AsyncRead() |
반환: void |
8바이트 고정 헤더 수신 → 길이 검증 → 페이로드 수신의 연속 비동기 체인을 가동합니다. | 수신 즉시 PacketDispatcher로 라우팅하여 비즈니스 로직과 I/O를 완전 분리합니다. |
TcpSession::AsyncWrite(pkt) |
CPacket pkt반환: void |
패킷을 세션 전용 송신 큐에 푸시하고, 대기 중인 쓰기 작업이 없으면 async_write를 가동합니다. |
인플라이트(In-Flight) 쓰기 플래그를 원자적으로 제어하여 패킷 뒤섞임을 원천 차단합니다. |
journal_mode=WAL, synchronous=NORMAL, cache_size=-64000, temp_store=MEMORY, mmap_size=1073741824, busy_timeout=5000, wal_autocheckpoint=1000.
C100K 리눅스 & macOS OS 커널 파라미터 완전 백서 완제표
동시 접속자 10만 명(C100K) 환경에서 OS 소켓 자원 고갈 및 SYN 드롭을 방지하기 위한 핵심 커널 파라미터 튜닝 완제표입니다.
| 커널 파라미터 / sysctl 키 | 기본값 vs 권장값 | 설정 목적 및 커널 내부 동작 | 미설정 시 발생하는 장애 |
|---|---|---|---|
fs.file-max |
기본 10만 → 2,097,152 | 운영체제 전역에서 오픈할 수 있는 최대 파일 디스크립터(FD) 개수 제한을 해제합니다. | EMFILE (Too many open files) 에러로 신규 유저 접속 전면 마비. |
net.core.somaxconn |
기본 128 → 65,535 | TCP 리슨(Listen) 백로그 큐의 최대 길이를 확장하여 접속 폭주를 수용합니다. | 오픈 이벤트 시 큐 오버플로우로 대량 접속 패킷이 사일런트 드롭됨. |
net.ipv4.tcp_max_syn_backlog |
기본 512 → 65,535 | 3-Way Handshake 미완료 반개방(Half-Open) SYN 큐 크기를 확장합니다. | 대규모 SYN 플러딩 공격이나 일시적 트래픽 몰림 시 접속 타임아웃 발생. |
net.ipv4.ip_local_port_range |
32768~60999 → 1024 65535 | 아웃바운드 연결에 사용 가능한 에페머럴(Ephemeral) 로컬 포트 대역을 확장합니다. | 게이트웨이-존 서버 간 프록시 연결 시 포트 고갈(EADDRNOTAVAIL) 발생. |
net.ipv4.tcp_tw_reuse |
기본 0 → 1 | TIME_WAIT 상태의 소켓을 새 나가는 TCP 연결에서 안전하게 재사용합니다. | 잦은 재접속 시 로컬 포트가 TIME_WAIT에 묶여 커넥션 생성 불가. |
net.ipv4.tcp_fin_timeout |
기본 60초 → 15초 | 소켓 닫힘(FIN) 후 FIN-WAIT-2 상태에 머무는 대기 시간을 대폭 단축합니다. | 좀비 세션이 커널 메모리를 장시간 점유하여 RAM 부족 현상 초래. |
net.core.rmem_max / wmem_max |
기본 208KB → 16,777,216 | TCP 소켓별 최대 수신 및 송신 버퍼(SO_RCVBUF, SO_SNDBUF) 한도를 16MB로 확장. | 대규모 월드 브로드캐스트 시 커널 버퍼 부족으로 전송 지연 발생. |
/etc/sysctl.conf에 상기 파라미터를 추가하고 sudo sysctl -p를 실행하여 즉각 반영하며, /etc/security/limits.conf에 * soft nofile 1048576, * hard nofile 1048576를 등록하십시오.
systemd 무인 서비스 유닛 및 GDB 코어 덤프 설정 규격
서버 재부팅 시 자동 기동, 비정상 크래시 시 1초 자가 부활 및 포렌식 코어 덤프 수집을 위한 프로덕션 설정 규격표입니다.
| 설정 지시어 / 키 | 섹션 및 대상 | 동작 메커니즘 및 365일 무인 복구 | 프로덕션 권장 값 |
|---|---|---|---|
Type=exec |
[Service] |
바이너리가 완전히 실행되고 초기화가 완료된 시점을 systemd에 통지합니다. | Type=exec (안전 기동 확인) |
Restart=always |
[Service] |
정상 종료(0)든 SIGSEGV 크래시든 상관없이 프로세스 사망 시 무조건 자동 재기동합니다. | Restart=always (365일 무인) |
RestartSec=1s |
[Service] |
프로세스 사망 후 재기동까지 대기하는 인터벌을 1초로 극소화합니다. | RestartSec=1s (다운타임 최소화) |
LimitNOFILE=1048576 |
[Service] |
systemd 데몬 프로세스에 부여할 최대 파일 디스크립터 한도를 100만 개로 확장. | LimitNOFILE=1048576 |
LimitCORE=infinity |
[Service] |
크래시 시 코어 덤프 파일 크기 제한을 무제한으로 풀어 완전한 덤프를 생성. | LimitCORE=infinity |
kernel.core_pattern |
/etc/sysctl.conf |
코어 덤프 파일이 저장될 경로와 파일명 포맷(바이너리명, PID, 타임스탬프) 지정. | /var/crash/core.%e.%p.%t |
gdb 배치 역추적 |
CLI 명령어 | 생성된 코어 덤프를 열어 모든 스레드의 콜스택을 텍스트로 즉각 자동 덤프. | gdb -batch -ex "thread apply all bt" |
/etc/systemd/system/gameserver.service 저장 → 2) sudo systemctl daemon-reload → 3) sudo systemctl enable --now gameserver. 24시간 365일 무인 자동 수호 가동.
Manintop 8바이트 고정 헤더 & 실전 패킷 ID 바이블
TCP 스트림의 경계(Boundary)를 완벽히 식별하고 패킷 변조를 방지하는 8바이트 표준 헤더 레이아웃 및 패킷 ID 규격표입니다.
| 오프셋 / 패킷 ID | 필드명 / 심볼명 | 타입 / 크기 | 프로토콜 규격 및 실전 처리 로직 |
|---|---|---|---|
Offset 0~1 |
Magic Number |
uint16_t (2B) |
고정 매직 식별자 0x77AA. 불일치 시 패킷 스니핑/해킹으로 간주 즉각 연결 해제. |
Offset 2~3 |
Packet ID (Opcode) |
uint16_t (2B) |
패킷의 비즈니스 명령 코드. PacketDispatcher 맵을 통해 해당 핸들러로 라우팅. |
Offset 4~5 |
Payload Length |
uint16_t (2B) |
헤더 뒤에 이어지는 순수 바디 데이터의 바이트 크기 (0 ~ 65535). |
Offset 6~7 |
Checksum |
uint16_t (2B) |
헤더와 페이로드 전체에 대한 Fletcher-16 알고리즘 무결성 검증값. 불일치 시 드롭. |
0x0001 |
PKT_CS_LOGIN_REQ |
CS 패킷 | 클라이언트 → 게이트웨이 인증 토큰 및 계정 ID 전송. |
0x0002 |
PKT_SC_LOGIN_RES |
SC 패킷 | 게이트웨이 → 클라이언트 인증 성공 여부 및 월드 서버 세션 티켓 발급. |
0x0010 |
PKT_CS_MOVE_REQ |
CS 패킷 | 플레이어의 목적지 좌표(X, Y, Z, Yaw) 및 타임스탬프 전송 (초당 20~30회). |
0x0011 |
PKT_SC_MOVE_BRD |
SC 패킷 | AoI 3x3 격자 내의 인접 유저들에게 플레이어 이동 좌표 브로드캐스트. |
boost::endian::native_to_big()으로 변환하여 네트워크에 쏘고, 수신 후 boost::endian::big_to_native()로 파싱해야 이기종(x86_64, ARM64) 호환성이 100% 보장됩니다.
AsioNetCore 큐·디스패처 & Boost Companion API 완제표
패킷 큐잉, 디스패처 라우팅, 원형 링버퍼 및 Boost.Lockfree/Boost.Endian 유틸리티 함수의 시그니처 완제표입니다.
| 함수명 및 시그니처 | 소속 라이브러리 / 모듈 | 메모리 및 큐 동작 메커니즘 | 10만 동접 실전 주의사항 |
|---|---|---|---|
SendQueue::Push(packet) |
AsioNetCore::SendQueue |
송신 큐에 패킷을 적재하고 대기 중인 비동기 쓰기가 없으면 자동으로 쓰기 체인을 기동. | 큐 크기 임계치(예: 10,000건) 초과 시 슬로우 리시버로 간주하여 세션 강제 차단. |
PacketDispatcher::RegisterHandler |
AsioNetCore::Dispatcher |
패킷 Opcode와 처리 콜백 함수 포인터를 해시맵에 1:1로 등록합니다. | 서버 부팅 시 람다나 멤버 함수를 std::bind로 일괄 등록하여 O(1) 초고속 분기. |
PacketDispatcher::DispatchPacket |
AsioNetCore::Dispatcher |
수신된 패킷의 Opcode를 조회하여 등록된 전용 핸들러를 원자적으로 호출합니다. | 미등록 Opcode 수신 시 비정상 클라이언트 에러 로그를 남기고 패킷을 즉시 폐기. |
RingBuffer::Write / Read |
AsioNetCore::RingBuffer |
연속 메모리 원형 큐에서 데이터 복사 없이 포인터 이동만으로 제로카피 송수신 수행. | 단일 생산자-단일 소비자(SPSC) 구조로 원자적 인덱스(Atomic Head/Tail)를 사용하여 락 0%. |
spsc_queue::push / pop |
boost::lockfree::spsc_queue |
하드웨어 메모리 배리어를 활용한 초고속 단일 생산자-소비자 락프리 큐 API. | 네트워크 I/O 스레드와 게임 로직 스레드 간의 틱 패킷 교환에 최적의 성능 제공. |
endian_reverse(T value) |
boost::endian |
16비트, 32비트, 64비트 정수의 바이트 순서를 인라인 어셈블리(BSWAP)로 0.1ns에 반전. | 네트워크 패킷 헤더 파싱 시 CPU 사이클 낭비 없이 완벽한 빅엔디안 상호 변환. |
Fletcher-16은 덧셈 2회로 계산되어 CRC32 대비 CPU 연산 비용이 70% 낮으면서도 단일/이중 비트 에러 검출률 99.998%를 보장하여 고빈도 게임 패킷 검증에 최적입니다.
대용량 온라인 게임 서버 핵심 기술 용어 사전 (A to Z)
본 도서 전반에서 다룬 실무 대용량 온라인 게임 서버 아키텍처의 12대 핵심 기술 용어 완제 정의표입니다.
| 핵심 기술 용어 | 영문 정규 표기 | 엔지니어링 개념 및 기술 아키텍처 정의 | 관련 챕터 |
|---|---|---|---|
| AoI | Area of Interest | 월드를 격자로 분할하여 플레이어 시야 반경(3x3) 내의 엔티티 정보만 필터링 브로드캐스트하는 기법. | 제8장, 제9장 |
| Backpressure | Backpressure Flow Control | 클라이언트의 수신 속도가 느릴 때 송신 큐의 과도한 적재를 감지하여 전송 속도를 조절하거나 차단하는 제어. | 제4장, 제6장 |
| C100K | Concurrent 100,000 Users | 단일 서버 프로세스가 10만 개의 동시 TCP 세션을 유지하며 초당 수백만 패킷을 실시간 처리하는 극한 목표. | 제18~20장 |
| Dead Reckoning | Dead Reckoning | 클라이언트가 서버로부터 새 좌표를 받기 전까지 이전 속도와 방향 벡터로 미래 위치를 추측 렌더링하는 기법. | 제9장 |
| epoll / IOCP | I/O Completion Ports | OS 커널이 비동기 I/O 완료 이벤트를 통지하는 초고성능 다중화 메커니즘 (리눅스 epoll, 윈도우 IOCP). | 제1장, 제5장 |
| LERP | Linear Interpolation | 네트워크 지연으로 뚝뚝 끊기는 캐릭터 위치 좌표를 시간 흐름에 따라 부드럽게 선형 보간하는 렌더링 공식. | 제9장 |
| Lock-Free | Lock-Free Synchronization | 뮤텍스 락 없이 CPU 원자적 명령어(CAS, fetch_add)를 활용하여 스레드 대기 없는 초고속 동기화 달성. | 제6장, 부록A |
| Strand | asio::strand | 멀티스레드 I/O 풀 환경에서 특정 세션의 비동기 핸들러들이 결코 동시 실행되지 않도록 직렬화하는 보장자. | 제6장, 부록A |
본서 찾아보기(Index) 및 저자 직통 기술 지원 채널
본 도서 전반에서 다룬 핵심 C++20 클래스, Boost.Asio 함수, 리눅스 커널 시스템 콜의 페이지 색인 완제표입니다.
| 핵심 색인 키워드 (Keyword) | 본문 및 부록 출현 페이지 | 기술 요약 및 핵심 참조 가이드 |
|---|---|---|
asio::io_context |
p. 15, 25, 85, 364~373 | 비동기 I/O Proactor 이벤트 루프 코어 엔진 및 스케줄러. |
asio::strand |
p. 105, 115, 368 | 뮤텍스 없는 세션별 락-프리 핸들러 직렬화 실행자. |
async_read / async_write |
p. 45, 65, 376 | 부분 전송(Partial Send) 없는 완벽한 스트림 I/O 무료 함수. |
co_spawn / use_awaitable |
p. 185, 205, 384 | C++20 표준 코루틴 비동기 직선형 호출 엔진 (ACO). |
Boost.MySQL |
p. 285, 295, 386 | 비차단 커넥션 풀 및 Prepared Statement 비동기 DB 엔진. |
SendQueue & RingBuffer |
p. 68, 88, 391 | AsioNetCore 프레임워크 단일 인플라이트 락프리 메모리 큐. |
TCP_NODELAY & SO_REUSEADDR |
p. 92, 305, 378 | 네이글 비활성화 및 TIME_WAIT 무시 즉각 재바인딩 소켓 옵션. |
C100K 커널 튜닝 백서 |
p. 303, 315, 388 | somaxconn 65535, file-max 2097152, Ephemeral 포트 확장. |
youb1649@gmail.com)로 문의하시면 성심성의껏 기술 지원을 제공해 드립니다.
C++20 & Boost.Asio: 10만 동접 대용량 온라인 게임 서버 프로그래밍
저자: 신 승 엽 (호주 UniSA 컴퓨터정보과학 박사 / 전 KAIST 연구조교수)
저자 이메일: youb1649@gmail.com / 기술 지원: 010-7330-1649
저자 및 발행인: 신 승 엽 / 출판사: 퍼플 (교보문고 바로출판)
판형: 46배판 변형 (178mm × 254mm / 7in × 10in)
공식 소스코드 저장소: https://drive.google.com/drive/folders/1eW8pV9-jv_K_ATDTplsdfJZTrrQ_sZI_?usp=drive_link
Copyright © 2026 Dr. Seung Youb Ssin. All rights reserved. 본서 및 수록된 소스코드는 저작권법의 보호를 받습니다.