한양과학기술고등학교

에듀테크 프로젝트 대시보드

포트 번호와 소켓

포트 번호와 소켓

IP 주소는 이 컴퓨터까지만 데이터를 데려다준다. 그런데 컴퓨터 안에는 브라우저도, 게임도, 메신저도 동시에 켜져 있다. 도착한 데이터를 어느 프로그램에게 줄지는 누가, 어떻게 정할까?

1. 문제 상황 — IP만으로는 부족하다

내 컴퓨터의 IP 주소가 192.168.0.12라고 하자. 지금 이 컴퓨터에서는 동시에 여러 프로그램이 인터넷과 통신 중이다.

  • 브라우저로 offset0xf.com을 보는 중
  • 온라인 게임 서버와 연결돼 있는 중
  • 메신저 앱이 새 메시지를 기다리는 중

이때 192.168.0.12로 데이터 패킷 하나가 도착했다. IP 헤더에는 "목적지 IP = 192.168.0.12" 라고만 적혀 있을 뿐, 어느 프로그램에게 전달해야 하는지는 전혀 적혀 있지 않다. IP는 딱 여기, 호스트(컴퓨터)까지만 책임지는 주소 체계이기 때문이다.

이 문제를 해결하는 것이 바로 전송 계층(4계층)의 포트 번호다.

2. 포트 번호란 — 아파트 동/호수 비유

포트 번호는 0 ~ 65535 범위의 숫자로, 한 컴퓨터 안에서 어느 프로그램(서비스)이 이 데이터를 받을지 구분하는 이름표다. 흔히 이렇게 비유한다.

IP 주소 아파트 동 번호 — 어느 건물인지
포트 번호 아파트 호 번호 — 건물 안 어느 집인지
101
102
103
104
택배가 "OO아파트 101동"까지만 적혀 있으면 경비실에서 멈춘다. 몇 호인지까지 있어야 정확한 집에 배달된다. 네트워크에서 IP는 "101동"까지, 포트 번호는 "그 안의 몇 호"까지 알려주는 셈이다. 실제로는 IP(동)를 찾아가는 3계층(라우팅)과 포트(호수)로 나누는 4계층이 함께 일해서 패킷을 정확한 프로그램에 배달한다.

3. 잘 알려진 포트 (Well-known Ports)

클라이언트가 서버에 접속하려면 "어느 포트로 가야 하는지" 미리 약속돼 있어야 한다. 그래서 자주 쓰이는 서비스들은 전 세계가 합의한 고정 번호를 쓴다. 브라우저 주소창에 포트를 안 적어도 https://면 자동으로 443번으로 가는 이유가 바로 이것이다.

포트프로토콜/서비스용도
20/21FTP파일 전송 (데이터/제어)
22SSH원격 서버 접속·터미널
25SMTP이메일 발송
53DNS도메인 이름 → IP 주소 조회
80HTTP일반 웹사이트 접속
443HTTPS암호화된 웹사이트 접속
0 ~ 1023 — Well-known Ports 표준 서비스용으로 예약. 서버가 이 번호로 "귀 기울이고(listen)" 있는다.
1024 ~ 49151 — 등록된 포트 특정 애플리케이션이 등록해 쓰는 번호대(예: 게임 서버 커스텀 포트).
49152 ~ 65535 — 동적/임시 포트 클라이언트가 접속할 때 OS가 그때그때 임의로 골라 쓰는 번호. 접속 끝나면 반납.

브라우저가 웹서버 443번 포트에 접속할 때, 내 컴퓨터 쪽에서도 포트가 하나 필요하다. 이때 OS가 동적 포트 범위에서 예를 들어 51422 같은 번호를 즉석에서 빌려준다. 서버는 항상 443번에서 기다리고 있지만, 클라이언트 쪽 포트는 접속할 때마다 달라진다.

4. 소켓(Socket) — IP + 포트 = 유일한 통신 종점

소켓은 "IP 주소 + 포트 번호"의 조합이다. 예를 들어 203.0.113.5:443은 이 지구상에 하나뿐인 통신 접점을 가리킨다. 그런데 실제 TCP 연결 하나를 완전히 식별하려면 소켓 하나가 아니라 4개의 값(4-tuple)이 모두 필요하다.

4-tuple = (내 IP, 내 포트, 상대 IP, 상대 포트)

이 네 가지 조합이 딱 하나라도 다르면 완전히 다른 연결로 취급된다. 그래서 서버의 443번 포트 하나에 수천 명이 동시에 접속해도, 서버는 각 연결을 정확히 구별해서 응답을 섞이지 않게 보낼 수 있다 — 클라이언트마다 IP가 다르거나, 같은 IP라도 포트가 다르기 때문이다.

5. 직접 해보기 — 소켓 4-tuple 시뮬레이터

서버는 203.0.113.5:80 한 곳에서만 기다리고 있다. "클라이언트 연결" 버튼을 누를 때마다 새 클라이언트가 임의의 IP와 임의의 임시 포트로 접속을 시도한다. 목적지(서버 쪽)는 전부 80번으로 똑같은데, 서버가 대체 어떻게 이들을 구별하는지 표를 통해 확인해보자.

서버 (고정)
203.0.113.5 : 80
계속 80번 포트에서 accept() 대기 중
현재 연결 수: 0
접속한 클라이언트들
아직 연결된 클라이언트가 없습니다.
"클라이언트 연결"을 눌러 첫 접속을 만들어보세요.
# 서버 쪽 (고정) 클라이언트 쪽 (매번 다름)
목적지 IP목적지 포트출발지 IP출발지 포트

6. 코드로 보면 — 서버 소켓 열기

파이썬 socket 모듈로 서버가 특정 포트를 bind하고 연결을 listen하는 가장 기본적인 형태다. accept()가 호출될 때마다 새 클라이언트용 소켓이 하나씩 만들어지는데, 이 소켓들이 바로 각기 다른 4-tuple로 구별된다.

# 서버: 0.0.0.0(모든 인터페이스)의 8080번 포트에서 대기
import socket

srv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
srv.bind(("0.0.0.0", 8080))    # 이 컴퓨터의 8080번 포트를 "내 것"으로 등록
srv.listen()                    # 이제부터 8080번으로 오는 연결 요청을 받기 시작

# 클라이언트가 접속할 때마다 새 소켓(conn)과 (IP, 포트)가 반환됨
conn, addr = srv.accept()       # addr = ('203.0.113.9', 51422) 같은 클라이언트 4-tuple 일부

관련 페이지

한 줄 정리: IP는 컴퓨터를, 포트는 그 안의 프로그램을 찾는다. 이 둘을 합친 "IP:포트"가 소켓이고, 실제 연결은 (내IP, 내포트, 상대IP, 상대포트) 4가지 값 전체로 완전히 구별된다 — 그래서 서버의 포트 하나로 수많은 클라이언트를 동시에 상대할 수 있다.