Network Diagnostics Engine Task.WhenAll Parallel ICMP Sliding Window Micro Chart

학내망과 군 폐쇄망 회선 단선을 0초 만에 판별하다: ZeliPing의 Task.WhenAll 병렬 ICMP 프로빙, 100건 슬라이딩 윈도우 RTT 통계, 및 실시간 마이크로 차트 아키텍처

"학교 수업 도중 '선생님, 인터넷이 안 돼요'라는 외침이 터져 나왔을 때, 단말기 문제인지, 교실 스위칭 허브 고장인지, 통신사 회선 장애인지 파악하는 데 10분이 걸린다면 그 수업은 완전히 망가집니다. 로컬 게이트웨이, 학교 내부 DNS, 교육청 메인 라우터를 단 1초의 지연도 없이 동시에 두드려 어느 구간에서 패킷이 드랍되는지 시각적으로 보여주는 다중 동시 프로빙 도구가 필수적인 이유입니다."

1. 서론: "인터넷이 안 돼요" — 교실과 군 지휘소의 네트워크 블랙아웃 위기

디지털 교과서(AIDT)와 AI 수업이 일상화된 현대 교육 현장에서 네트워크 연결성은 교실의 공기와도 같습니다. 40대의 학생 태블릿과 PC가 일제히 클라우드 교육 플랫폼이나 교내 모델 허브 서버에 접속할 때, 사소한 회선 병목이나 스위치 루핑 하나만으로도 교실 전체가 마비되는 네트워크 블랙아웃(Blackout)이 발생합니다.

기존의 윈도우 표준 콘솔 명령어 ping은 단 하나의 호스트만을 순차적으로 테스트할 수 있어, "내 PC ➔ 기본 게이트웨이 ➔ DNS ➔ 외부 망"으로 이어지는 네트워크 홉(Hop) 구간 중 정확히 어느 지점에서 단선이 발생했는지 비교 진단하려면 수 분의 시간이 소모됩니다.

ZeliDesk의 시스템 유틸리티 제품군인 ZeliPing은 무한 확장이 가능한 멀티 타깃 동시성 구조와 실시간 비주얼 텔레메트리를 결합하여, 수십 개 호스트의 지연시간(RTT)과 패킷 유실을 한 화면에서 0.1초 만에 직관적으로 파악하는 병렬 감사 엔진을 완성했습니다.

2. 동시 비동기 ICMP 파이프라인: Task.WhenAll을 통한 O(N) 지연의 O(1) 압축

만약 관리자가 5개의 주요 인프라 호스트(게이트웨이, 보조 DNS, 교육청 라우터, AI 서버 등)를 감시한다고 가정해 봅시다. 기존의 동기식 순차 루프로 각 호스트에 2초 타임아웃의 핑을 날린다면, 회선 단선 시 한 라운드를 검사하는 데만 $5 \times 2\text{초} = 10\text{초}$라는 막대한 지연이 발생합니다.

ZeliPing은 C#의 비동기 작업 병합 연산자인 Task.WhenAll을 도입하여 등록된 모든 호스트 슬롯을 단일 라운드 안에서 완전 병렬로 동시 격발합니다:

// ── ZeliPing/Views/ZeliPingWindow.xaml.cs ──
int round = 0;
while (_isPinging && !_cts.Token.IsCancellationRequested)
{
    round++;
    if (maxCount > 0 && round > maxCount) break;

    // ⚡ 모든 활성 호스트 슬롯에 대해 비동기 ICMP 작업을 동시에 격발
    var tasks = activeSlots.Select(s => PingOneAsync(s, _cts.Token)).ToList();
    
    // N개 호스트의 결과가 모두 돌아올 때까지 논블로킹 대기 (가장 늦은 응답 시간 = 전체 라운드 소요 시간)
    await Task.WhenAll(tasks);

    // 지정된 주기(intervalMs) 동안 비동기 대기 후 다음 라운드 실행
    if (_isPinging && !_cts.Token.IsCancellationRequested)
        await Task.Delay(intervalMs, _cts.Token);
}

이 병렬화 아키텍처 덕분에 감시 대상 호스트가 3개든 20개든 관계없이 전체 라운드 검사 지연시간은 항상 $O(1)$(네트워크 최대 RTT 수준)로 압축되어, 네트워크 상태 변동을 실시간으로 감지할 수 있습니다.

3. 무한 순환 8색상 팔레트와 동적 호스트 슬롯(HostSlot) 추상화

여러 개의 네트워크 타깃을 동시에 시각화할 때 가장 중요한 것은 각 호스트의 지표가 시각적으로 명확하게 구분되어야 한다는 점입니다. ZeliPing은 8단계의 고대비 오로라 컬러 팔레트를 정의하고 모듈로 연산을 통해 호스트가 무한히 추가되더라도 자동으로 고유 색상과 이모지 배지를 부여하는 `HostSlot` 구조를 채택했습니다:

