본 콘텐츠의 이미지 및 내용은 AI로 생성되었습니다.
본 콘텐츠의 이미지 및 내용을 무단으로 복제, 배포, 수정하여 사용할 경우 저작권법에 의해 법적 제재를 받을 수 있습니다.
이미지 로딩 중...
AI Generated
2025. 12. 5. · 13 Views
캡슐화와 PDU 완벽 이해 가이드
네트워크에서 데이터가 어떻게 포장되고 전달되는지, 캡슐화와 역캡슐화 과정부터 PDU, 트래픽, 처리율까지 초급 개발자를 위해 쉽게 설명합니다.
목차
- 캡슐화(Encapsulation)_과정_이해
- 역캡슐화(Decapsulation)_과정
- PDU(Protocol_Data_Unit)란
- 각_계층별_PDU_명칭
- 트래픽(Traffic)_개념
- 처리율(Throughput)과_대역폭(Bandwidth)
- 패킷_손실(Packet_Loss)_이해
1. 캡슐화(Encapsulation) 과정 이해
어느 날 김개발 씨가 네트워크 관련 업무를 맡게 되었습니다. 패킷 분석 도구를 열어보니 알 수 없는 헤더들이 겹겹이 쌓여 있었습니다.
"도대체 이 데이터들은 어디서 온 걸까요?" 선배 박시니어 씨가 웃으며 말합니다. "그건 캡슐화 때문이에요."
캡슐화는 상위 계층에서 하위 계층으로 데이터가 내려갈 때마다 각 계층의 헤더 정보를 추가하는 과정입니다. 마치 편지를 보낼 때 편지지를 봉투에 넣고, 그 봉투를 상자에 넣고, 상자를 택배 박스에 넣는 것과 같습니다.
각 단계마다 필요한 정보가 겹겹이 포장되어 최종 목적지까지 안전하게 전달됩니다.
다음 코드를 살펴봅시다.
# 네트워크 캡슐화 과정 시뮬레이션
def encapsulate_data(application_data):
# 응용 계층: 원본 데이터
data = application_data
# 전송 계층: TCP/UDP 헤더 추가
transport_header = {"src_port": 8080, "dst_port": 80}
segment = {"header": transport_header, "data": data}
# 네트워크 계층: IP 헤더 추가
network_header = {"src_ip": "192.168.1.1", "dst_ip": "10.0.0.1"}
packet = {"header": network_header, "data": segment}
# 데이터링크 계층: 이더넷 헤더 + 트레일러 추가
datalink_header = {"src_mac": "AA:BB:CC:DD:EE:FF", "dst_mac": "11:22:33:44:55:66"}
frame = {"header": datalink_header, "data": packet, "trailer": "FCS"}
return frame
김개발 씨는 입사 6개월 차 주니어 개발자입니다. 오늘 처음으로 Wireshark라는 패킷 분석 도구를 열어보게 되었습니다.
화면에는 낯선 데이터들이 빼곡히 나열되어 있었습니다. 분명 자신이 보낸 건 "Hello, World!"라는 간단한 메시지였는데, 왜 이렇게 복잡해 보이는 걸까요?
선배 개발자 박시니어 씨가 다가와 모니터를 들여다봅니다. "캡슐화 과정을 이해하면 이게 다 보여요." 그렇다면 캡슐화란 정확히 무엇일까요?
쉽게 비유하자면, 캡슐화는 마치 해외로 선물을 보내는 것과 같습니다. 먼저 선물을 포장지로 감쌉니다.
그 다음 완충재와 함께 상자에 넣습니다. 상자에는 받는 사람 이름을 적습니다.
그리고 택배 회사용 송장을 붙입니다. 마지막으로 국제 배송을 위한 세관 서류를 첨부합니다.
각 단계마다 필요한 정보가 추가되는 것이죠. 네트워크에서도 똑같은 일이 일어납니다.
우리가 웹 브라우저에서 데이터를 보내면, 그 데이터는 여러 계층을 거치며 포장됩니다. 먼저 응용 계층에서 시작합니다.
여기서는 HTTP, FTP 같은 프로토콜이 사용됩니다. 우리가 보내려는 원본 데이터가 바로 이 계층에 있습니다.
다음은 전송 계층입니다. 이 계층에서는 TCP나 UDP 헤더가 추가됩니다.
출발지 포트와 목적지 포트 정보가 여기에 담깁니다. 마치 편지에 발신인과 수신인의 전화번호를 적는 것과 같습니다.
그 다음 네트워크 계층에서 IP 헤더가 추가됩니다. 출발지 IP 주소와 목적지 IP 주소가 이 헤더에 포함됩니다.
이건 편지의 주소와 같은 역할을 합니다. 마지막으로 데이터링크 계층에서 이더넷 헤더와 트레일러가 붙습니다.
MAC 주소 정보가 여기에 담기고, 오류 검출을 위한 FCS도 추가됩니다. 위의 코드를 살펴보겠습니다.
가장 먼저 application_data라는 원본 데이터로 시작합니다. 그 다음 전송 계층에서 포트 정보가 담긴 헤더를 추가해 세그먼트를 만듭니다.
네트워크 계층에서는 IP 정보를 추가해 패킷이 됩니다. 마지막으로 데이터링크 계층에서 MAC 주소와 오류 검출 코드를 붙여 프레임이 완성됩니다.
실제 현업에서는 이 과정을 직접 구현할 일은 거의 없습니다. 운영체제와 네트워크 스택이 알아서 처리해주기 때문입니다.
하지만 네트워크 문제를 디버깅할 때, 패킷 분석을 할 때, 이 원리를 아는 것과 모르는 것은 천지 차이입니다. 다시 김개발 씨의 이야기로 돌아가 봅시다.
박시니어 씨의 설명을 들은 김개발 씨는 Wireshark 화면을 다시 바라봅니다. 이제 그 복잡해 보이던 데이터가 질서정연한 포장 과정으로 보이기 시작했습니다.
실전 팁
💡 - 캡슐화는 항상 상위 계층에서 하위 계층 방향으로 진행됩니다
- 각 계층에서 추가된 헤더는 해당 계층의 프로토콜 정보를 담고 있습니다
2. 역캡슐화(Decapsulation) 과정
김개발 씨가 이제 캡슐화를 이해했습니다. 그런데 문득 궁금해졌습니다.
"그럼 받는 쪽에서는 어떻게 이 포장을 풀죠?" 박시니어 씨가 답합니다. "그게 바로 역캡슐화예요.
캡슐화의 정반대 과정이죠."
역캡슐화는 수신 측에서 데이터를 받았을 때 하위 계층부터 상위 계층으로 올라가며 각 계층의 헤더를 순차적으로 제거하는 과정입니다. 마치 택배를 받았을 때 송장을 떼고, 상자를 열고, 완충재를 걷어내고, 마지막으로 포장지를 벗겨 선물을 꺼내는 것과 같습니다.
각 단계마다 해당 계층의 정보를 읽고 처리한 뒤 다음 계층으로 전달합니다.
다음 코드를 살펴봅시다.
# 네트워크 역캡슐화 과정 시뮬레이션
def decapsulate_frame(frame):
# 데이터링크 계층: 이더넷 헤더 확인 및 제거
print(f"MAC 확인: {frame['header']['dst_mac']}")
packet = frame['data']
# 네트워크 계층: IP 헤더 확인 및 제거
print(f"IP 확인: {packet['header']['dst_ip']}")
segment = packet['data']
# 전송 계층: TCP/UDP 헤더 확인 및 제거
print(f"포트 확인: {segment['header']['dst_port']}")
data = segment['data']
# 응용 계층: 원본 데이터 전달
return data
# 실행 결과: 원본 애플리케이션 데이터 반환
김개발 씨는 캡슐화를 이해하고 나니 자연스럽게 다음 질문이 떠올랐습니다. 데이터를 보낼 때 이렇게 겹겹이 포장한다면, 받는 쪽에서는 어떻게 원래 데이터를 꺼내는 걸까요?
박시니어 씨가 설명을 이어갑니다. "역캡슐화는 말 그대로 캡슐화의 반대 과정이에요.
포장을 푸는 거죠." 역캡슐화를 일상적인 비유로 설명해보겠습니다. 해외에서 선물이 도착했다고 상상해봅시다.
먼저 세관 서류를 확인합니다. 문제가 없으면 택배 송장을 떼어냅니다.
그 다음 상자를 열고 완충재를 걷어냅니다. 포장지를 벗기면 드디어 선물이 나타납니다.
각 단계에서 해당 정보를 확인하고 처리한 뒤, 안에 있는 내용물을 다음 단계로 전달하는 것입니다. 네트워크에서 역캡슐화는 수신 측 컴퓨터에서 일어납니다.
데이터가 네트워크 카드에 도착하면 가장 먼저 데이터링크 계층이 프레임을 받습니다. 데이터링크 계층에서는 먼저 목적지 MAC 주소를 확인합니다.
자신의 MAC 주소와 일치하면 이더넷 헤더와 트레일러를 제거하고, 안에 있는 패킷을 네트워크 계층으로 올려보냅니다. 만약 MAC 주소가 일치하지 않으면 그 프레임은 버려집니다.
네트워크 계층에서는 IP 헤더를 확인합니다. 목적지 IP 주소가 자신의 것인지 검사합니다.
맞다면 IP 헤더를 제거하고 세그먼트를 전송 계층으로 전달합니다. 전송 계층에서는 포트 번호를 확인합니다.
어떤 애플리케이션이 이 데이터를 기다리고 있는지 포트 번호로 알 수 있습니다. TCP나 UDP 헤더를 제거하고 원본 데이터를 해당 애플리케이션에 전달합니다.
마지막으로 응용 계층에서 애플리케이션이 원본 데이터를 받습니다. 웹 브라우저라면 HTML을 렌더링하고, 이메일 클라이언트라면 메일 내용을 표시합니다.
위의 코드를 보면 이 과정이 명확하게 드러납니다. frame에서 시작해서 각 계층의 헤더를 확인하고 제거한 뒤, 최종적으로 원본 data를 반환합니다.
실제 네트워크 스택에서는 각 계층이 자신의 역할만 수행하고 나머지는 신경 쓰지 않습니다. 중요한 점이 있습니다.
역캡슐화 과정에서 각 계층은 자신의 헤더만 읽을 수 있습니다. 데이터링크 계층은 IP 헤더의 내용을 알 수 없고, 네트워크 계층은 TCP 헤더의 내용을 이해하지 못합니다.
이것이 바로 계층화의 핵심입니다. 각 계층이 독립적으로 동작하면서도 전체적으로는 완벽하게 협력합니다.
김개발 씨가 고개를 끄덕입니다. "아, 그래서 네트워크를 계층으로 나눈 거군요.
각자 맡은 일만 하면 되니까요."
실전 팁
💡 - 역캡슐화는 항상 하위 계층에서 상위 계층 방향으로 진행됩니다
- 각 계층은 자신의 헤더만 읽고 처리할 수 있습니다
3. PDU(Protocol Data Unit)란
김개발 씨가 네트워크 문서를 읽다가 이상한 용어를 발견했습니다. "세그먼트, 패킷, 프레임...
다 같은 거 아닌가요?" 박시니어 씨가 고개를 젓습니다. "아니요, 각 계층에서 부르는 이름이 달라요.
그걸 통틀어서 PDU라고 해요."
**PDU(Protocol Data Unit)**는 각 네트워크 계층에서 처리하는 데이터 단위를 말합니다. 마치 같은 물건이라도 공장에서는 "제품", 창고에서는 "재고", 매장에서는 "상품"이라고 부르는 것처럼, 동일한 데이터가 계층에 따라 다른 이름으로 불립니다.
PDU라는 용어는 이러한 계층별 데이터 단위를 통칭할 때 사용합니다.
다음 코드를 살펴봅시다.
# 각 계층별 PDU 구조 표현
class PDU:
"""Protocol Data Unit - 각 계층의 데이터 단위"""
# 응용 계층 PDU
application_pdu = "Data (데이터)"
# 전송 계층 PDU
transport_pdu_tcp = "Segment (세그먼트)" # TCP 사용 시
transport_pdu_udp = "Datagram (데이터그램)" # UDP 사용 시
# 네트워크 계층 PDU
network_pdu = "Packet (패킷)"
# 데이터링크 계층 PDU
datalink_pdu = "Frame (프레임)"
# 물리 계층 PDU
physical_pdu = "Bit (비트)"
김개발 씨는 네트워크 관련 기술 문서를 읽으면서 혼란에 빠졌습니다. 어떤 문서에서는 "패킷"이라고 하고, 다른 문서에서는 "프레임"이라고 합니다.
또 어디서는 "세그먼트"라는 용어가 나옵니다. 다 같은 데이터를 말하는 것 같은데, 왜 이렇게 용어가 다른 걸까요?
박시니어 씨가 친절하게 설명합니다. "이건 마치 사람을 부르는 호칭과 비슷해요." 집에서는 "아들"이라고 불리는 사람이, 회사에서는 "김 대리"로 불립니다.
친구들 사이에서는 "개발이"라는 별명으로 불릴 수도 있죠. 같은 사람인데 상황과 관계에 따라 호칭이 달라지는 것입니다.
네트워크에서도 마찬가지입니다. 동일한 데이터가 각 계층을 지나가면서 다른 이름으로 불립니다.
이러한 계층별 데이터 단위를 통틀어 **PDU(Protocol Data Unit)**라고 합니다. PDU라는 용어가 필요한 이유가 있습니다.
네트워크 엔지니어나 개발자들이 대화할 때, "그 데이터"라고 하면 정확히 어느 계층의 데이터인지 알 수 없습니다. 하지만 "그 패킷"이라고 하면 네트워크 계층의 데이터라는 것이 명확해집니다.
"그 프레임"이라고 하면 데이터링크 계층의 데이터라는 것을 바로 알 수 있습니다. 이것은 단순한 명명 규칙이 아닙니다.
각 PDU는 해당 계층의 특성을 반영합니다. 프레임에는 MAC 주소 정보가 있고, 패킷에는 IP 주소 정보가 있습니다.
세그먼트에는 포트 번호가 있습니다. PDU 이름만 들어도 어떤 정보가 포함되어 있는지 유추할 수 있는 것입니다.
네트워크 문제를 진단할 때도 PDU 개념은 중요합니다. "패킷 손실이 발생한다"는 말은 네트워크 계층에서 문제가 있다는 의미입니다.
"프레임 오류가 많다"는 말은 데이터링크 계층이나 물리적 연결에 문제가 있을 수 있다는 신호입니다. 김개발 씨가 질문합니다.
"그럼 모든 계층의 PDU 이름을 외워야 하나요?" 박시니어 씨가 웃으며 답합니다. "자주 사용하는 건 자연스럽게 외워져요.
특히 세그먼트, 패킷, 프레임은 정말 많이 쓰이니까 꼭 기억해두세요."
실전 팁
💡 - PDU는 특정 계층의 데이터 단위를 지칭할 때 사용하는 용어입니다
- 네트워크 문제 진단 시 PDU 이름으로 문제 계층을 파악할 수 있습니다
4. 각 계층별 PDU 명칭
김개발 씨가 본격적으로 각 계층의 PDU 이름을 정리하기로 했습니다. "응용 계층은 데이터, 전송 계층은 세그먼트..." 박시니어 씨가 끼어듭니다.
"잠깐, UDP는 세그먼트가 아니라 데이터그램이에요. 세부 사항도 중요해요."
각 네트워크 계층은 고유한 PDU 명칭을 가지고 있습니다. 응용 계층에서는 데이터(Data), 전송 계층에서는 TCP일 때 세그먼트(Segment), UDP일 때 **데이터그램(Datagram)**이라고 합니다.
네트워크 계층에서는 패킷(Packet), 데이터링크 계층에서는 프레임(Frame), 물리 계층에서는 **비트(Bit)**라고 부릅니다.
다음 코드를 살펴봅시다.
# 계층별 PDU와 주요 정보
LAYER_PDU_INFO = {
"L7_Application": {
"pdu_name": "Data",
"korean": "데이터",
"protocols": ["HTTP", "FTP", "SMTP", "DNS"]
},
"L4_Transport": {
"pdu_name": "Segment/Datagram",
"korean": "세그먼트/데이터그램",
"key_info": "포트 번호",
"protocols": ["TCP", "UDP"]
},
"L3_Network": {
"pdu_name": "Packet",
"korean": "패킷",
"key_info": "IP 주소",
"protocols": ["IP", "ICMP", "ARP"]
},
"L2_DataLink": {
"pdu_name": "Frame",
"korean": "프레임",
"key_info": "MAC 주소",
"protocols": ["Ethernet", "Wi-Fi"]
},
"L1_Physical": {
"pdu_name": "Bit",
"korean": "비트",
"description": "전기/광 신호"
}
}
김개발 씨가 노트를 펴고 각 계층의 PDU 이름을 정리하기 시작했습니다. 체계적으로 알아두면 나중에 큰 도움이 될 것 같았습니다.
가장 위에 있는 응용 계층부터 시작합니다. 이 계층에서는 사용자가 실제로 다루는 데이터가 있습니다.
HTTP 요청, 이메일 내용, 파일 데이터 등이 모두 여기에 해당합니다. 이 계층의 PDU는 단순히 **데이터(Data)**라고 부릅니다.
아직 어떤 프로토콜 헤더도 붙지 않은 순수한 정보입니다. 전송 계층은 조금 특별합니다.
사용하는 프로토콜에 따라 PDU 이름이 달라집니다. TCP를 사용할 때는 **세그먼트(Segment)**라고 부릅니다.
TCP는 데이터를 여러 조각으로 나누어 보내기 때문에 "조각"이라는 의미의 세그먼트라는 이름이 붙었습니다. 반면 UDP를 사용할 때는 **데이터그램(Datagram)**이라고 합니다.
UDP는 데이터를 나누지 않고 독립적인 단위로 보내기 때문입니다. 네트워크 계층의 PDU는 **패킷(Packet)**입니다.
이 이름이 가장 널리 알려져 있습니다. "인터넷 패킷", "패킷 손실"처럼 일상적으로도 많이 사용되는 용어입니다.
패킷에는 출발지와 목적지의 IP 주소가 포함되어 있어서 네트워크를 통해 어디로 가야 하는지 알 수 있습니다. 데이터링크 계층의 PDU는 **프레임(Frame)**입니다.
프레임에는 MAC 주소 정보가 들어있습니다. 같은 네트워크 내에서 정확히 어떤 장치로 데이터를 보내야 하는지 프레임이 결정합니다.
프레임의 끝에는 오류 검출을 위한 FCS(Frame Check Sequence)도 포함됩니다. 마지막으로 물리 계층의 PDU는 **비트(Bit)**입니다.
모든 데이터는 결국 0과 1의 연속인 비트로 변환되어 전선이나 광케이블을 통해 전송됩니다. 이 계층에서는 전기 신호, 빛 신호, 전파 등 물리적인 신호로 데이터가 전달됩니다.
박시니어 씨가 덧붙입니다. "실무에서는 L2, L3, L4처럼 계층 번호로 말하는 경우도 많아요.
L3 스위치라고 하면 네트워크 계층까지 처리할 수 있는 스위치라는 뜻이에요." 김개발 씨가 정리를 마치고 말합니다. "비트, 프레임, 패킷, 세그먼트, 데이터.
아래에서 위로 올라가면서 외우면 되겠네요."
실전 팁
💡 - TCP는 세그먼트, UDP는 데이터그램으로 구분해서 기억하세요
- L2, L3, L4 같은 계층 번호 표기도 실무에서 자주 사용됩니다
5. 트래픽(Traffic) 개념
어느 날 김개발 씨의 서비스에 갑자기 장애가 발생했습니다. 모니터링 대시보드에는 "트래픽 급증"이라는 알림이 떠 있었습니다.
"트래픽이 정확히 뭐예요? 그냥 접속자 수 아닌가요?" 박시니어 씨가 차분히 설명을 시작합니다.
**트래픽(Traffic)**은 네트워크를 통해 이동하는 데이터의 양을 의미합니다. 마치 도로 위를 지나다니는 자동차의 흐름을 "교통량"이라고 부르는 것처럼, 네트워크 회선을 통해 오가는 데이터의 흐름을 트래픽이라고 합니다.
트래픽은 보통 초당 비트 수(bps)나 초당 바이트 수(Bps)로 측정됩니다.
다음 코드를 살펴봅시다.
# 트래픽 측정 및 분석 예제
import time
class TrafficMonitor:
def __init__(self):
self.bytes_sent = 0
self.bytes_received = 0
self.start_time = time.time()
def record_traffic(self, sent, received):
self.bytes_sent += sent
self.bytes_received += received
def get_traffic_rate(self):
elapsed = time.time() - self.start_time
# 초당 바이트를 Mbps로 변환
sent_mbps = (self.bytes_sent * 8 / elapsed) / 1_000_000
recv_mbps = (self.bytes_received * 8 / elapsed) / 1_000_000
return {"upload_mbps": sent_mbps, "download_mbps": recv_mbps}
def get_total_traffic(self):
total_mb = (self.bytes_sent + self.bytes_received) / 1_000_000
return f"총 트래픽: {total_mb:.2f} MB"
김개발 씨가 처음으로 대규모 트래픽 장애를 경험했습니다. 서비스가 느려지고 일부 사용자는 접속조차 못하는 상황이었습니다.
모니터링 도구에서는 그래프가 치솟아 있었고, "트래픽 초과"라는 경고가 연신 울렸습니다. 트래픽은 쉽게 말해 네트워크 도로 위를 달리는 데이터 자동차들의 흐름입니다.
출퇴근 시간에 도로가 막히는 것처럼, 많은 사용자가 동시에 서비스를 이용하면 네트워크도 혼잡해집니다. 트래픽을 측정하는 단위를 알아야 합니다.
가장 기본적인 단위는 **bps(bits per second)**입니다. 초당 몇 비트의 데이터가 이동하는지를 나타냅니다.
하지만 bps는 단위가 너무 작아서 보통 **Mbps(메가비트)**나 **Gbps(기가비트)**를 사용합니다. 여기서 주의할 점이 있습니다.
Mbps와 MBps는 다릅니다. 소문자 b는 비트(bit), 대문자 B는 바이트(Byte)를 의미합니다.
1바이트는 8비트이므로, 100Mbps는 약 12.5MBps와 같습니다. 인터넷 속도는 보통 Mbps로 표시하고, 파일 다운로드 속도는 MBps로 표시하는 경우가 많아서 혼란이 생기기도 합니다.
트래픽에는 두 가지 방향이 있습니다. 서버에서 사용자에게 나가는 아웃바운드(Outbound) 트래픽과, 사용자가 서버로 보내는 인바운드(Inbound) 트래픽입니다.
웹 서비스의 경우 보통 아웃바운드 트래픽이 훨씬 많습니다. 사용자가 보내는 요청은 작지만, 서버가 응답으로 보내는 HTML, 이미지, 동영상 등은 크기가 크기 때문입니다.
클라우드 서비스를 이용할 때 트래픽은 비용과 직결됩니다. AWS, GCP 같은 클라우드 제공자들은 아웃바운드 트래픽에 대해 비용을 청구합니다.
트래픽이 많은 서비스는 월 수백만 원의 트래픽 비용이 나올 수도 있습니다. 위의 코드를 보면 트래픽을 어떻게 측정하는지 알 수 있습니다.
송신과 수신 바이트를 누적해서 기록하고, 경과 시간으로 나누어 초당 전송률을 계산합니다. 실제 모니터링 도구들도 이와 비슷한 원리로 동작합니다.
김개발 씨가 물었습니다. "그럼 트래픽이 많으면 무조건 나쁜 건가요?" 박시니어 씨가 웃으며 답합니다.
"트래픽이 많다는 건 그만큼 사용자가 많다는 뜻이에요. 좋은 거죠.
다만 그 트래픽을 감당할 수 있는 인프라가 준비되어 있어야 해요."
실전 팁
💡 - Mbps(비트)와 MBps(바이트)를 혼동하지 않도록 주의하세요
- 클라우드 비용 절감을 위해 CDN을 활용하면 트래픽 비용을 크게 줄일 수 있습니다
6. 처리율(Throughput)과 대역폭(Bandwidth)
김개발 씨가 네트워크 장비 스펙을 보다가 혼란에 빠졌습니다. "대역폭 1Gbps"라고 적혀 있는데, 실제로 테스트해보니 500Mbps밖에 안 나왔습니다.
"불량품인가요?" 박시니어 씨가 고개를 젓습니다. "아뇨, 대역폭과 처리율은 다른 개념이에요."
**대역폭(Bandwidth)**은 네트워크가 이론적으로 전송할 수 있는 최대 데이터량입니다. 반면 **처리율(Throughput)**은 실제로 전송되는 데이터량을 의미합니다.
고속도로에 비유하면, 대역폭은 차선 수이고 처리율은 실제로 통과하는 차량 수입니다. 대역폭이 넓어도 신호등, 사고, 정체 등으로 인해 실제 통과 차량은 줄어들 수 있습니다.
다음 코드를 살펴봅시다.
# 대역폭과 처리율 비교 시뮬레이션
class NetworkConnection:
def __init__(self, bandwidth_mbps):
self.bandwidth = bandwidth_mbps # 이론적 최대 대역폭
self.overhead = 0.1 # 프로토콜 오버헤드 10%
self.congestion = 0.0 # 혼잡도 (0~1)
self.packet_loss = 0.02 # 패킷 손실률 2%
def calculate_throughput(self):
# 실제 처리율 = 대역폭 - 각종 손실 요인
effective = self.bandwidth
effective *= (1 - self.overhead) # 프로토콜 오버헤드 차감
effective *= (1 - self.congestion) # 혼잡도 반영
effective *= (1 - self.packet_loss) # 패킷 손실 반영
return effective
def get_efficiency(self):
throughput = self.calculate_throughput()
return f"대역폭: {self.bandwidth}Mbps, 처리율: {throughput:.1f}Mbps"
# 결과: 대역폭 1000Mbps에서 실제 처리율은 약 860Mbps
김개발 씨는 회사에서 새로 구입한 네트워크 장비를 테스트하고 있었습니다. 스펙에는 분명히 "1Gbps 지원"이라고 적혀 있었습니다.
하지만 실제로 대용량 파일을 전송해보니 500Mbps 정도밖에 나오지 않았습니다. 혹시 불량품일까요?
아닙니다. 이것은 대역폭과 처리율의 차이를 이해하지 못해서 생긴 오해입니다.
대역폭은 고속도로의 차선 수와 같습니다. 8차선 고속도로는 이론적으로 한 번에 8대의 차가 나란히 달릴 수 있습니다.
하지만 실제로 8대가 항상 나란히 달리는 건 아닙니다. 어떤 차는 끼어들기를 하고, 어떤 차는 천천히 가고, 사고가 나면 차선이 막히기도 합니다.
처리율은 실제로 고속도로를 통과하는 차량 수입니다. 8차선 도로라도 정체가 심하면 시간당 통과 차량은 2차선 도로보다 적을 수 있습니다.
네트워크에서도 마찬가지입니다. 대역폭이 1Gbps라고 해서 항상 1Gbps로 데이터가 전송되는 것은 아닙니다.
여러 요인이 실제 처리율을 낮춥니다. 첫째, 프로토콜 오버헤드가 있습니다.
데이터를 보낼 때 캡슐화 과정에서 각종 헤더가 추가됩니다. 이 헤더들도 대역폭을 사용합니다.
순수한 사용자 데이터만 보면 전체 대역폭의 90~95% 정도만 실제로 활용됩니다. 둘째, 네트워크 혼잡이 있습니다.
많은 사용자가 동시에 네트워크를 사용하면 서로 경쟁하면서 각자의 처리율이 낮아집니다. 셋째, 패킷 손실이 있습니다.
중간에 패킷이 유실되면 재전송이 필요합니다. 재전송하는 동안 새로운 데이터를 보내지 못하므로 처리율이 떨어집니다.
넷째, **지연 시간(Latency)**도 영향을 미칩니다. 멀리 있는 서버와 통신할 때는 왕복 시간이 길어져서 처리율이 낮아질 수 있습니다.
위의 코드에서 이런 요인들을 시뮬레이션하고 있습니다. 1000Mbps 대역폭에서 각종 손실 요인을 적용하면 실제 처리율은 860Mbps 정도가 됩니다.
실제 환경에서는 더 많은 요인이 작용하기 때문에 차이가 더 클 수 있습니다. 김개발 씨가 이해했다는 듯이 고개를 끄덕입니다.
"아, 그래서 인터넷 속도 100Mbps를 신청해도 실제로는 그보다 낮게 나오는 거군요."
실전 팁
💡 - 실제 처리율은 대역폭의 70~90% 정도로 예상하는 것이 현실적입니다
- 네트워크 성능 측정 시 여러 번 테스트하여 평균값을 사용하세요
7. 패킷 손실(Packet Loss) 이해
김개발 씨가 화상 회의 중에 갑자기 화면이 끊기고 목소리가 로봇처럼 들렸습니다. "인터넷 연결은 되어 있는데 왜 이러지?" 회의가 끝난 후 박시니어 씨에게 물어봤습니다.
"그건 아마 패킷 손실 때문일 거예요."
**패킷 손실(Packet Loss)**은 네트워크를 통해 전송되는 패킷 중 일부가 목적지에 도달하지 못하고 사라지는 현상입니다. 마치 우편물 중 일부가 배달 도중 분실되는 것과 같습니다.
패킷 손실은 네트워크 혼잡, 하드웨어 장애, 소프트웨어 버그, 무선 신호 간섭 등 다양한 원인으로 발생하며, 서비스 품질에 큰 영향을 미칩니다.
다음 코드를 살펴봅시다.
# 패킷 손실 측정 및 분석
import subprocess
import re
def measure_packet_loss(host, count=10):
"""ping을 사용하여 패킷 손실률 측정"""
try:
# Linux/Mac에서 ping 실행
result = subprocess.run(
["ping", "-c", str(count), host],
capture_output=True, text=True, timeout=30
)
output = result.stdout
# 패킷 손실률 추출 (예: "10% packet loss")
match = re.search(r'(\d+)% packet loss', output)
if match:
loss_rate = int(match.group(1))
return analyze_packet_loss(loss_rate)
except Exception as e:
return f"측정 실패: {e}"
def analyze_packet_loss(loss_rate):
if loss_rate == 0:
return "정상: 패킷 손실 없음"
elif loss_rate < 3:
return f"양호: {loss_rate}% 손실 (일반 사용에 문제 없음)"
elif loss_rate < 10:
return f"주의: {loss_rate}% 손실 (실시간 서비스 품질 저하)"
else:
return f"심각: {loss_rate}% 손실 (즉시 조치 필요)"
김개발 씨는 중요한 화상 회의 중에 당황스러운 경험을 했습니다. 상대방의 말이 중간중간 끊기고, 화면은 모자이크처럼 깨졌습니다.
인터넷 연결은 분명히 되어 있는데 왜 이런 일이 생긴 걸까요? 박시니어 씨가 설명합니다.
"그건 패킷 손실 때문이에요. 데이터가 중간에 사라진 거죠." 패킷 손실은 마치 택배 배송 사고와 같습니다.
10개의 택배를 보냈는데 8개만 도착했다면, 2개는 어딘가에서 분실된 것입니다. 네트워크에서도 보낸 패킷 중 일부가 목적지에 도달하지 못하는 경우가 있습니다.
패킷이 손실되는 원인은 다양합니다. 첫째, 네트워크 혼잡입니다.
너무 많은 데이터가 한꺼번에 몰리면 라우터나 스위치의 버퍼가 가득 찹니다. 더 이상 담을 곳이 없으면 새로 들어오는 패킷을 버릴 수밖에 없습니다.
둘째, 하드웨어 장애입니다. 네트워크 장비가 오래되었거나 결함이 있으면 패킷을 제대로 전달하지 못합니다.
케이블 불량도 패킷 손실의 원인이 됩니다. 셋째, 무선 신호 간섭입니다.
Wi-Fi를 사용할 때 벽, 다른 전자기기, 이웃집 공유기 등이 신호를 방해하면 패킷이 손실될 수 있습니다. 패킷 손실률은 서비스 유형에 따라 허용 범위가 다릅니다.
웹 브라우징이나 파일 다운로드는 패킷 손실에 비교적 관대합니다. TCP 프로토콜이 손실된 패킷을 자동으로 재전송하기 때문입니다.
사용자는 약간 느려지는 것만 느낄 뿐입니다. 하지만 실시간 서비스는 다릅니다.
화상 통화, 음성 통화, 온라인 게임 등은 패킷 손실에 매우 민감합니다. 재전송을 기다릴 시간이 없기 때문입니다.
1~2%의 패킷 손실만으로도 음성이 끊기거나 영상이 깨지는 현상이 나타납니다. 위의 코드는 ping 명령어를 사용해 패킷 손실률을 측정하는 예제입니다.
지정한 호스트로 패킷을 보내고 몇 개가 돌아오는지 확인합니다. 손실률에 따라 네트워크 상태를 진단할 수 있습니다.
김개발 씨가 물었습니다. "패킷 손실을 줄이려면 어떻게 해야 하나요?" 박시니어 씨가 답합니다.
"유선 연결을 사용하고, 네트워크 장비를 점검하고, 대역폭에 여유를 두는 게 기본이에요. 중요한 서비스라면 QoS 설정으로 우선순위를 높이는 방법도 있어요."
실전 팁
💡 - 실시간 서비스는 패킷 손실률 1% 미만을 목표로 해야 합니다
- ping 명령어로 간단하게 패킷 손실을 확인할 수 있습니다
이상으로 학습을 마칩니다. 위 내용을 직접 코드로 작성해보면서 익혀보세요!
댓글 (0)
함께 보면 좋은 카드 뉴스
Helm 마이크로서비스 패키징 완벽 가이드
Kubernetes 환경에서 마이크로서비스를 효율적으로 패키징하고 배포하는 Helm의 핵심 기능을 실무 중심으로 학습합니다. Chart 생성부터 릴리스 관리까지 체계적으로 다룹니다.
보안 아키텍처 구성 완벽 가이드
프로젝트의 보안을 처음부터 설계하는 방법을 배웁니다. AWS 환경에서 VPC부터 WAF, 암호화, 접근 제어까지 실무에서 바로 적용할 수 있는 보안 아키텍처를 단계별로 구성해봅니다.
AWS Organizations 완벽 가이드
여러 AWS 계정을 체계적으로 관리하고 통합 결제와 보안 정책을 적용하는 방법을 실무 스토리로 쉽게 배워봅니다. 초보 개발자도 바로 이해할 수 있는 친절한 설명과 실전 예제를 제공합니다.
AWS KMS 암호화 완벽 가이드
AWS KMS(Key Management Service)를 활용한 클라우드 데이터 암호화 방법을 초급 개발자를 위해 쉽게 설명합니다. CMK 생성부터 S3, EBS 암호화, 봉투 암호화까지 실무에 필요한 모든 내용을 담았습니다.
AWS Secrets Manager 완벽 가이드
AWS에서 데이터베이스 비밀번호, API 키 등 민감한 정보를 안전하게 관리하는 Secrets Manager의 핵심 개념과 실무 활용법을 배워봅니다. 초급 개발자도 쉽게 따라할 수 있도록 실전 예제와 함께 설명합니다.