안동민 개발노트

본문 시작

데이터 전송의 기본 원리

회선 교환과 패킷 교환을 비교하고 패킷 구조·지연·대역폭·처리량을 이용해 네트워크 성능과 혼잡을 해석합니다.

네트워크가 무엇이고 인터넷이 어떤 구조인지 이해했다면, 이제 그 안에서 데이터가 실제로 어떻게 전달되는지를 들여다볼 차례입니다.

인터넷이 느리다라는 말을 할 때, 정확히 무엇이 느린 것인지 자신 있게 대답할 수 있는 사람은 많지 않습니다.

이 절에서 다루는 교환 방식과 성능 지표를 이해하면, 그 질문에 답할 수 있게 됩니다.


회선 교환 vs 패킷 교환

데이터를 목적지까지 전달하는 방식은 크게 두 가지입니다.

회선 교환(Circuit Switching)은 통신을 시작하기 전에 송신자와 수신자 사이에 전용 경로(회선)를 미리 설정하는 방식입니다.

회선 교환: 전용 경로 독점
[A] ════════════════════════> [B]   (통화 중 — 회선 점유)
     다른 이용자 사용 불가

과거의 전화 통화를 떠올리면 됩니다.

전화를 걸면 두 사람을 위한 회선 자원이 예약되고, 통화가 끝날 때까지 그 예약분은 다른 사용자가 사용할 수 없습니다. 위 그림의 독점은 예약 자원을 뜻하며 물리 케이블 전체의 독점만을 뜻하지는 않습니다. 시분할·주파수분할로 한 매체를 나누어 쓸 수도 있습니다.

대역폭이 안정적으로 보장되지만, 대화가 잠시 멈추는 순간에도 회선을 계속 점유하기 때문에 자원 낭비가 심합니다.

패킷 교환(Packet Switching)은 데이터를 패킷(Packet)이라는 작은 단위로 나누어 독립적으로 전송하는 방식입니다.

각 패킷은 목적지 주소 같은 전달 정보를 가지고 있으며, 라우터는 패킷마다 다음 홉을 결정합니다.

같은 흐름의 패킷이 항상 다른 경로를 타는 것은 아니지만, 라우팅 변화나 부하 분산 환경에서는 서로 다른 경로로 갈 수도 있습니다.

수신 측 또는 전송 계층은 필요한 경우 순서를 맞추고 손실을 복구합니다.

기준회선 교환 / 패킷 교환
연결·경로회선: 통신 전에 경로와 자원 예약. 패킷: 공유 링크에서 패킷마다 다음 홉 결정.
자원 효율회선: 유휴 시간에도 예약분 점유. 패킷: 트래픽이 있을 때 링크 자원 사용.
지연회선: 예약 후 비교적 일정. 패킷: 혼잡·큐잉·라우팅 상태에 따라 가변.
확장회선: 연결 수와 예약 자원에 제한. 패킷: 여러 흐름이 인프라를 공유.
장애회선: 예약 경로 장애 시 재설정 필요. 패킷: 대체 경로가 있고 라우팅이 수렴하면 우회 가능.
용도회선: 전통 전화망·전용 회선. 패킷: 인터넷·데이터 중심 네트워크.

오늘날의 인터넷은 기본적으로 패킷 교환 방식을 기반으로 동작합니다.

다만 MPLS, 전용 회선, 가상 회선처럼 운영자가 특정 경로나 품질을 관리하는 기술도 함께 쓰일 수 있습니다.


패킷의 구조

대부분의 네트워크 전송 단위는 크게 헤더(Header)와 페이로드(Payload)로 이해할 수 있습니다.

데이터 링크 계층 프레임처럼 끝에 FCS 같은 트레일러(Trailer)가 붙는 경우도 있습니다.

헤더는 전달과 처리를 위한 메타데이터를 담고 있습니다.

계층에 따라 출발지/목적지 주소, 포트 번호, 프로토콜 번호, TTL/Hop Limit, 순서 번호 같은 정보가 들어갑니다.

페이로드는 실제로 전달하려는 데이터, 즉 "상자 안의 물건"입니다.

네트워크의 각 계층은 패킷에 자신만의 헤더를 추가합니다.

이 과정을 캡슐화(Encapsulation)라고 합니다.

수신 측에서는 역순으로 각 계층의 헤더를 벗겨내며(역캡슐화), 최종적으로 애플리케이션 데이터를 얻습니다.

MTU와 단편화

MTU(Maximum Transmission Unit)는 특정 링크에서 한 번에 실을 수 있는 최대 L3 패킷 크기입니다.

일반 이더넷의 MTU는 보통 1500바이트이지만, PPPoE, VPN, 터널링, 점보 프레임 환경에서는 달라질 수 있습니다.