private static readonly (string Dot, Color Color, Color Header)[] Palette =
{
    ("🟢", Color.FromArgb(255, 52, 211, 153),  Color.FromArgb(16, 52, 211, 153)),  // 에메랄드
    ("🔵", Color.FromArgb(255, 96, 165, 250),  Color.FromArgb(16, 96, 165, 250)),  // 스카이블루
    ("🟡", Color.FromArgb(255, 251, 191, 36),  Color.FromArgb(16, 251, 191, 36)),  // 앰버/골드
    ("🟣", Color.FromArgb(255, 167, 139, 250), Color.FromArgb(16, 167, 139, 250)), // 퍼플
    ("🔴", Color.FromArgb(255, 248, 113, 113), Color.FromArgb(16, 248, 113, 113)), // 로즈
    ("🟠", Color.FromArgb(255, 251, 146, 60),  Color.FromArgb(16, 251, 146, 60)),  // 오렌지
    ("⚪", Color.FromArgb(255, 200, 200, 200), Color.FromArgb(16, 200, 200, 200)), // 플래티넘
    ("🩵", Color.FromArgb(255, 34, 211, 238),  Color.FromArgb(16, 34, 211, 238)),  // 시안
};

private void AddHostSlot(string defaultHost)
{
    int idx = _nextColorIndex % Palette.Length;
    _nextColorIndex++;

    var slot = new HostSlot
    {
        ColorIndex = idx,
        DotEmoji = Palette[idx].Dot,
        AccentColor = Palette[idx].Color,
        HeaderBg = Palette[idx].Header,
    };
    // 반응형 입력 행 및 독립 결과 패널 동적 바인딩...
}

4. 100건 슬라이딩 윈도우 통계 엔진: Min/Max/Avg 및 패킷 손실률(Loss Rate) 자동 산출

단순한 1회성 핑은 일시적인 지터(Jitter)나 순간 노이즈에 왜곡되기 쉽습니다. 네트워크 회선의 품질을 신뢰성 있게 평가하기 위해서는 최근 N회 패킷의 통계적 평균과 분산을 계산해야 합니다.

각 `HostSlot`은 내부에 100건 제한의 슬라이딩 윈도우 링 버퍼(`RttHistory`)를 유지하며, 응답이 도착할 때마다 4대 핵심 품질 지표를 실시간으로 갱신합니다:

private void UpdateStats(HostSlot slot)
{
    if (slot.RttHistory.Count == 0)
    {
        double loss = slot.TotalSent > 0 ? (double)slot.TotalFail / slot.TotalSent * 100 : 0;
        slot.StatsText.Text = $"전송: {slot.TotalSent} | 손실: {slot.TotalFail} ({loss:F1}%)";
        return;
    }

    // 100건 슬라이딩 윈도우 기반 실시간 통계 계산
    long min = slot.RttHistory.Min();
    long max = slot.RttHistory.Max();
    double avg = slot.RttHistory.Average();
    double lossRate = slot.TotalSent > 0 ? (double)slot.TotalFail / slot.TotalSent * 100 : 0;

    slot.StatsText.Text = $"Min: {min}ms | Max: {max}ms | Avg: {avg:F1}ms | 전송: {slot.TotalSent} (손실 {lossRate:F1}%)";
}
통계 지표 (Metric) 계산 알고리즘 (Algorithm) 회선 상태 판정 기준 (Network Quality Assessment)
최소 지연 (Min RTT) RttHistory.Min() 물리적 광케이블/구리선 대역폭의 한계 지연시간 (기저 성능).
평균 지연 (Avg RTT) RttHistory.Average() 교실 내 트래픽 부하에 따른 실질적인 체감 반응 속도.
최대 지연 (Max RTT) RttHistory.Max() 버퍼블로트(Bufferbloat) 또는 라우터 큐 적체 발생 여부 식별.
손실률 (Loss Rate) (TotalFail / TotalSent) * 100 0% 초과 시 즉시 무선 AP 간섭 또는 스위치 포트 불량 의심.

5. 실시간 마이크로 바 차트: RTT 지연 3단계 동적 색상 매핑과 60건 FIFO 메모리 캡핑

텍스트 숫자만 나열되는 모니터링 화면은 관리자가 한눈에 이상 징후를 감지하기 어렵습니다. ZeliPing은 응답이 도착할 때마다 패널 내부에 수평 마이크로 바 차트(Micro Bar Chart)를 상단 삽입(`Insert(0, barContainer)`)하여 마치 심전도 모니터처럼 최신 지연시간이 실시간으로 흘러내려가도록 렌더링합니다.

