이전 편에서는 프로토콜이 무엇이고, HTTP 통신에 대해서 알아보았다. 이번에는 HTTP 요청 이전에 일어나는 DNS 조회와 TCP 연결과정에 대해서 알아보자.
DNS는 Domain Name Service의 약자로 호스트의 도메인 이름을 네트워크 주소로 바꾸거나, 네트워크 주소를 도메인 이름으로 바꾸는 과정을 이야기한다.
예를 들어 우리가 흔히 접속하는 구글의 경우 google.com의 Domain Name을 사용하고 있다.
하지만 네트워크 통신은 실제로 숫자로 이루어진 IP 주소를 사용해서 서버와 연결한다. 즉 클라이언트에서 도메인 이름을 먼저 IP 주소로 변환해야 한다. 이때 변환하기 위한 시스템을 DNS라고 한다.
왜 IP 주소를 직접 사용하지 않고 도메인 이름을 사용해야할까?
IP 주소 대신 도메인 이름을 사용하는 이유는 여러가지가 있겠지만, 크게 3가지로 볼 수 있다.
IP 주소는 한 번 정해지면 영원히 고정된 값이 아니다.
예를 들어 서버가 다른 장소로 이전하는 경우도 있고, AWS 같은 클라우드 환경에서 인스턴스가 재배치되기도 한다. 만약 앱에서 IP 주소를 하드코딩 하여 사용하고 있다면, 서버의 IP가 바뀔 때마다 이미 배포 되어 있는 앱을 다시 빌드하고 재배포 해야한다. 이러한 번거로움을 도메인 이름을 사용하면 앱 코드의 변경사항은 없이 DNS 설정만 바꿔 해결할 수 있다.
하나의 도메인 이름에 여러 개의 IP 주소가 매핑될 수 있다.
예를 들어 전세계에서 접속하는 google.com이라는 도메인 뒤에는 수백 개의 서버가 존재할 것이고 각각 서로 다른 IP 주소를 가진다. 이렇게 여러 서버 중 하나를 선택하여 연결하는 방식을 로드 밸런싱 (부하 분산)이라고 한다. 클라이언트가 도메인 요청을 보낼 때 DNS 서버는 상황에 따라 가깝고, 여유 있는 서버의 IP를 반환해주는 방식이다. 실제로 google.com 도메인에 다른 시간에 ping을 보내보면 아래와 같이 IP 주소가 달라진 것을 볼 수 있다.
HTTPS를 통해 통신하기 위해서는 SSL 인증서가 필요하다.
해당 인증서는 특정 도메인 이름에 대해 발급되기 때문에, 도메인과 1:1로 연결된다. 따라서 도메인 이름이 아닌 IP 주소로 직접 접속하게 되는 경우 인증이 실패한다.
앞에서 도메인 이름을 사용하는 이유에 대해 알아보았다.이번에는 실제로 도메인 이름이 어떻게 IP 주소로 변환되는지 즉 DNS 조회 과정에 대해 알아보자.
우리가 웹브라우저에 'google.com'을 입력하면 화면에 홈페이지가 보이기까지 내부적으로는 아래와 같은 과정을 수행한다.
TCP는 Transmission Control Protocol의 약자로, 신뢰성 있는 데이터 전송을 위해 사용되는 전송 프로토콜이다. HTTP, HTTPS 같은 기반의 통신은 바로 TCP 위에서 동작한다.
네트워크를 통해 데이터를 주고 받을 때, 한 번에 통째로 보내는 경우는 거의 없다.
대부분의 경우 데이터를 작게 나눈 패킷 단위로 전송한다. 이러한 패킷들은 하나의 경로를 통해 이동하는 것이 아닌 서로 다른 경로를 통해 이동할 수도 있다. 예를 들어 목적지(A) 까지 가는 경로가 고속도로가 있고 일반도로가 있다면, 우리는 상황에 따라 길을 선택할 수 있다. 패킷도 마찬가지로 네트워크 상황에 따라 여러 경로중 빠른 경로를 선택하여 이동할 수 있다. 하지만 경로가 다양해지면 아래와 같은 문제가 발생할 수 있다.
이러한 문제점을 해결하기 위해 TCP는 헤더에 담긴 정보와 내부 동작 방식을 통해 해결할 수 있다.
TCP는 아래와 같은 과정을 통해 데이터를 안정적으로 전송할 수 있다.
데이터 분할
데이터 스트림에서 받은 데이터를 일정 크기로 분할한다.
세그먼트 생성
분할된 데이터마다 TCP 헤더를 붙여 TCP 세그먼트를 생성한다.
이 헤더에는 순서 번호, ACK, 송수신 포트 등의 정보가 포함된다.
IP 패킷 변환
TCP 세그먼트에 IP 헤더를 붙여 IP 데이터그램으로 만든다.
IP 데이터그램은 네트워크 통신에서 사용되는 데이터패킷이다.
수신 및 재조립
IP 데이터그램을 수신 애플리케이션에 보내고, 수신 측에서는 헤더의 정보로 세그먼트를 순서대로 나열하고 유실된 데이터는 재요청한다.
패킷 vs 세그먼트
용어 | 소속 계층 | 설명 |
---|---|---|
세그먼트 (Segment) | 전송 계층 (TCP/UDP) | 애플리케이션 데이터를 전송 계층에서 나눈 단위. TCP 헤더가 붙음 |
패킷 (Packet) | 네트워크 계층 (IP) | 세그먼트에 IP 헤더를 붙인 것. 실제로 네트워크를 통해 전송되는 단위 |
TCP는 데이터를 전송할 때 전체를 한 번에 보내지 않고 작은 단위로 나누어 전송한다. 이렇게 나뉜 데이터 조각을 TCP 세그먼트라고 한다.
세그먼트의 구조는 크게 헤더와 데이터 필드 영역으로 구분된다.
헤더에는 세그먼트가 언제, 어디서 어떤 순서로 만들어졌는지에 대한 정보가 담겨있고
데이터 필드에는 실제 전송하려는 데이터의 정보가 담겨있다.
주요 헤더에 대해서 알아보자
위와 같은 헤더의 정보를 통해 몇 번째 세그먼트인지, 송수신자가 누구인지와 같은 정보들을 알 수 있다.
TCP는 데이터를 전송하기 전에, 송신자(클라이언트)와 수신자(서버) 간에 연결을 맺어야한다.
이러한 연결 과정을 3-Way Handshake라고 하며 3단계를 거쳐서 연결을 성립할 수 있다.
SYN (Syncgronize) 단계
클라이언트가 서버에게 연결을 요청하는 메시지
해당 단계에서 자신의 ISN이라는 고유번호를 담아서 SYN을 보냄
SYN + ACK 단계
서버가 클라이언트의 SYN을 수신하여 요청을 수락함
서버는 자신의 ISN을 보내며 승인번호로 클라이언트의 ISN+1을 보냄
ACK (Acknowledgment) 단계
클라이언트가 서버의 요청을 수락했다는 응답
클라이언트는 서버의 ISN+1한 값인 승인번호를 담아 ACK를 서버에 보냄
해당 과정을 통해 Handshake 과정이 끝나면, 서로의 존재와 상태를 확인하여 안정적인 연결을 맺는다.
3-Way Handshake는 단순한 연결만 하는 것은 아니다.
서버와 클라이언트가 서로의 상태를 확인하고, 신뢰성 있는 전송을 위한 기반을 설정하는 과정이다. 시퀀스 번호를 통해 패킷의 순서를 보장하고 윈도우 크기를 협상하여 데이터 흐름을 제어할 수 있다. 또한 패킷의 손실이 발생해도 재전송 메커니즘을 통해 신뢰성 있는 데이터 전송이 가능하다.
이번 글에서는 HTTP 요청이 서버에 도달하기전에 앞단에서 수행해야 하는 DNS 조회와 TCP 연결(3-Way Handshake) 과정을 살펴보았다.
우리가 브라우저에 google.com을 입력하면 일어나는 일들은 생각보다 복잡하고 정교한 시스템 위에서 돌아간다.
도메인을 IP로 변환하고, 서버와 안정적인 연결을 맺는 과정을 거쳐야 비로소 HTTP 요청이 가능해지는 것이다.
다음 글에서는 TCP 연결 이후, 다음 편에서는 데이터 전송 방식(TCP vs UDP)에 대해 알아보자.