아래 계산은 옵션 없는 IPv4/TCP 헤더를 가정합니다. 10 KiB 파일의 TCP 페이로드를 매번 MSS만큼 채울 때의 개수를 계산하며 TLS·응용 헤더나 실제 세그먼트 분할을 관측한 값은 아닙니다.

mtu_check.py
ETHERNET_MTU = 1500
IP_HEADER = 20
TCP_HEADER = 20
MSS = ETHERNET_MTU - IP_HEADER - TCP_HEADER  # Maximum Segment Size

print(f"MTU: {ETHERNET_MTU} bytes")
print(f"IP 헤더: {IP_HEADER} bytes")
print(f"TCP 헤더: {TCP_HEADER} bytes")
print(f"MSS (실제 데이터): {MSS} bytes")

# 10KiB 파일 전송 시 필요한 세그먼트 수
file_size = 10 * 1024
segments = -(-file_size // MSS)  # 올림 나눗셈
print(f"\n10KiB 전송 → {segments}개 세그먼트 필요")

전송하려는 IP 패킷이 경로의 MTU를 초과하면 단편화(Fragmentation) 문제가 생깁니다.

IPv4에서는 DF 비트가 꺼져 있으면 라우터가 단편화할 수 있지만, DF가 켜져 있으면 ICMP 오류로 송신자에게 더 작은 크기를 요구합니다.

IPv6에서는 중간 라우터가 단편화하지 않고, 송신자가 Fragment 헤더를 사용해야 합니다.

단편화는 오버헤드와 손실 영향을 키우므로, 현대 네트워크에서는 Path MTU Discovery 또는 Packetization Layer PMTUD로 경로상 최소 MTU를 파악하고 전송 크기를 조절하는 방식이 중요합니다.


지연, 대역폭, 처리량

네트워크 성능을 논할 때 반드시 구분해야 하는 세 가지 핵심 지표입니다.

지연 (Latency)

지연(Latency)은 데이터가 출발지에서 목적지까지 도달하는 데 걸리는 시간입니다.

지연을 만드는 네 가지 요인

지연을 만드는 네 가지 요인

지연을 만드는 네 가지 요인
유형시간을 만드는 요인줄이는 방법
전파 지연거리 ÷ 매체 내 신호 속도. 같은 속도라면 경로가 길수록 증가합니다.가까운 서버·CDN으로 경로 길이를 줄입니다.
전송 지연데이터 비트 수 ÷ 링크 전송률. 큰 패킷·낮은 전송률에서 증가합니다.전송률을 높이거나 압축·전송량 축소를 사용합니다.
처리 지연장비의 헤더 검사·처리 시간. 장비 성능과 기능에 따라 달라집니다.처리 용량을 확보하고 불필요한 처리를 줄입니다.
큐잉 지연송신 버퍼에서 앞선 데이터를 기다리는 시간. 혼잡·트래픽 집중에 따라 증가합니다.혼잡 제어·QoS·트래픽 분산을 적용합니다.
전파 지연
시간을 만드는 요인: 거리 ÷ 매체 내 신호 속도. 같은 속도라면 경로가 길수록 증가합니다.
줄이는 방법: 가까운 서버·CDN으로 경로 길이를 줄입니다.
전송 지연
시간을 만드는 요인: 데이터 비트 수 ÷ 링크 전송률. 큰 패킷·낮은 전송률에서 증가합니다.
줄이는 방법: 전송률을 높이거나 압축·전송량 축소를 사용합니다.
처리 지연
시간을 만드는 요인: 장비의 헤더 검사·처리 시간. 장비 성능과 기능에 따라 달라집니다.
줄이는 방법: 처리 용량을 확보하고 불필요한 처리를 줄입니다.
큐잉 지연
시간을 만드는 요인: 송신 버퍼에서 앞선 데이터를 기다리는 시간. 혼잡·트래픽 집중에 따라 증가합니다.
줄이는 방법: 혼잡 제어·QoS·트래픽 분산을 적용합니다.

다음은 Linux 계열 도구의 명령 예시이며 주석의 RTT 숫자는 예시 출력입니다. 새 측정 결과가 아닙니다. curl의 time_* 값은 시작 시점부터의 누적 시간입니다. 단일 새 연결에서 TCP 연결 구간은 time_connect - time_namelookup, TLS 구간은 time_appconnect - time_connect로 구분하며, 재사용·리다이렉트 조건은 별도로 확인해야 합니다.

latency_measurement.sh
# RTT(Round-Trip Time) 측정
ping -c 10 google.com
# 결과: min/avg/max/mdev = 3.2/4.1/5.8/0.7 ms

# 경로별 지연 측정
traceroute -n google.com
# 각 홉(라우터)에서의 RTT를 확인

# HTTP 요청의 각 단계별 시간 측정
curl -w "\nDNS: %{time_namelookup}s\nConnect: %{time_connect}s\nTLS: %{time_appconnect}s\nFirst byte: %{time_starttransfer}s\nTotal: %{time_total}s\n" -o /dev/null -s https://example.com

대역폭과 처리량

대역폭(Bandwidth)은 단위 시간당 전송할 수 있는 최대 데이터량입니다.

보통 bps, Kbps, Mbps, Gbps 같은 단위로 표기합니다.

처리량(Throughput)은 실제로 전송된 데이터량입니다.

혼잡, 패킷 손실, 프로토콜 오버헤드, 수신/송신 장비 성능 때문에 처리량은 보통 명목 대역폭보다 낮습니다.

아래 함수는 손실률과 오버헤드 비율을 선형으로 곱하는 수치 연습 모델입니다. 실제 TCP 처리량은 RTT·혼잡 제어·재전송 등에 영향을 받으므로 이 식이 측정 결과나 일반적인 예측을 보장하지 않습니다. 파일 크기 GB와 전송률 Mbps는 여기서 모두 십진 단위입니다.

bandwidth_vs_throughput.py
def calculate_throughput(bandwidth_mbps, packet_loss_pct, overhead_pct):
    """단순 비율 모델의 처리량 추정"""
    effective = bandwidth_mbps * (1 - packet_loss_pct / 100)
    effective *= (1 - overhead_pct / 100)
    return effective

# 1Gbps 회선, 패킷 손실 0.1%, 프로토콜 오버헤드 5%
throughput = calculate_throughput(1000, 0.1, 5)
print(f"대역폭: 1000 Mbps")
print(f"모형 처리량: {throughput:.1f} Mbps")

# 대용량 파일 전송 시간 추정
file_size_gb = 10
transfer_time = (file_size_gb * 8 * 1000) / throughput
print(f"\n10GB 파일 전송: {transfer_time:.0f}초 ({transfer_time/60:.1f}분)")

정리하면 대역폭은 링크가 제공하는 이론적 상한, 지연은 한 데이터 단위가 도착하기까지 걸리는 시간, 처리량은 손실·혼잡·오버헤드를 반영한 실제 전송량입니다.


병목과 혼잡의 차이

네트워크가 느리다라는 증상은 같지만, 원인은 크게 두 가지로 나뉩니다.

병목(Bottleneck)은 경로 중 가장 좁은(대역폭이 낮은) 구간이 전체 성능을 제한하는 현상입니다.

서버 ──1Gbps──→ 라우터 ──1Gbps──→ ISP ──100Mbps──→ 사용자
                                           ↑
                                      병목 지점!
                                  처리량 상한 = 100Mbps

혼잡(Congestion)은 특정 지점에 트래픽이 한꺼번에 몰려 큐잉 지연이 급증하고, 심하면 패킷 손실이 발생하는 현상입니다.

라우터는 버퍼가 가득 차기 전에도 AQM·ECN으로 혼잡을 알릴 수 있습니다. ECN 표시가 저장 공간을 만드는 것은 아니므로, 버퍼에 여유가 없으면 패킷을 버려야 합니다.

송신 측이 손실을 감지하고 재전송을 늘리는데 전송량을 줄이지 않으면, 재전송 트래픽이 다시 혼잡을 키워 혼잡 붕괴(Congestion Collapse)로 이어질 수 있습니다.

그래서 TCP 혼잡 제어는 손실이나 ECN 신호를 기반으로 송신량을 조절합니다.

구분병목 / 혼잡
원인병목: 경로의 상대적으로 낮은 용량. 혼잡: 순간 트래픽 집중·버퍼 대기.
시간 특성병목: 구조적으로 오래 지속될 수 있음. 혼잡: 시간대·부하에 따라 변동.
증상병목: 처리량 상한 제한. 혼잡: 지연·지터 증가·패킷 손실.
대응병목: 회선 증설·CDN·캐시·경로 개선. 혼잡: 혼잡 제어·QoS·로드 밸런싱·AQM.

다음도 실행 관측이 없는 명령 예시입니다. mtr 중간 홉의 손실은 ICMP 응답 제한이나 반환 경로 차이일 수 있으므로 그 홉을 병목으로 단정하지 않습니다. iperf3는 접근 권한이 있는 대응 서버와 측정 조건을 준비해야 합니다.

bottleneck_check.sh
# 경로상 병목 확인
mtr -rw -c 20 example.com
# 각 홉의 패킷 손실률과 지연을 확인

# 대역폭 측정 (서버 필요)
iperf3 -c server.example.com -t 30
# → 실제 achievable throughput 측정

이어지는 장에서는 이처럼 복잡한 네트워크의 동작을 체계적으로 이해하기 위해, 통신을 계층별로 분리하는 모델을 살펴보겠습니다.