private void AddGraphBar(HostSlot slot, long rttMs, bool success)
{
    var barContainer = new Grid { Height = 18, Margin = new Thickness(0, 0, 0, 1) };

    if (success)
    {
        double ratio = Math.Min(rttMs / 200.0, 1.0); // 200ms를 최대 너비 기준으로 정규화
        var bar = new Border
        {
            HorizontalAlignment = HorizontalAlignment.Left,
            Width = Math.Max(ratio * 240, 4), // 최소 4px 보장
            Height = 14,
            CornerRadius = new CornerRadius(3),
            // 지연시간에 따른 3단계 직관적 색상 코딩
            Background = new SolidColorBrush(
                rttMs < 30 ? slot.AccentColor :                 // 🟢 쾌적 (초록/파랑)
                rttMs < 100 ? Color.FromArgb(255, 251, 191, 36) : // 🟡 보통 (노랑)
                Color.FromArgb(255, 248, 113, 113)),             // 🔴 심각한 지연 (빨강)
            Opacity = 0.8
        };
        // ...
    }
    else
    {
        // ❌ 타임아웃/유실 발생 시 전체 영역에 붉은색 경고 바 표시
        var failBar = new Border { /* Background = Red */ };
    }

    // 💡 메모리 누수 방지: 최대 60개 항목만 유지하고 오래된 아이템 자동 제거
    slot.ResultList.Items.Insert(0, barContainer);
    while (slot.ResultList.Items.Count > 60)
        slot.ResultList.Items.RemoveAt(slot.ResultList.Items.Count - 1);
}

오래된 차트 엘리먼트는 60건 엄격 캡핑(FIFO Truncation)을 통해 즉시 가비지 컬렉션되므로, 컴퓨터실에서 24시간 내내 핑을 켜두어도 메모리 사용량이 일정하게 유지됩니다.

6. 멀티스레드 안전성 수호: DispatcherQueue.TryEnqueue와 CancellationTokenSource 즉각 중단

백그라운드 스레드에서 돌아가는 Ping.SendPingAsync가 완료되었을 때, 직접 XAML UI 요소를 조작하면 COMException: The application called an interface that was marshalled for a different thread 크래시가 터집니다.

ZeliPing은 WinUI 3의 DispatcherQueue.TryEnqueue를 엄격하게 적용하여 모든 UI 업데이트(바 차트 추가, 통계 텍스트 갱신, RTT 폰트 변경)를 안전하게 UI 스레드로 마샬링합니다. 또한 사용자가 중지 버튼을 누르는 순간 _cts?.Cancel()을 격발하여 대기 중인 모든 비동기 소켓 I/O를 0.001초 만에 취소하고 안전하게 리소스를 반납합니다.

7. 실무 인프라 감사 시나리오: 교내 게이트웨이·DNS·NEIS 동시 감시와 단선 구간 0초 판별

실제 학교 전산 담당 교사가 겪는 대표적인 장애 상황을 ZeliPing으로 진단하는 방법입니다:

시나리오: 교내 외부망 장애 시 3포인트 동시 대조 진단

호스트 슬롯에 1) 기본 게이트웨이(192.168.1.1), 2) 학교 코어 스위치(10.0.0.1), 3) 교육청 공공 DNS(1.1.1.1)를 동시에 등록하고 핑을 시작합니다:

  • 게이트웨이만 ✕ Timeout: 교실 내부 랜선 또는 로컬 허브 전원 문제.
  • 게이트웨이/스위치는 정상인데 공공 DNS만 ✕ Timeout: 통신사 외부 전용회선 단선 또는 교육청 방화벽 차단.
  • 모든 호스트에서 Max 지연이 500ms 이상 치솟음: 특정 학생 단말기의 대용량 불법 다운로드로 인한 대역폭 포화.

8. 결론: 가장 가볍고 직관적인 온디바이스 네트워크 회선 모니터링의 표준

네트워크 진단 도구의 본질은 "복잡한 네트워크 지표를 얼마나 비전공자도 알기 쉽게 시각화하느냐"에 있습니다. 명령 프롬프트에서 빠르게 지나가는 흑백 텍스트만으로는 순간적인 패킷 드랍이나 간헐적 지터를 포착하기 어렵습니다.

ZeliPing은 Task.WhenAll 동시 비동기 병렬 프로빙, 8색상 순환 호스트 슬롯, 100건 슬라이딩 윈도우 통계 엔진, 그리고 3단계 마이크로 바 차트를 통해 윈도우 데스크톱 환경에서 가장 신속하고 정확한 회선 진단 솔루션을 제공합니다.

이 초경량 진단 엔진이 뒷받침되기에, 전국 학교의 교원들과 군사 작전망의 통신 장교들은 네트워크 장애가 발생하는 즉시 단 1초 만에 원인 구간을 지목하고 수업과 임무를 완수할 수 있습니다.

← 이전 기술 백서 #852 스마트 교실과 군 인트라넷의 비인가 침해 0초 차단: ZeliPort의 netstat -ano 커널 파이프 역추적, Win32Exception 샌드박싱, 및 IPv4/IPv6 중복 배제 실시간 포트 감사 아키텍처 다음 기술 백서 → #850 [제150편 기념] 72종 데스크톱 유틸리티와 AI 패밀리의 단일 진실 공급원(SSOT): ZeliDesk 선언적 레지스트리, AssemblyLoadContext 플러그인 격리, 및 0ms 원자적 윈도우 오케스트레이션 총결산 아키텍처
⚡ ZeliPing 실시간 병렬 네트워크 진단 체험하기

단 0.1초 만에 다중 호스트 회선 단선을 밝혀내는 ZeliPing을 지금 만나보세요.

ZeliDesk Suite 무료 다운로드