<aside> 🧭
Windows 전용으로 만든 IOCP MMO 서버를 리눅스에서 그대로 돌렸다.
같은 소스 하나로 Windows(완료 포트·RIO)와 리눅스(epoll) 양쪽이 빌드되고, 리눅스에서 접속·이동·채팅이 왕복한다. Windows에서 빌드한 기존 부하 클라이언트가 리눅스 서버에 그대로 붙는다.
이 페이지는 전체 요약이고, 각 대목은 아래 네 문서에 있다.
</aside>
<aside> 📌
아직 안 한 것 — 성능 비교. 여기까지는 전부 "정확하게 도는가"이고, IOCP와 epoll의 성능을 맞대본 숫자는 없다. WSL2로는 의미 있는 비교가 안 되기 때문이다(5장 참고).
</aside>
| 항목 | 결과 |
|---|---|
| 빌드 | 같은 소스로 Windows(IOCP·RIO) · 리눅스(epoll) — CMake 한 벌 |
| 리눅스에서 도는가 | 접속 · 이동 · 채팅 전부 왕복 |
| Windows 클라이언트가 붙는가 | 기존 부하 클라 10개 접속, 패킷 에러 0 |
| Windows가 안 깨졌는가 | IOCP 팔 · RIO 팔 클린 재빌드 경고 0 / 오류 0 |
| 락프리 자료구조 | 코드 무변경 — 어댑터 헤더 하나로 이식 |
| 성능 비교 | 아직 — 측정 환경 필요 |
| 단계 | 확인 |
|---|---|
| 접속 | S2C_ZONE_INFO(1010) · S2C_CREATE_MY_PLAYER(1004) 수신 |
| 이동 | 40회 → 서버가 40개 전부 파싱, 게임 로직 31회 수행, 클라가 31개 되받음 |
| 채팅 | S2C_CHAT(1008) 26바이트 수신, 서버 에러 0 |
<aside> 💡
클라이언트 두 개를 붙였을 때 서로에게 브로드캐스트가 안 갔다. 처음엔 결함을 의심했는데 AOI(관심 영역)가 제대로 도는 증거였다 — 둘이 서로 시야 밖에 스폰된 것이다.
</aside>
이 서버는 완료 포트(IOCP)를 전제로 설계됐다. 세션 수명, 송신 큐, 워커 스레드 모델까지 "커널이 완료를 알려준다"에 기대어 짜여 있다.
리눅스로 옮기는 일은 그래서 단순한 이식이 아니다. 무엇이 그 전제에 기대고 있었는지가 드러나는 작업. 결과부터 말하면 골격은 거의 그대로 옮겨졌고, 진짜로 갈린 곳은 두 곳이었다.(→ 3. 두 모델 차이가 터진 곳)
본체를 건드리기 전에 순수 소켓 에코 서버를 리눅스용으로 따로 만들었다(epoll_echo_poc). 게임 로직도, 락프리도, 직렬화 버퍼도 연결하지 않은 것이다.
목적이 둘이었다.
<aside> 🔑
큰 것을 옮기다 막히면 원인이 툴체인인지 설계인지 코드인지 구분이 안 된다. 작은 것으로 먼저 길을 내두면, 이후에 나는 문제는 전부 "본체 쪽"이라고 좁힐 수 있다.
이 PoC는 지금도 빌드 대상으로 남겨 뒀다 — 환경이 깨졌는지 확인하는 가장 싼 방법이기 때문이다.
</aside>
환경 → 락프리 → 안전성 검사 → 크래시 덤프 → epoll 백엔드 → 실동작. 각 단계에 넘어가도 되는 조건을 미리 적어두고, 그 조건을 실제로 돌려 확인한 뒤에만 다음으로 갔다.