Files

ClientTester - MMO 서버 테스트 도구

MMO Game Server의 네트워크 성능 검증 및 부하 테스트를 위한 클라이언트 시뮬레이터.


1. 환경 (라이브러리)

항목 버전 용도
.NET 9.0 런타임
LiteNetLib 2.0.2 UDP 네트워크 통신 (서버와 동일)
protobuf-net 3.2.56 패킷 직렬화/역직렬화
Serilog 4.3.1 구조적 로깅
Serilog.Sinks.Console 6.0.0 콘솔 출력
Serilog.Sinks.File 7.0.0 파일 로깅
Microsoft.Diagnostics.NETCore.Client 0.2.553101 크래시 힙 덤프 (Release만)

빌드

cd ClientTester/EchoClientTester
dotnet build

2. 디렉토리 구조

ClientTester/
├── EchoClientTester/
│   ├── Program.cs                          # 진입점 (대화형 + CLI)
│   ├── EchoClientTester.csproj
│   ├── Vector3.cs                          # 위치 구조체
│   │
│   ├── DummyService/                       # 이동 테스트
│   │   ├── DummyClientService.cs           # 다중 더미 클라 관리
│   │   ├── DummyClients.cs                 # 개별 더미 클라 (이동 시뮬)
│   │   └── MapBounds.cs                    # 맵 경계 / 벽 충돌
│   │
│   ├── EchoDummyService/                   # Echo RTT 테스트
│   │   ├── EchoDummyClientService.cs       # 다중 에코 클라 관리
│   │   └── EchoDummyClients.cs             # 개별 에코 클라 (RTT 측정)
│   │
│   ├── StressTest/                         # 부하/스트레스 테스트
│   │   ├── StressTestService.cs            # 오케스트레이터 (Ramp-up, 통계, CSV)
│   │   └── StressTestClient.cs             # 통합 클라 (이동 + Echo 동시)
│   │
│   ├── Packet/                             # 패킷 정의 (서버와 동일 프로토콜)
│   │   ├── PacketHeader.cs                 # PacketCode Enum
│   │   ├── PacketBody.cs                   # Protobuf 패킷 클래스
│   │   └── PacketSerializer.cs             # 직렬화 유틸
│   │
│   └── Utils/
│       └── CrashDumpHandler.cs             # 크래시 로그 + 힙 덤프
│
└── TempServer/                             # 간이 에코 서버 (독립 테스트용)
    └── Program.cs

3. 사용방법

3.1 대화형 모드

dotnet run
========== 더미 클라 테스터 ==========
1. 에코 서버
2. 더미 클라(이동만)
3. 스트레스 테스트 (부하)
====================================
1 / 2 / 3 :
모드 설명
1. 에코 서버 Echo 패킷 송수신, RTT(Round-Trip Time) 측정
2. 더미 클라 이동(Transform) 패킷 전송, 패킷 손실률 측정
3. 스트레스 테스트 Ramp-up + 이동 + Echo 동시, 퍼센타일 레이턴시, CSV 내보내기

3.2 CLI 모드 (스트레스 테스트)

# 기본 실행 (50명, 60초)
dotnet run -- stress

# 100명 클라이언트, 120초 테스트
dotnet run -- stress -c 100 -d 120

# 원격 서버 대상, 커스텀 설정
dotnet run -- stress -c 200 -d 60 -r 500 -b 20 --ip 192.168.0.10 --port 9500

# 도움말
dotnet run -- --help

CLI 옵션

옵션 축약 기본값 설명
--clients -c 50 총 클라이언트 수
--duration -d 60 테스트 지속 시간 (초, 0=무제한)
--interval -i 100 패킷 전송 주기 (ms)
--ramp -r 1000 Ramp-up 간격 (ms)
--batch -b 10 Ramp-up 당 추가 클라이언트 수
--ip localhost 서버 IP 주소
--port 9500 서버 포트

3.3 출력 파일

경로 내용
logs2/log_{timestamp}.txt 전체 실행 로그
results/stress_{N}clients_{timestamp}.csv 스트레스 테스트 결과 (클라이언트별 통계)
crashes/crash_{timestamp}.log 크래시 스택 트레이스
crashes/crash_{timestamp}.dmp 힙 덤프 (Release 빌드만)

4. 파이프라인

4.1 에코 테스트 (모드 1)

[클라이언트 N개 동시 생성]
        ↓
[연결] UDP Connect → ServerBase.OnConnectionRequest()
        ↓
[PollLoop]  10ms 주기로 네트워크 이벤트 처리
[SendLoop]  100ms 주기로 Echo 패킷 전송
        ↓
[송신] EchoPacket { Str = "Echo seq:{N}" }
       → PacketSerializer.Serialize()
       → 4바이트 헤더(type + size) + Protobuf 페이로드
       → DeliveryMethod.ReliableUnordered
        ↓
[수신] 서버가 Echo 패킷 그대로 반환
       → seq 번호로 pendingPings 조회
       → RTT 계산: (수신시각 - 송신시각) / Stopwatch.Frequency
        ↓
[통계] 클라이언트별: AvgRTT, LastRTT, Sent, Recv, PacketLoss%
       전체: 총 Sent/Recv, 평균 RTT

4.2 이동 테스트 (모드 2)

[클라이언트 N개 동시 생성]
        ↓
[연결 + 인증]
       DummyAccTokenPacket { Token = clientId }
       → DeliveryMethod.ReliableOrdered
        ↓
