포트와 소켓 - 연결을 식별하는 방법
지난 글에서 TCP는 IP 위에서 동작하며, 연결이라는 상태를 맺고 유지한다고 했습니다. 그런데 IP 주소 하나로 컴퓨터 한 대는 찾아갈 수 있어도, 그 컴퓨터 안에서 어떤 프로그램에게 데이터를 전달해야 하는지는 아직 정해지지 않았습니다. 이번 글은 그 문제를 다룹니다.
IP 주소만으로는 왜 부족한가
서버 한 대(IP: 203.0.113.10)에서 웹 서버, SSH, 메일 서버가 동시에 돌아가고 있다고 해봅시다. 인터넷에서 이 서버로 패킷이 하나 도착했습니다. IP 주소만 보면 “이 서버로 가는 패킷”이라는 것까지만 알 수 있고, 셋 중 누구에게 전달해야 하는지는 알 수 없습니다.
포트(port)는 이 문제를 푸는 16비트 숫자(0~65535)입니다. 패킷은 목적지 IP뿐 아니라 목적지 포트도 함께 가지고 다니고, 호스트는 그 포트 번호를 보고 어느 프로그램에게 넘길지 결정합니다.
포트 번호의 범위
포트 번호는 관행적으로 세 구간으로 나뉩니다.
| 구간 | 범위 | 용도 |
|---|---|---|
| Well-known | 0 ~ 1023 | HTTP(80), HTTPS(443), SSH(22)처럼 널리 합의된 서비스용. 대부분 OS에서 관리자 권한이 있어야 열 수 있음 |
| Registered | 1024 ~ 49151 | 특정 애플리케이션이 IANA에 등록해서 쓰는 포트 |
| Dynamic/Private | 49152 ~ 65535 | 클라이언트가 연결을 맺을 때 임시로 쓰는 포트. “임시 포트(ephemeral port)”라고도 부름 |
여기서 중요한 포인트: 웹 브라우저가 서버의 :80에 접속할 때, 브라우저 쪽도 포트가 필요합니다. 이때 브라우저는 보통 dynamic 구간에서 아무 포트나 하나 골라 씁니다. 그래서 서버 쪽은 항상 :80처럼 고정돼 있지만, 클라이언트 쪽 포트는 접속할 때마다 다릅니다. 이게 다음 이야기로 이어집니다.
포트만으로도 사실 부족하다 — 소켓과 5-tuple
여기서 자연스러운 의문이 생깁니다. 서버의 :80번 포트로 클라이언트 수천 명이 동시에 접속하면, 그 수천 개의 연결은 어떻게 서로 구분될까요? 다들 같은 포트로 들어오는데 말입니다.
답은 “포트 하나만으로 연결을 식별하지 않는다”입니다. TCP는 다음 다섯 가지 값의 조합, 5-tuple로 각 연결을 구분합니다.
(프로토콜, 로컬 IP, 로컬 포트, 원격 IP, 원격 포트)
서버 입장에서 로컬 IP·로컬 포트(203.0.113.10:80)는 클라이언트가 몇 명이 붙든 항상 같습니다. 하지만 원격 IP·원격 포트(클라이언트 쪽)는 클라이언트마다 다릅니다. 그래서 5개 값을 통째로 보면 클라이언트 수만큼 서로 다른 조합이 나오고, 서버는 이 조합으로 각 연결을 구분합니다.
정리하면 이렇습니다.
- 포트는 “같은 호스트 안 어느 프로그램인가”를 구분한다.
- 소켓은 (프로토콜, IP, 포트) 조합으로, 한쪽 endpoint를 가리킨다.
- 5-tuple(연결)은 로컬 소켓과 원격 소켓을 합친 것으로, TCP 연결 하나를 유일하게 식별한다.
“포트가 겹치면 안 되는 거 아닌가?”라는 흔한 오해는 여기서 풀립니다. 겹치면 안 되는 건 포트 번호가 아니라 5-tuple 전체입니다. 서버 쪽 포트(:80)는 모든 연결에서 똑같아도 되고, 실제로 항상 똑같습니다.
확인해보기
리눅스/macOS에서 ss -tn(또는 netstat -tn)을 실행하면 실제 5-tuple을 눈으로 볼 수 있습니다.
$ ss -tn
State Local Address:Port Peer Address:Port
ESTAB 192.168.0.5:22 203.0.113.50:51000
ESTAB 192.168.0.5:22 198.51.100.7:52000
Local Address:Port는 두 줄 다 같은데(SSH 데몬이 :22에서 듣고 있으니까), Peer Address:Port는 서로 다릅니다. 두 연결은 로컬 포트가 같아도 완전히 독립된, 서로 다른 TCP 연결입니다.
다음 글
이제 연결을 “식별하는 법”은 알았습니다. 다음 글에서는 이 5-tuple로 식별되는 연결이 실제로 어떻게 맺어지는지 — 3-way handshake를 다룹니다.