업데이트됨 1개월 전
전송 계층은 인터넷이 개인적으로 변하는 곳입니다.
하위 계층들은 여러분이 무엇을 말하는지, 누구에게 말하는지 신경 쓰지 않습니다. 네트워크 계층은 그저 패킷을 A에서 B로 옮길 뿐입니다. 데이터 링크 계층은 그저 프레임을 하나의 회선을 통해 전달할 뿐입니다. 하지만 전송 계층은요? 실제로 중요한 질문들을 던집니다. 어떤 애플리케이션이 이것을 보냈는가? 어떤 애플리케이션이 이것을 받아야 하는가? 메시지가 온전히 도착했는가? 도착은 했는가?
이 계층은 IP 주소만으로는 부족해지는 곳입니다. 서버 하나에 수십 개의 애플리케이션이 실행될 수 있습니다—웹 서버, 이메일, 데이터베이스, SSH. 이것들은 모두 하나의 IP 주소를 공유합니다. 전송 계층은 포트 번호를 추가하여 하나의 주소를 수천 개의 고유한 엔드포인트로 만듭니다. 누군가의 건물 주소를 아는 것과 그 사람의 호수를 아는 것의 차이입니다.
포트: 인터넷의 호수
IP 주소는 여러분을 특정 컴퓨터까지 데려다 줍니다. 포트는 여러분을 특정 애플리케이션까지 데려다 줍니다.
브라우저가 웹사이트에 연결할 때, 구체적인 일이 일어납니다. 여러분의 컴퓨터는 임의의 높은 포트(예: 52143)를 반송 주소로 선택하고, 서버의 443번 포트로 메시지를 보냅니다. IP 주소와 포트의 조합이 소켓을 만듭니다. 두 소켓이 합쳐져 연결이 됩니다.
내선번호가 있는 전화 통화라고 생각해 보세요. 여러분의 전화번호가 IP 주소입니다. 내선번호가 포트입니다. 누군가에게 전화를 걸 때, 두 전화번호와 두 내선번호가 함께 그 특정 대화를 식별합니다. 이것이 하나의 웹 서버가 1만 명의 동시 사용자를 처리하는 방법입니다—각 연결은 고유한 소켓 쌍을 가집니다.
포트 번호 범위가 존재하는 데는 이유가 있습니다:
0-1023 (잘 알려진 포트): 표준 서비스를 위해 예약되어 있습니다. URL을 입력하면 브라우저는 HTTPS에 443번 포트를, HTTP에 80번 포트를 사용할 줄 압니다. SSH는 22번에 있습니다. 이메일은 25번과 587번에 있습니다. DNS는 53번에 있습니다. 이것들이 인터넷의 잘 알려진 주소들입니다—모두가 동의하는 번호들입니다.
1024-49151 (등록된 포트): 애플리케이션들이 충돌을 피하기 위해 이 포트들을 등록합니다. MySQL은 3306번을 씁니다. PostgreSQL은 5432번을 씁니다. 원격 데스크톱은 3389번을 씁니다.
49152-65535 (동적 포트): 컴퓨터가 외부 연결을 위해 즉석에서 가져다 씁니다. 모든 브라우저 탭, 네트워크 요청을 하는 모든 앱—각각 이 범위에서 임시 포트를 할당받습니다.
두 가지 철학: TCP와 UDP
전송 계층은 데이터를 전송하는 두 가지 근본적으로 다른 방식을 제공합니다. 여러분의 선택이 애플리케이션의 동작 방식을 모든 면에서 결정합니다.
TCP: 의심 많은 프로토콜
TCP는 최악을 가정합니다. 패킷이 손실될 것이라고 가정합니다. 순서가 뒤바뀌어 도착할 것이라고 가정합니다. 데이터가 손상될 것이라고 가정합니다. 수신자가 처리 용량을 초과할 수 있다고 가정합니다.
그래서 TCP는 완전한 확인 응답 체계를 구축합니다.
무언가를 보내기 전에, TCP는 연결을 먼저 설정합니다. 이것이 3방향 핸드셰이크입니다:
- 여러분의 컴퓨터가 SYN을 보냅니다: "대화하고 싶습니다. 제 시작 순서 번호는 X입니다."
- 서버가 SYN-ACK으로 응답합니다: "당신의 X를 확인했습니다. 제 시작 순서 번호는 Y입니다."
- 여러분의 컴퓨터가 ACK을 보냅니다: "당신의 Y를 확인했습니다. 시작합시다."
이 과정을 거쳐야만 데이터가 흐를 수 있습니다. 시간이 걸립니다—실제 데이터의 단 1바이트도 이동하기 전에 완전한 왕복이 한 번 필요합니다. 하지만 이제 양측 모두 상대방이 듣고 있다는 것을 알게 됩니다.
전송 중에 TCP는 모든 것에 번호를 매깁니다. 모든 바이트는 순서 번호를 가집니다. 수신된 모든 세그먼트는 확인 응답을 받습니다. 타임아웃 내에 응답을 받지 못하면, 최악을 가정하고 재전송합니다. 세그먼트가 순서 없이 도착하면, 수신자는 순서 번호를 사용하여 올바르게 재조립합니다. 중복이 도착하면 버립니다.
이것이 신뢰할 수 있는 전달입니다: 연결이 유지되는 한 데이터가 정확히 한 번, 정확히 올바른 순서로 도착한다는 보장입니다.
TCP는 또한 처리 용량을 감시합니다. 수신자는 얼마나 많은 버퍼 공간이 있는지(윈도우 크기)를 알려줍니다. 송신자는 이 한도를 지킵니다—수신자가 처리할 수 있는 것보다 빠르게 데이터를 보내는 것은 의미가 없습니다. 그리고 TCP는 네트워크 자체도 감시합니다. 혼잡(패킷 손실, 지연 증가)을 감지하면 속도를 줄입니다. 천천히 시작하고, 점차 속도를 높이고, 상황이 혼잡해지면 물러납니다. TCP는 네트워크의 모범 시민입니다.
종료도 시작만큼 격식을 갖춥니다. 어느 쪽이든 FIN(종료)을 보낼 수 있습니다. 상대방이 확인하고, 자체 FIN을 보냅니다. 최종 확인. 연결 종료. 작별 인사에 4개의 메시지가 필요합니다.
UDP: 낙관적인 프로토콜
UDP는 최선을 가정합니다. 패킷은 아마도 도착할 것이라고 가정합니다. 도착하지 않으면 여러분이 알아서 처리하라고 가정합니다.
UDP에는 핸드셰이크가 없습니다. 연결도 없습니다. 확인 응답도 없습니다. 재전송도 없습니다. 흐름 제어도 없습니다. 혼잡 제어도 없습니다. 데이터그램을 만들고, 네트워크에 던지고, 도착하기를 바랍니다.
UDP 헤더는 8바이트입니다. TCP는 최소 20바이트입니다. 초당 수천 개의 패킷을 보낼 때 이 차이가 중요합니다.
왜 UDP를 사용할까요? 때로는 신뢰성이 그 비용을 치를 가치가 없기 때문입니다.
화상 통화: 영상 프레임이 담긴 패킷이 늦게 도착하면 쓸모가 없습니다—그 순간은 이미 지나갔습니다. 재전송을 기다리며 모든 것을 멈추는 것보다 그 패킷을 버리고 다음 프레임을 보여주는 것이 낫습니다.
온라인 게임: 서버가 1초에 60번 여러분의 위치를 전송합니다. 47번째 패킷이 손실되면, 48번째 패킷이 이미 더 새로운 정보를 담아 오고 있습니다. 47번을 재전송하는 것은 대역폭 낭비일 뿐입니다.
DNS 조회: 질문을 보내고 답을 기다립니다. 답이 오지 않으면 다시 물어보면 됩니다. 애플리케이션이 재시도 로직을 처리합니다—TCP의 복잡성이 필요하지 않습니다.
라이브 스트리밍: 시청자들은 몇 개의 프레임이 빠지는 것은 참을 수 있습니다. TCP가 재전송하는 동안 계속 버퍼링하는 것은 참을 수 없습니다.
UDP는 또한 멀티캐스트와 브로드캐스트를 지원합니다—하나의 패킷을 여러 수신자에게 전송하는 것입니다. TCP는 이것을 할 수 없습니다. TCP는 엄격하게 일대일 방식입니다.
둘 중 하나를 선택하기
선택은 대개 미묘하지 않습니다:
다음 경우에 TCP를 사용하세요:
- 모든 바이트가 중요할 때 (파일 전송, 이메일, 웹 페이지)
- 순서가 중요할 때 (데이터베이스 트랜잭션, 원격 쉘)
- 데이터를 잃는 것보다 기다리는 것이 더 나을 때
- 애플리케이션이 신뢰성을 스스로 처리하기를 원하지 않을 때
다음 경우에 UDP를 사용하세요:
- 완전성보다 속도가 더 중요할 때 (스트리밍, 게임, VoIP)
- 오래된 데이터가 무의미해질 때 (실시간 위치 업데이트)
- 멀티캐스트나 브로드캐스트를 사용할 때
- 애플리케이션에 자체 신뢰성 메커니즘이 있을 때
- 지연 시간이 중요할 때 (재전송할 여유가 없을 때)
HTTP는 웹 페이지의 모든 바이트가 올바른 순서로 필요하기 때문에 TCP를 사용합니다. 비디오 스트리밍은 완벽한 화질보다 부드러운 재생 경험이 더 중요하기 때문에 점점 더 UDP(또는 내부적으로 UDP를 사용하는 QUIC)를 사용합니다.
여러분의 애플리케이션을 떠받치는 프로토콜
모든 네트워크 애플리케이션은 전송 계층 위에 있습니다. 코드에서 소켓을 열면, 전송 계층에게 대화를 관리해 달라고 요청하는 것입니다. TCP 소켓은 신뢰할 수 있는 스트림을 제공합니다—바이트를 써 넣으면, 바이트가 올바른 순서로 반대편에서 나옵니다. UDP 소켓은 데이터그램을 제공합니다—도착할 수도, 도착하지 않을 수도 있는 별개의 패킷들입니다.
전송 계층은 복잡성을 알아서 처리해 주기 때문에 애플리케이션이 신경 쓰지 않아도 됩니다. 웹 브라우저는 패킷 손실을 걱정하지 않습니다. 비디오 플레이어는 TCP의 오버헤드를 걱정하지 않습니다. 각각 적절한 전송 방식을 선택하고 계층이 제 역할을 하도록 맡깁니다.
TCP와 UDP를 넘어서
전송 환경은 계속 진화하고 있습니다:
QUIC은 UDP 위에서 실행되지만 낮은 지연 시간으로 TCP와 유사한 신뢰성을 제공합니다. HTTP/3를 구동합니다. 여기서 중요한 점은, 전송 로직을 애플리케이션 안으로 이동하면 OS 커널을 변경하는 것보다 더 빠르게 혁신할 수 있다는 것입니다.
SCTP는 여러 스트림과 멀티호밍(다수의 네트워크 경로)을 갖춘 신뢰할 수 있는 메시지 지향 전송을 제공합니다. 통신 신호 처리에 사용됩니다.
DCCP는 혼잡 제어를 갖춘 비신뢰성 전송을 제공합니다—UDP의 속도에 더 나은 네트워크 시민 의식을 더한 것입니다.
하지만 TCP와 UDP는 여전히 주력 프로토콜입니다. 이것들을 이해하는 것이 여러분의 데이터가 실제로 어떻게 이동하는지를 이해하는 것입니다.
문제가 생길 때
전송 계층 문제들은 예측 가능한 방식으로 나타납니다:
연결 거부: 해당 포트에서 수신 대기 중인 것이 없습니다. 서비스가 실행되지 않거나 방화벽이 차단하고 있습니다.
연결 타임아웃: SYN이 나갔지만 SYN-ACK이 돌아오지 않았습니다. 원격 호스트가 다운되었거나, 포트가 방화벽으로 차단되었거나, 네트워크 경로가 끊어졌을 수 있습니다.
과도한 재전송: 패킷이 손실되고 있습니다. 혼잡일 수도, 링크 장애일 수도, 잘못 설정된 라우터일 수도 있습니다.
작은 윈도우 크기: 수신자(또는 송신자)의 버퍼 공간이 부족하여 처리량이 제한되고 있습니다. 종종 설정 문제입니다.
포트가 이미 사용 중: 다른 애플리케이션이 해당 포트를 점유하고 있습니다. 특정 포트에는 한 번에 하나의 애플리케이션만 바인딩할 수 있습니다.
netstat, ss, tcpdump 같은 도구들을 사용하면 전송 계층에서 무슨 일이 일어나고 있는지 정확히 볼 수 있습니다—활성 연결, 수신 대기 중인 포트, 패킷 교환, 재전송 비율.
전송 계층에 대해 자주 묻는 질문
IP 주소와 포트 번호가 모두 필요한 이유는 무엇인가요?
IP 주소는 컴퓨터를 식별하지만, 컴퓨터는 많은 애플리케이션을 실행합니다. 포트 번호는 어떤 애플리케이션이 데이터를 받아야 하는지 식별합니다. 포트가 없다면, 컴퓨터는 한 번에 하나의 네트워크 애플리케이션만 실행할 수 있습니다.
아무 포트 번호나 사용할 수 있나요?
기술적으로는 그렇지만, 실제로는 그렇지 않습니다. 0-1023번 포트는 관리자 권한이 필요하며 잘 알려진 서비스를 위해 예약되어 있습니다. HTTP가 아닌 다른 용도로 80번 포트를 사용하면 여러분의 컴퓨터에 연결하려는 누구나 혼란스러워할 것입니다. 커스텀 애플리케이션에는 높은 포트 번호(1024 이상)를 사용하세요.
TCP가 2단계가 아닌 3방향 핸드셰이크가 필요한 이유는 무엇인가요?
두 개의 메시지만으로는 한 방향으로만 통신이 성립됩니다. 세 번째 메시지(최종 ACK)는 클라이언트가 서버로부터 수신할 수 있으며, 양측이 순서 번호에 동의했음을 확인합니다. 이것이 양방향, 동기화된 통신을 위해 필요한 최소한입니다.
UDP가 실제로 신뢰할 수 없는 건가요, 아니면 그냥 기술적인 용어인가요?
"신뢰할 수 없다(unreliable)"는 기술 용어로, UDP가 전달 보증을 제공하지 않는다는 의미입니다—손실된 패킷을 재전송하거나 순서를 보장하지 않습니다. 이것이 실제 신뢰성 문제로 이어지는지는 여러분의 애플리케이션에 달려 있습니다. 대부분의 UDP 패킷은 잘 도착합니다. 단지 프로토콜이 그것을 보장하지 않을 뿐입니다.
TCP와 UDP가 같은 포트를 사용하려고 하면 어떻게 되나요?
사용할 수 있습니다. TCP 53번 포트와 UDP 53번 포트는 별개입니다. DNS는 실제로 둘 다 사용합니다—빠른 쿼리에는 UDP, 큰 응답에는 TCP를 사용합니다. 각 프로토콜에는 자체적인 포트 번호 공간이 있습니다.
이 페이지가 도움이 되었나요?