계층과 응용 계층의 원리 — 처리량, 캡슐화, 소켓, TCP와 UDP
1. 처리량과 병목 링크
앞 글에서 성능 지표 가운데 지연과 손실을 보았습니다. 남은 하나가 처리량(throughput)입니다. 처리량은 송신자에서 수신자로 비트가 실제로 전달되는 속도(bits/sec)입니다. 어느 한 순간의 속도를 순간 처리량(instantaneous throughput), 긴 시간에 걸친 평균 속도를 평균 처리량(average throughput)이라고 합니다.
단위가 전송률과 같은 bps라서 헷갈리기 쉽습니다. 전송률은 링크 하나의 성질입니다. 처리량은 송신자에서 수신자까지 경로 전체를 두고 재는 종단 간(end-to-end) 값입니다.
서버가 Rs 링크로 라우터에 붙고, 라우터가 Rc 링크로 클라이언트에 붙어 있다고 합시다. 굵기가 다른 수도관 두 개를 이어 물을 흘리는 상황과 같습니다. 물은 가는 쪽 관이 허락하는 만큼만 흐릅니다.
평균 종단 간 처리량 = min(Rs, Rc)
경로에서 전송률이 가장 작아 종단 간 처리량을 묶어 두는 링크를 병목 링크(bottleneck link)라고 합니다. 링크가 셋 이상이어도 규칙은 같습니다. 모든 링크를 비교해 가장 작은 값을 고릅니다. 예를 들어 Rs = 50 Mbps, Rc = 20 Mbps라면 처리량은 20 Mbps이고, 100 MB 파일(800 Mb)을 받는 데 약 800 / 20 = 40초가 걸립니다. 처리량은 방향마다 다를 수도 있습니다. 케이블이나 DSL처럼 하향과 상향의 전송률이 다른 접속망에서는 서버에서 클라이언트로 갈 때와 반대로 갈 때의 병목이 달라집니다.
문제 1
서버 20대와 클라이언트 20대가 한 쌍씩 짝을 지어 동시에 파일을 주고받습니다. 각 서버의 접속 링크는 50 Mbps, 각 클라이언트의 접속 링크는 20 Mbps입니다. 모든 연결은 가운데의 300 Mbps 링크 하나를 지나고, 이 링크를 연결들이 고르게 나눠 씁니다. 연결 하나의 종단 간 처리량은 얼마입니까. 쌍이 10개뿐이라면 어떻습니까.
가운데 링크를 20개 연결이 나누므로 한 연결의 몫은 300 / 20 = 15 Mbps입니다. 세 값을 비교하면 min(50, 20, 15) = 15 Mbps이고, 병목은 가운데 공유 링크입니다. 쌍이 10개면 몫이 300 / 10 = 30 Mbps로 늘어 min(50, 20, 30) = 20 Mbps가 되고, 병목은 클라이언트 접속 링크로 옮겨 갑니다. 실제 인터넷의 코어 링크는 매우 굵어서, 대개 접속 링크가 병목입니다.
2. 왜 계층으로 나누나
지금까지 호스트, 라우터, 여러 매체의 링크, 수많은 프로토콜을 보았습니다. 이것들을 한꺼번에 다루기는 어렵습니다. 그래서 네트워크는 기능을 여러 층으로 나눈 계층 구조(layered architecture)로 정리합니다.
비행기 여행도 단계로 나뉩니다. 출발할 때 항공권을 사고, 짐을 부치고, 탑승구를 지나고, 이륙합니다. 도착하면 착륙하고, 탑승구를 나오고, 짐을 찾습니다. 출발 쪽 단계와 도착 쪽 단계가 짝을 이루고, 짝마다 맡은 일이 정해져 있습니다. 수하물 담당은 승객이 어떤 항공권을 샀는지 따지지 않고 짐을 옮기는 일만 합니다. 각 층은 자기 일을 하면서, 자기가 못 하는 일은 아래층의 서비스에 맡깁니다. 탑승구는 승객을 태우고 내리는 일만 하고, 목적지까지 옮기는 일은 비행 단계에 맡깁니다.
- 구조가 드러납니다. 복잡한 시스템을 조각으로 나누고 조각 사이의 관계를 보여 줍니다.
- 모듈화(modularity) — 한 층의 구현을 바꿔도 위아래 층이 받는 서비스만 같으면 나머지는 바꾸지 않아도 됩니다. 탑승 절차를 바꿔도 수하물 처리는 그대로입니다.
- 대가 — 층마다 자기 정보를 덧붙이고 처리하므로 오버헤드가 늘어납니다.
3. 인터넷 5계층과 OSI 7계층
인터넷의 프로토콜은 다섯 계층으로 나뉘고, 각 프로토콜은 그중 한 층에 속합니다.
| 계층 | 하는 일 | 프로토콜 예 |
|---|---|---|
| 응용 (application) | 네트워크 응용 프로그램이 주고받는 메시지를 정한다 | HTTP, SMTP, DNS |
| 전송 (transport) | 한 호스트의 프로세스에서 다른 호스트의 프로세스로 데이터를 나른다 | TCP, UDP |
| 네트워크 (network) | 출발지 호스트에서 목적지 호스트까지 경로를 따라 데이터그램을 나른다 | IP, 라우팅 프로토콜 |
| 링크 (link) | 이웃한 두 장치 사이, 링크 하나를 건너 데이터를 나른다 | 이더넷, Wi-Fi |
| 물리 (physical) | 비트를 선이나 전파 위의 신호로 바꿔 보낸다 | 매체마다 다르다 |
이 연재는 위에서 아래로(top-down) 내려갑니다. 응용 계층부터 시작해 한 층씩 내려갑니다.
ISO가 만든 OSI 참조 모델은 7계층입니다. 인터넷이 지금처럼 퍼지기 전에 만들어져서 인터넷 스택과 딱 맞지는 않습니다. 응용 계층 아래에 두 층이 더 있습니다. 표현 계층(presentation)은 데이터의 뜻을 해석하게 해 주는 암호화, 압축, 기계마다 다른 표현 방식의 변환을 맡고, 세션 계층(session)은 데이터 교환의 동기화, 중간 저장점, 복구를 맡습니다. 인터넷 스택은 이 두 층을 따로 두지 않습니다. 이 기능이 필요한 응용은 응용 계층 안에서 직접 구현합니다.
4. 캡슐화
메시지가 층을 내려갈 때마다 그 층이 쓸 제어 정보가 앞에 붙습니다. 이 정보를 헤더(header)라고 하고, 위층에서 받은 데이터에 헤더를 붙여 자기 층의 데이터 단위로 만드는 과정을 캡슐화(encapsulation)라고 합니다. 받는 쪽에서는 층을 올라가며 헤더를 하나씩 읽고 떼어 냅니다. 이 반대 과정이 역캡슐화(decapsulation)입니다. 상자를 더 큰 상자에 넣고, 그것을 다시 더 큰 상자에 넣는 포장과 같습니다.
| 계층 | 데이터 단위 이름 | 모양 |
|---|---|---|
| 응용 | 메시지 (message) | M |
| 전송 | 세그먼트 (segment) | Ht + M |
| 네트워크 | 데이터그램 (datagram) | Hn + Ht + M |
| 링크 | 프레임 (frame) | Hl + Hn + Ht + M |
전송 계층 헤더에는 받는 쪽에서 메시지를 어느 프로세스에 줄지와 오류 검사에 쓸 정보가 들어갑니다. 네트워크 계층 헤더에는 출발지와 목적지 호스트의 주소가 들어가고, 링크 계층 헤더에는 링크 하나를 건널 때 필요한 정보가 들어갑니다. 이름 네 개의 순서, 메시지 → 세그먼트 → 데이터그램 → 프레임은 영어 이름 그대로 기억해 둡니다.
중간 장비는 다섯 층을 모두 갖지 않습니다. 라우터는 네트워크, 링크, 물리 세 층만 있습니다. 프레임을 받으면 링크 헤더를 떼고, 네트워크 헤더의 목적지 IP 주소를 보고 나갈 링크를 정한 뒤, 새 링크 헤더를 붙여 내보냅니다. 응용 프로그램을 실행하지 않으므로 전송 헤더나 메시지를 볼 필요가 없습니다. 스위치는 링크와 물리 두 층만 있어서 링크 헤더까지만 봅니다. 헤더를 읽고 떼는 일은 앞 글의 네 지연 가운데 처리 지연에 들어갑니다.
문제 2
응용이 1,000바이트 메시지를 보냅니다. 전송 계층 헤더가 20바이트, 네트워크 계층 헤더가 20바이트, 링크 계층이 붙이는 정보가 18바이트입니다. 100 Mbps 링크로 이 프레임을 내보내는 전송 지연은 얼마이고, 프레임에서 헤더가 차지하는 비율은 얼마입니까.
링크로 나가는 것은 헤더를 모두 붙인 프레임이므로 L에 헤더를 포함합니다. L = 1,000 + 20 + 20 + 18 = 1,058바이트 = 8,464비트입니다. 전송 지연은 8,464 / 108 ≈ 84.6 μs입니다. 헤더는 58 / 1,058 ≈ 5.5%입니다. 메시지가 100바이트로 작아지면 헤더 비율은 58 / 158 ≈ 37%로 커집니다. 작은 메시지를 많이 보낼수록 헤더에 쓰는 몫이 커집니다.
5. 네트워크 보안의 기본 용어
인터넷은 처음에 서로 믿는 사용자들이 한 망에 붙어 있는 상황을 가정하고 설계되어 보안을 크게 고려하지 않았습니다. 그래서 보안은 나중에 모든 계층에 덧붙여 가고 있습니다. 대표적인 공격은 이렇습니다.
| 공격 | 방법 |
|---|---|
| 악성 코드 (malware) | 호스트를 감염시켜 정보를 빼내거나 다른 공격에 동원한다. 스스로 퍼지는 웜(worm), 다른 프로그램에 붙어 퍼지는 바이러스(virus)가 있다 |
| 서비스 거부 (DoS) | 가짜 트래픽을 퍼부어 서버나 링크를 정상 사용자가 쓸 수 없게 만든다. 감염된 호스트 여러 대를 동원하면 DDoS라고 한다 |
| 패킷 스니핑 (packet sniffing) | 공유 매체에서 지나가는 패킷을 모두 엿듣는다. 비밀번호가 그대로 보일 수 있다 |
| IP 스푸핑 (IP spoofing) | 출발지 주소를 남의 주소로 속인 패킷을 보낸다 |
방어 수단으로는 상대가 누구인지 확인하는 인증(authentication), 내용을 암호화해 엿보지 못하게 하는 기밀성(confidentiality), 내용이 바뀌지 않았는지 확인하는 무결성 검사(integrity check), 허가된 사용자만 들어오게 하는 접근 제한, 들어오고 나가는 트래픽을 규칙에 따라 거르는 방화벽(firewall)이 있습니다. 앞에서 공유 매체를 여러 번 강조한 이유가 여기서도 드러납니다. 매체를 나눠 쓰면 옆 사용자가 내 패킷을 엿들을 수 있습니다.
6. 응용 계층 — 엣지에서만 프로그램을 짭니다
여기서부터 응용 계층입니다. 웹, 메신저, 이메일, 게임, 영상 스트리밍, 화상회의처럼 우리가 쓰는 서비스가 모두 네트워크 응용입니다. 네트워크 응용은 서로 다른 종단 시스템에서 실행되며 망을 통해 대화하는 프로그램입니다. 웹 서버 소프트웨어와 브라우저가 그 예입니다.
응용을 만들 때 네트워크 코어의 라우터용 프로그램은 짤 필요가 없습니다. 코어 장비는 사용자 응용을 실행하지 않습니다. 응용이 종단 시스템에만 있으니 새 응용을 빠르게 만들고 퍼뜨릴 수 있습니다.
응용을 짜는 구조는 두 가지입니다.
| 클라이언트-서버 (client-server) | P2P (peer-to-peer) | |
|---|---|---|
| 항상 켜진 서버 | 있다. 고정 IP 주소를 가지고, 흔히 데이터센터에서 규모를 키운다 | 없다 |
| 누가 누구와 대화하나 | 클라이언트는 서버와 대화한다. 클라이언트끼리 직접 대화하지 않는다 | 임의의 종단 시스템끼리 직접 대화한다 |
| 연결 | 클라이언트는 가끔 연결되고 IP 주소가 바뀔 수 있다 | 피어는 가끔 연결되고 IP 주소가 바뀔 수 있어 관리가 복잡하다 |
| 예 | 웹(HTTP), 메일 가져오기(IMAP) | P2P 파일 공유 |
서버의 주소가 고정되어야 하는 이유는 클라이언트가 그 주소로 찾아와야 하기 때문입니다. P2P의 장점은 자가 확장성(self scalability)입니다. 피어 하나하나가 다른 피어에게 서비스를 요청하는 동시에 다른 피어에게 서비스를 줍니다. 그래서 새 피어가 들어오면 수요와 함께 서비스 용량도 늘어납니다.
7. 프로세스, 소켓, 주소
네트워크에서 실제로 대화하는 주체는 프로세스(process)입니다. 프로세스는 호스트 안에서 실행 중인 프로그램입니다. 노트북 하나에서 브라우저, 메신저, 음악 앱이 동시에 돌고 있으면 프로세스가 여럿입니다. 같은 호스트 안의 두 프로세스는 운영체제가 주는 프로세스 간 통신(inter-process communication)으로 대화하고, 다른 호스트의 두 프로세스는 네트워크로 메시지를 주고받습니다.
대화를 먼저 시작하는 쪽이 클라이언트 프로세스, 연락을 기다리는 쪽이 서버 프로세스입니다. 이 구분은 대화 한 번을 기준으로 합니다. P2P에서는 같은 호스트가 파일을 받을 때는 클라이언트 프로세스, 파일을 내줄 때는 서버 프로세스가 됩니다.
소켓
프로세스는 소켓(socket)으로 메시지를 보내고 받습니다. 소켓은 집의 현관문과 비슷합니다. 보내는 프로세스는 메시지를 문 밖으로 내놓고, 문 밖의 전송 설비가 그 메시지를 받는 쪽 프로세스의 문 앞까지 가져다준다고 믿고 맡깁니다. 대화 한 번에 소켓은 양쪽에 하나씩 있습니다. 응용 개발자가 직접 다루는 부분은 소켓 위쪽, 응용 계층까지입니다. 소켓 아래의 전송 계층부터는 운영체제가 맡아서 헤더를 붙이고 내보냅니다.
IP 주소와 포트 번호
메시지를 받으려면 받는 프로세스를 가리킬 식별자가 필요합니다. 호스트는 32비트 IP 주소로 구분합니다. 0부터 255까지의 수 넷을 점으로 이어 쓰고, 수 하나가 8비트이므로 4 × 8 = 32비트입니다. 하지만 한 호스트에서 여러 프로세스가 돌고 있으니 IP 주소만으로는 어느 프로세스인지 알 수 없습니다. 그래서 포트 번호(port number)를 함께 씁니다. 웹 서버는 80번, 메일 서버는 25번을 씁니다. 웹 서버에 접속하는 클라이언트들은 모두 서버의 80번 포트로 가고, 서버는 클라이언트 쪽의 IP 주소와 포트 번호 쌍으로 손님을 서로 구분합니다.
응용 계층 프로토콜이 정하는 것
- 메시지 종류 — 요청과 응답처럼 어떤 메시지가 오가는가.
- 문법(syntax) — 메시지에 어떤 필드가 있고 어떻게 구분하는가.
- 의미(semantics) — 각 필드의 정보가 무슨 뜻인가.
- 규칙 — 언제, 어떻게 메시지를 보내고 응답하는가.
HTTP나 SMTP처럼 RFC로 공개된 프로토콜은 누구나 구현할 수 있어서 서로 다른 회사의 브라우저와 서버가 대화할 수 있습니다. 한 회사가 내부 규칙을 공개하지 않는 사유(proprietary) 프로토콜도 있습니다.
8. 응용이 전송 계층에 바라는 것, 그리고 TCP와 UDP
응용 계층은 메시지를 소켓에 넣을 뿐, 나르는 일은 아래층에 맡깁니다. 응용이 전송 서비스에 바랄 만한 성질은 넷입니다.
| 성질 | 뜻 | 꼭 필요한 응용 |
|---|---|---|
| 데이터 무결성 (data integrity) | 보낸 데이터가 빠짐없이, 틀림없이 도착한다 | 파일 전송, 웹, 이메일 |
| 타이밍 (timing) | 지연이 일정 한도 안에 든다 | 인터넷 전화, 온라인 게임 |
| 처리량 (throughput) | 최소한의 처리량이 보장된다 | 영상 스트리밍처럼 일정 속도가 있어야 하는 멀티미디어 |
| 보안 (security) | 암호화, 무결성 확인 | 금융, 로그인 |
파일과 웹 문서는 한 비트도 틀리면 안 되지만 몇 초 늦는 것은 견딥니다. 실시간 음성과 영상은 약간의 손실은 견디지만 지연에 민감합니다. 인터넷의 전송 계층은 이 바람에 맞춰 두 프로토콜을 줍니다.
| TCP | UDP | |
|---|---|---|
| 신뢰적 전송 | 준다. 잃은 데이터를 다시 보내 순서대로 전달한다 | 주지 않는다 |
| 흐름 제어 (flow control) | 준다. 받는 쪽이 감당할 만큼만 보낸다 | 주지 않는다 |
| 혼잡 제어 (congestion control) | 준다. 망이 붐비면 보내는 속도를 줄인다 | 주지 않는다 |
| 연결 설정 | 데이터를 보내기 전에 두 프로세스 사이에 연결을 맺는다 (connection-oriented) | 없다. 바로 보낸다 |
| 타이밍, 최소 처리량, 보안 | 주지 않는다 | 주지 않는다 |
UDP는 아무것도 주지 않는 것처럼 보입니다. 그래도 쓰는 이유는 연결을 맺느라 기다리지 않고, 혼잡 제어 때문에 속도가 깎이지 않기 때문입니다. 인터넷 전화나 게임처럼 늦게 온 데이터가 쓸모없는 응용은 UDP를 쓰기도 합니다. 웹, 이메일, 파일 전송은 무결성이 꼭 필요하므로 TCP를 씁니다.
두 프로토콜 모두 암호화를 하지 않습니다. 그래서 보안이 필요한 응용은 응용 계층에서 직접 해결합니다. TCP 연결 위에 암호화와 인증을 더하는 TLS(Transport Layer Security)를 응용이 가져다 쓰는 방식이고, HTTPS가 HTTP를 TLS 위에서 돌린 것입니다.
9. 웹과 HTTP의 기본
응용 계층 프로토콜 가운데 웹의 HTTP(HyperText Transfer Protocol)부터 봅니다. 하이퍼텍스트는 다른 문서나 파일로 가는 링크를 담은 텍스트입니다.
웹 페이지는 여러 객체(object)로 이루어집니다. 객체는 HTML 파일, JPEG 이미지, 자바스크립트 파일, 오디오 파일 같은 파일 하나하나입니다. 페이지는 기본 HTML 파일 하나와, 그 파일이 참조하는 여러 객체로 구성됩니다. 객체마다 URL로 위치를 가리키고, 서로 다른 서버에 있어도 됩니다. URL은 호스트 이름과 경로 이름으로 나뉩니다. www.example.com/notes/cat.png에서 www.example.com이 호스트 이름, /notes/cat.png가 경로 이름입니다.
HTTP는 클라이언트-서버 구조이고 메시지는 요청(request)과 응답(response) 두 종류뿐입니다. 클라이언트는 객체를 요청하고 받아서 화면에 보여 주는 브라우저입니다. 서버는 요청을 받아 객체를 돌려주는 웹 서버로, 늘 켜져 있고 고정된 IP 주소를 가집니다.
- 클라이언트가 서버의 80번 포트로 TCP 연결을 엽니다.
- 서버가 연결을 받아들입니다.
- 브라우저와 웹 서버가 HTTP 메시지를 주고받습니다.
- TCP 연결을 닫습니다.
웹 문서는 한 글자도 깨지면 안 되므로 HTTP는 TCP를 쓰고, 그래서 메시지를 보내기 전에 연결부터 맺습니다.
HTTP는 무상태(stateless) 프로토콜입니다. 서버는 클라이언트가 전에 무엇을 요청했는지 기억하지 않습니다. 상태를 기억하는 프로토콜은 복잡합니다. 지난 기록을 계속 들고 있어야 하고, 서버나 클라이언트가 중간에 죽으면 양쪽이 기억하는 상태가 서로 어긋나 맞춰 줘야 합니다. 쇼핑몰의 장바구니처럼 사용자를 기억해야 하는 기능은 HTTP 바깥의 쿠키로 만듭니다. 다음 글에서 HTTP 연결 방식과 메시지 형식, 쿠키와 웹 캐시를 차례로 봅니다.
정리
종단 간 처리량은 경로에서 가장 좁은 병목 링크가 정합니다. 네트워크는 응용, 전송, 네트워크, 링크, 물리 다섯 계층으로 나뉘고, 메시지는 층을 내려가며 헤더를 하나씩 붙여 세그먼트, 데이터그램, 프레임이 됩니다. 라우터는 네트워크 계층까지, 스위치는 링크 계층까지만 처리합니다. 응용은 엣지에서만 실행되며 클라이언트-서버 또는 P2P 구조를 따르고, 프로세스는 소켓으로 메시지를 주고받으며 IP 주소와 포트 번호로 서로를 찾습니다. 전송 계층의 TCP는 신뢰적 전송, 흐름 제어, 혼잡 제어를 주고 UDP는 연결 설정 없이 바로 보냅니다. 웹의 HTTP는 TCP 위에서 도는 무상태 프로토콜입니다.