[이동 시뮬레이션 - UpdateDummy()]
       ┌────────────────────────────────────────┐
       │ 1. 델타 타임 계산 (Stopwatch)            │
       │ 2. 남은 거리 = 0 이면:                    │
       │    - 벽 근처? → 반대 방향 회전              │
       │    - 아니면 → 현재 방향 ±30도 랜덤 회전      │
       │    - 목표 거리 = moveSpeed × (3~12초)      │
       │ 3. 이번 틱 이동 (moveSpeed × delta)       │
       │ 4. MapBounds.Clamp() → 벽 충돌 처리        │
       └────────────────────────────────────────┘
        ↓
[송신] TransformPlayerPacket { PlayerId, Position(X,0,Z), RotY }
       → DeliveryMethod.Unreliable (손실 감수)
        ↓
[통계] 클라이언트별: Sent, Recv, PacketLoss%

4.3 스트레스 테스트 (모드 3 / CLI)

[설정 입력] CLI 인자 또는 대화형 입력
        ↓
[Ramp-up Loop]
       ┌────────────────────────────────────┐
       │ rampInterval(1000ms)마다             │
       │ clientsPerRamp(10)명씩 클라이언트 생성  │
       │ → totalClients 도달 시 중단            │
       └────────────────────────────────────┘
        ↓ (병렬 실행)
[PollLoop]   10ms 주기 네트워크 이벤트
[SendLoop]   sendInterval(100ms) 주기
             ├─ UpdateAndSendTransform() (이동 - Unreliable)
             └─ SendPing()              (Echo - ReliableUnordered)
[StatsLoop]  10초마다 실시간 통계 출력
        ↓
[지속시간 만료 또는 Ctrl+C]
        ↓
[최종 리포트]
       ├─ 처리량: 총 Sent/Recv, 패킷/초
       ├─ 레이턴시: Min, Avg, P50, P95, P99, Max
       ├─ 최악 RTT 상위 5 클라이언트 상세
       └─ CSV 파일 자동 저장

4.4 패킷 직렬화 파이프라인

객체 (e.g. TransformPlayerPacket)
        ↓
protobuf-net Serialize → byte[] payload
        ↓
PacketSerializer.Serialize()
        ↓
┌──────────────────────────────┐
│ [2B type] [2B size] [payload] │
│  ushort    ushort    byte[]   │
└──────────────────────────────┘
        ↓
NetDataWriter.Put(data)
        ↓
peer.Send(writer, DeliveryMethod)

5. 테스트 모드별 기능 비교

기능 에코 (1) 이동 (2) 스트레스 (3)
동시접속 클라이언트 10 (고정) 10 (고정) N (설정 가능)
인증 패킷 전송 X O O
이동 시뮬레이션 X O O
Echo RTT 측정 O X O
패킷 손실 추적 O O O
점진적 Ramp-up X X O
지속시간 제한 무제한 무제한 설정 가능
실시간 통계 X X O (10초 주기)
퍼센타일 레이턴시 X (평균만) X O (P50/P95/P99)
CSV 내보내기 X X O
CLI 인자 X X O
최악 클라이언트 분석 X X O (상위 5)

6. 구현 진행도

완료

항목 상태 설명
Echo RTT 측정 완료 seq 기반 ping/pong, Stopwatch 고정밀 타이머
더미 이동 시뮬레이션 완료 벽 충돌, 랜덤 방향 전환, 델타 타임 기반 이동
맵 경계 처리 완료 MapBounds (Clamp, 벽 반대 방향 계산)
패킷 손실 추적 완료 LiteNetLib.NetStatistics 활용
크래시 덤프 완료 Debug: .log / Release: .log + .dmp
로깅 (콘솔+파일) 완료 Serilog 타임스탬프별 로그 파일
Graceful Shutdown 완료 Ctrl+C → CancellationToken → 통계 출력 후 종료
스트레스 테스트 완료 Ramp-up, 퍼센타일, CSV, CLI 인자
CLI 인자 지원 완료 stress -c N -d T --ip --port

미구현 / 향후 작업

항목 상태 설명
채널 입장 시뮬레이션 미구현 INTO_CHANNEL 패킷 전송 후 게임 루프 진입
전투 액션 시뮬레이션 미구현 ACTION_PLAYER (공격/스킬) 패킷 전송
상태 변경 시뮬레이션 미구현 STATE_PLAYER (HP/MP) 패킷 전송
JWT 토큰 인증 테스트 미구현 ACC_TOKEN 방식 인증 플로우 검증
서버 응답 검증 미구현 수신 패킷 내용 파싱 및 정합성 체크
테스트 시나리오 스크립트 미구현 JSON/YAML 기반 테스트 시나리오 정의
그래프 출력 미구현 RTT/처리량 시계열 차트 생성

7. 설정 참고

서버 연결 기본값

항목
IP localhost
Port 9500
Connection Key test

이동 시뮬레이션 파라미터

항목 설명
moveSpeed 3.5 이동 속도 (units/sec)
맵 범위 -50 ~ 50 (X, Z) 100x100 영역
벽 감지 마진 0.5 벽 근처 판정 거리
목표 거리 moveSpeed x 3~12초 직진 후 방향 전환
방향 전환 현재 ±30도 랜덤 벽 근처 시 반대 방향 강제

스트레스 테스트 기본값

항목 설명
클라이언트 수 50 -c 옵션
지속 시간 60초 -d 옵션
전송 주기 100ms -i 옵션
Ramp-up 간격 1000ms -r 옵션
Ramp-up 배치 10명 -b 옵션
실시간 통계 주기 10초 고정
Echo 최대 pending 500 메모리 누수 방지