🔵 HTTP 프로토콜

HTTP는 웹에서 클라이언트와 서버가 데이터를 주고받기 위해 사용하는
요청-응답 기반 프로토콜입니다.
무상태성(stateless)을 가지므로 서버는 이전 요청의 상태를 기억하지 않고
각 요청은 독립적으로 처리됩니다.
GET·POST·PUT·DELETE 같은 메서드를 통해 리소스를 표현하고 조작하며
헤더와 바디 구조로 다양한 형태의 데이터를 교환합니다.
HTTP/1.1과 HTTP/2는 신뢰성 있는 전송을 위해
TCP를 기반으로 동작하는 애플리케이션 계층 프로토콜입니다.
HTTP/2는 기존 TCP 구조를 유지하면서 멀티플렉싱과 헤더 압축을 도입해 성능을 개선했습니다.
HTTP/3는 TCP 대신 QUIC 프로토콜을 기반으로 동작하여 핸드셰이크 지연을 줄이고 연결 설정의 안정성을 높였습니다.
🔵 HTTP의 요청/응답 모델

HTTP는 클라이언트가 요청을 보내면
서버가 그에 대한 응답을 반환하는 단방향, Request-Response 기반 통신 모델입니다.
클라이언트는 메서드·URI·헤더·바디로 구성된 요청 메시지를 보내고
서버는 상태코드·헤더·바디를 포함한 응답 메시지로 결과를 전달합니다.
이 구조는 각 요청이 완전히 독립적으로 처리되는 무상태성(stateless) 특성을 가지며
서버는 클라이언트의 이전 상태를 기억하지 않습니다.
덕분에 확장성이 뛰어나고 단순한 구조를 유지할 수 있지만
로그인 유지 같은 상태 저장이 필요할 경우 쿠키·세션·JWT 같은 추가 메커니즘이 필요합니다.
🔵 HTTP/1.1, HTTP/2, HTTP/3 각각의 특징

HTTP/1.1은 TCP 위에서 동작하며 한 연결에서 한 요청만 처리할 수 있는 구조를 가지고 있습니다.
이로 인해 요청이 순차적으로 처리되며, 앞선 요청이 지연될 경우 뒤의 요청이 모두 대기하는
헤드-오브-라인 블로킹(HOL Blocking) 문제가 발생합니다.
또한 텍스트 기반 헤더를 사용하므로 중복되는 헤더 데이터가 자주 포함되고
전송 효율이 떨어지는 단점이 있습니다.
Keep-Alive 기능을 통해 연결 재사용은 가능하지만
병렬 처리가 불가능하다는 구조적 한계는 그대로 남아 있습니다.

HTTP/2는 HTTP/1.1의 HOL Blocking 문제를 완화하기 위해
바이너리 프레이밍과 멀티플렉싱을 도입한 프로토콜입니다.
여전히 TCP 위에서 동작하지만
요청과 응답을 여러 개의 스트림(stream) 으로 나누고
이를 작은 단위의 프레임(frame) 으로 쪼개어
하나의 TCP 연결 위에서 동시에 전송할 수 있도록 설계되었습니다.
이를 통해 논리적으로는 여러 요청이 병렬로 처리되는 것처럼 동작하므로 성능이 크게 향상됩니다.
또한 HPACK 헤더 압축을 통해 중복 헤더 전송 비용을 줄이고 효율을 높입니다.

그러나 TCP는 전송 순서를 강제 보장하는 프로토콜이므로,
하나의 패킷이 손실되면 재전송이 완료될 때까지 뒤의 데이터가 모두 정체되는 HOL Blocking은 완전히 사라지지 않습니다.
HTTP/2는 애플리케이션 레벨에서의 멀티플렉싱만 제공하며
TCP의 구조적 한계를 근본적으로 해결하지는 못합니다.

HTTP/3는 이 문제를 해결하기 위해 TCP 대신 UDP 기반의 QUIC 프로토콜을 사용합니다.
UDP는 전송 순서를 보장하지 않기 때문에 HOL Blocking 문제가 발생하지 않으며,
QUIC은 그 위에 다음 기능을 애플리케이션 계층에서 직접 구현합니다:
- 패킷 재전송 관리
- 독립적인 스트림 단위 멀티플렉싱
- 손실된 스트림만 재전송하는 구조
이로 인해 특정 스트림에 문제가 발생해도 다른 스트림에는 영향이 없으며
TCP 기반 HTTP/1.1·HTTP/2에서 발생하던 전송 레벨 HOL Blocking이 제거됩니다..
🔵 HTTP Keep-Alive
HTTP Keep-Alive는 요청마다 새로운 TCP 연결을 생성하지 않고,
하나의 TCP 연결을 여러 요청에 재사용하도록 하는 기능입니다.
기본적으로 HTTP는 요청과 응답이 끝나면 연결을 끊는 특성을 가지고 있지만,
Keep-Alive를 사용하면 매 요청마다 반복되는 TCP 핸드셰이크 과정을 줄일 수 있습니다.
TCP 연결을 재사용하게 되면 네트워크 왕복 시간(RTT)이 감소하고,
특히 여러 리소스(HTML, CSS, JavaScript, 이미지 등)를 연속적으로 요청하는 웹 환경에서
전체 페이지 로딩 속도가 크게 개선됩니다.
이러한 이유로 Keep-Alive는 웹 통신 성능을 높이는 핵심적인 기술로 널리 사용됩니다.
또한 HTTP/2에서는 하나의 연결 위에서 여러 요청을 동시에 처리하는 멀티플렉싱 구조가 도입되면서
Keep-Alive의 이점이 더욱 확장된 형태로 구현되었습니다.
🔵 HTTP 파이프라이닝

HTTP 파이프라이닝은 하나의 TCP 연결에서
앞선 요청의 응답을 기다리지 않고 다음 요청들을 미리 전송하는 방식입니다.
그러나 서버는 요청을 받은 순서에 따라 응답을 반환해야 하므로,
앞선 요청 중 하나라도 지연되면 뒤에 있는 모든 응답이 함께 지연되는
헤드-오브-라인 블로킹(HOL Blocking) 문제가 발생합니다.
이 구조적 한계 때문에 실제 성능 향상이 크지 않았으며
여러 브라우저에서 구현 차이와 호환성 문제가 존재했습니다.
이러한 이유로 파이프라이닝은 대부분의 브라우저에서 기본적으로 비활성화되었고,
현대 웹 환경에서는 거의 사용되지 않습니다.
현재는 파이프라이닝의 한계를 보완한 HTTP/2의 멀티플렉싱 기술이 사실상 표준으로 자리잡아,
TCP 기반에서도 여러 요청을 동시에 처리할 수 있는 방식이 보다 안정적으로 제공되고 있습니다.
🔵 HTTP 헤더

HTTP 헤더는 클라이언트와 서버가 요청(Request)과 응답(Response) 과정에서
부가적인 정보를 교환하기 위해 사용하는 메타데이터 영역입니다.
헤더에는 콘텐츠 형식, 인코딩 방식, 캐싱 정책, 인증 정보 등
HTTP 통신 동작을 제어하는 다양한 설정이 포함됩니다.
🔵 1. HTTP 요청(Request) 헤더
HTTP 요청 헤더는 클라이언트가 서버에게 자신의 상태와 요구사항을 전달하기 위한 정보로 구성됩니다.
브라우저가 어떤 형식의 데이터를 받고 싶은지, 어떤 언어를 선호하는지,
어떤 쿠키를 포함해서 요청하는지 등이 여기에 포함됩니다.
대표적인 요청 헤더
✔ Accept: 클라이언트가 응답에서 받고 싶은 콘텐츠 유형
✔ Accept-Encoding: 지원 가능한 압축 방식(gzip, br 등)
✔ Cookie: 클라이언트가 가진 쿠키를 서버로 전송
✔ Cache-Control: 캐싱 정책(max-age 등)
✔ Content-Type: 요청 바디의 데이터 형식
✔ Content-Length: 바디의 길이
✔ Referer: 어떤 페이지에서 요청이 발생했는지
✔ User-Agent: 브라우저·OS 정보
🔵 2. HTTP 응답(Response) 헤더
HTTP 응답 헤더는 서버가 클라이언트에게 응답 내용과 처리 정책을 전달하는 정보로 구성됩니다.
서버가 어떤 형식의 데이터를 보내는지, 쿠키를 저장해야 하는지,
특정 리소스를 캐싱해도 되는지 등을 알려줍니다.
대표적인 응답 헤더
✔ Content-Type: 서버가 보내는 콘텐츠 유형
✔ Content-Length: 응답 바디의 크기
✔ Cache-Control: 응답 데이터의 캐싱 정책
✔ Set-Cookie: 클라이언트에게 쿠키 저장 명령
✔ Server: 서버 소프트웨어 정보
✔ Date: 응답 생성 시각
✔ Access-Control-Allow-Origin: CORS 정책
✔ Alt-Svc: 대체 프로토콜 제공(예: HTTP/3, h2)
🔵 HTTP 상태 코드
HTTP 상태 코드는 서버가 클라이언트의 요청을 어떻게 처리했는지를 숫자로 표현한 응답 결과 코드입니다.
대표적인 상태 코드는 다음과 같습니다.
- 200 OK: 요청이 정상적으로 처리됨.
- 201 Created: 새로운 리소스가 성공적으로 생성됨.
- 400 Bad Request: 요청 형식이나 파라미터가 잘못됨.
- 401 Unauthorized: 인증이 필요한 요청이나 토큰이 유효하지 않음.
- 403 Forbidden: 인증은 되었지만 권한이 없어 접근 불가.
- 404 Not Found: 요청한 리소스가 존재하지 않음.
- 500 Internal Server Error: 서버 내부 오류로 요청 처리 실패.
- 503 Service Unavailable: 서버 과부하 또는 점검 등으로 일시적으로 서비스 불가.
300번대 상태 코드는 리다이렉션을 의미하지만, 이 중 일부는 브라우저 캐싱과 직접적으로 연결됩니다.
특히 304 Not Modified는 가장 대표적인 캐싱 관련 코드로
클라이언트가 ETag나 Last-Modified 값을 보내며 조건부 요청을 했을 때
서버 리소스가 변경되지 않았다면 304를 반환하고
바디 없이 캐시된 데이터를 그대로 사용하도록 합니다.
또한 301 Moved Permanently와 308 Permanent Redirect는
리소스 위치가 영구적으로 변경되었음을 나타내며
브라우저가 이 정보를 오랫동안 캐싱하는 특징이 있어 캐싱 정책에 영향을 줄 수 있습니다.
반면 302나 307 같은 임시 리다이렉트는 캐싱이 보장되지 않습니다.
캐싱과 가장 직접적인 코드는 304,
그리고 영구 리다이렉트인 301/308도 캐싱과 연관이 있습니다.
🔵 HTTP의 무상태성(Stateless)
HTTP는 무상태성(stateless) 을 기반으로 동작하는 프로토콜입니다.
이는 각 요청이 서로 독립적으로 처리되며
서버가 클라이언트의 이전 상태를 저장하지 않는다는 의미입니다.
따라서 서버는 사용자가 이전에 어떤 요청을 보냈는지,
로그인한 사용자였는지와 같은 정보를 기본적으로 기억하지 않습니다.
무상태성은 서버가 별도의 상태를 유지하지 않기 때문에
구현이 단순하며 확장성이 뛰어난 장점이 있습니다.
요청을 처리하는 서버가 바뀌어도 문제가 없기 때문에
대규모 서비스에서 서버를 쉽게 수평 확장할 수 있습니다.
그러나 로그인 유지, 장바구니, 사용자 설정처럼 상태가 필요한 기능은 HTTP 자체로는 관리할 수 없으므로
쿠키, 세션, JWT 등 추가적인 상태 관리 기법이 필요합니다.
🔵 HTTP 메서드중 PUT과 PATCH의 차이점
PUT은 리소스 전체를 교체하는 메서드로, 요청 바디가 해당 리소스의 완전한 표현이어야 합니다.
즉, 일부 필드만 보내더라도 서버는 이를 전체 업데이트로 간주하고 기존 값을 모두 대체하는 방식이 원칙입니다.
이 때문에 PUT은 설계상 멱등성(idempotent) 을 가지도록 정의됩니다.
반면 PATCH는 리소스의 일부만 수정하는 메서드입니다.
변경하고자 하는 필드만 포함해 보내며, 나머지 필드는 그대로 유지됩니다.
부분 업데이트에 최적화되어 있으며
상황에 따라 멱등성을 가질 수도, 가지지 않을 수도 있습니다.
🟢 HTTPS

HTTPS는 HTTP에 SSL/TLS 암호화 계층을 적용한 보안 프로토콜입니다.
클라이언트와 서버 간 데이터를 암호화하며,
무결성을 보장하고, 서버 인증을 수행하여 안전하게 통신할 수 있도록 합니다.
이 방식은 통신 내용을 도청하거나 조작하려는 공격 및 패킷 분석을 효과적으로 차단합니다.
또한 브라우저는 서버가 제공하는 TLS 인증서를 검증하여, 통신 대상이 신뢰할 수 있는 서버인지 확인합니다.
HTTPS는 기존 HTTP의 평문 전송으로 인한 보안 취약점을 해결하며,
현대의 웹 서비스에서는 기본적으로 HTTPS를 사용하는 것이 표준이 되었습니다.
🟢 SSL/TLS

SSL/TLS는 인터넷에서 데이터를 안전하게 주고받기 위해 사용되는 보안 통신 프로토콜입니다.
현재는 SSL이 아닌 TLS가 표준으로 사용되며
서버와 클라이언트 사이에 암호화된 연결을 설정하는 역할을 합니다.
TLS는 먼저 서버 인증서를 이용해 상대가 신뢰할 수 있는 대상인지 확인한 뒤
공개키 암호화를 사용해 대칭키를 안전하게 공유합니다.
이후 실제 데이터 전송은 속도가 빠른 대칭키 암호화 방식으로 이루어져
보안성과 성능을 동시에 확보합니다.
정리하면, TLS는 안전한 연결을 만드는 기술이고
HTTPS는 HTTP 통신 위에 TLS를 적용한 보안 프로토콜입니다.
🟢 대칭키 암호화 방식

대칭키 암호화는 암호화와 복호화에 동일한 키를 사용하는 방식입니다.
연산 속도가 빠르고 처리 효율이 높기 때문에
HTTPS에서는 실제 애플리케이션 데이터를 암호화하는 핵심 방식으로 사용됩니다.
그러나 동일한 키를 양측이 공유해야 한다는 특성 때문에
키가 노출될 경우 모든 암호화된 정보가 그대로 유출되는 위험이 있습니다.
따라서 대칭키를 안전하게 교환하는 과정이 보안에서 가장 중요한 요소가 됩니다.
🟢 비대칭키(공개키) 암호화 방식
비대칭키 암호화는 공개키와 개인키 두 개의 키를 사용하는 방식입니다.
공개키로 암호화된 데이터는 개인키로만 복호화할 수 있고
개인키로 암호화한 정보는 공개키로만 복호화할 수 있습니다.
HTTPS에서는 이 구조를 활용해 대칭키를 안전하게 교환하고,
서버 인증서 검증이나 전자서명 검증과 같은 보안 기능을 수행합니다.
비대칭키 방식은 보안성이 높지만 연산 비용이 크기 때문에
실제 애플리케이션 데이터 암호화에는 사용되지 않고
주로 키 교환과 인증 과정에서 사용됩니다.
🟢 전자 서명
전자 서명은 데이터를 보낸 사람이 누구인지 증명하고
전송 과정에서 데이터가 변조되지 않았음을 보장하기 위한 기술입니다.
- 데이터의 해시값 계산
- 해시를 개인키로 암호화
- 검증하는 쪽은
- 받은 데이터로 해시를 다시 계산하고,
- 전자 서명을 공개키로 복호화해서 나온 값과 비교
HTTPS에서도 전자 서명이 활용되며
서버 인증서가 신뢰할 수 있는 기관에 의해 발급되었는지 검증하는 과정에서
전자 서명이 사용되어 인증서 위조를 방지합니다.
🟢 HTTPS 암호화 과정 (SSL Handshake의 동작 과정)

HTTPS는 서버 인증 및 키 교환을 위해 TLS Handshake를 수행하며
전체 흐름은 다음과 같습니다.
0) TCP 3단계 연결(SYN → SYN/ACK → ACK)
먼저 클라이언트와 서버는
“우리 이제 통신할게요”
라고 서로 신호를 주고받아 연결을 만듭니다.
1) Client Hello
클라이언트 -> 서버
“제가 사용할 수 있는 TLS 버전은 이거고,
이런 암호화 방식들을 지원해요.
그리고 이건 제가 만든 랜덤 값이에요.”
이 메시지를 보내며 TLS 암호화 준비를 시작합니다.
2) Server Hello + 인증서
서버가 클라이언트에게 답장합니다:
“좋아요, 저는 이 암호화 방식을 쓸게요.
그리고 이건 제 인증서(공개키 포함)입니다.”
인증서에는 서버의 신원 정보와 공개키가 들어 있습니다.
3) 클라이언트가 인증서 확인
클라이언트는 받은 인증서를 검사합니다.
- 이 인증서가 진짜인지
- 만료되지 않았는지
- 주소(도메인)가 맞는지
문제가 없으면
“이 서버는 믿을 수 있네.”
라고 판단합니다.
4) Premaster Secret 전달
클라이언트가 새로운 비밀 값(Premaster Secret)을 하나 만들고
서버의 공개키로 암호화해서 서버에게 보냅니다.
서버는 자신의 개인키로 복호화해서 이 값을 얻게 됩니다.
즉, 둘만 아는 비밀값이 생긴 것입니다.
5) Session Key 만들기
클라이언트와 서버는
- 클라이언트 랜덤값
- 서버 랜덤값
- Premaster Secret
이 3개를 섞어서
똑같은 Session Key(대칭키) 를 각각 만들어냅니다.
이 키가 앞으로 데이터를 암호화하는 데 사용됩니다.
6) Change Cipher Spec
서로 이렇게 말합니다:
“이제부터는 이 세션키로 암호화해서 이야기할게요!”
7) Finished 메시지
서버와 클라이언트는
암호화가 잘 되는지 확인하기 위해
암호화된 Finished 메시지를 서로 주고받습니다.
“암호화 잘 됩니다!”
하는 확인 단계입니다.
8) 암호화된 HTTPS 통신 시작
모든 준비가 끝나면
HTTP 데이터는 전부 세션키로 암호화된 상태로 안전하게 주고받습니다.
🔴 DNS
DNS는 도메인 이름을 IP 주소로 변환해주는 인터넷의 전화번호부 역할을 하는 시스템입니다.
사람은 “google.com” 같은 문자열을 기억하기 쉽지만
컴퓨터는 실제로 통신하기 위해 IP 주소가 필요하므로
DNS가 중간에서 이름을 IP로 매핑해주는 기능을 수행합니다.
이 덕분에 사용자는 숫자 주소를 직접 입력하지 않고도 안정적으로 서버에 접속할 수 있습니다.
🔴 DNS 작동 방식
DNS 동작은 사용자가 브라우저에 도메인을 입력했을 때,
그 주소가 어떤 IP인지 찾기 위해 여러 단계를 거쳐 조회하는 과정입니다.
1) 브라우저와 로컬 캐시 확인
브라우저는 먼저
- 브라우저 캐시
- OS 캐시
- 로컬 DNS 캐시
에 해당 도메인의 IP가 저장돼 있는지 확인합니다.
이미 있다면 바로 그 IP를 사용합니다.
2) 로컬 DNS(Resolver)로 질의
캐시에 없다면 브라우저는 DNS Resolver(로컬 DNS 서버) 에
“이 도메인 IP 좀 알려줘”라고 요청합니다.
대부분 ISP(통신사)나 회사/공용 DNS가 이 역할을 합니다.
3) DNS Resolver의 단계별 조회
Resolver는 직접 답을 모르면 다음 순서로 상위 DNS 서버에 차례대로 물어봅니다.
- Root DNS
→ “.com을 담당하는 서버 어디 있어?” - TLD DNS(.com, .net 등)
→ “google.com의 권한 서버 어디 있어?” - Authoritative DNS(권한 DNS)
→ “google.com의 실제 IP는 이거야.”
이렇게 루트 → 최상위 도메인(TLD) → 권한 DNS 순서로 정보를 찾아갑니다.
4) 최종 IP 반환 + 캐싱
Authoritative DNS가 알려준 정확한 IP 주소는
- Resolver 캐시
- OS 캐시
- 브라우저 캐시
에 저장됩니다.
다음에 같은 도메인을 입력하면 조회 과정을 생략하고 훨씬 빠르게 연결됩니다.
🔴 DNS 질의 종류
- 재귀 질의: "IP 나올 때까지 너가 다 찾아와!" (클라이언트 → Resolver)
- 반복 질의: "난 몰라, 대신 다음 주소는 알려줄게." (Resolver가 DNS를 단계별 탐색)
- 비재귀 질의: "이미 답 알고 있어, 바로 줄게!" (캐시 히트)
🔴 DNS 서버에게 IP 주소를 요청할 때 UDP 사용 이유
DNS는 빠른 응답이 중요한 서비스이기 때문에,
처리가 가볍고 빠른 UDP를 기본으로 사용합니다.
DNS 요청·응답은 대부분 크기가 작아서
UDP가 한 번에 보낼 수 있는 용량 안에 충분히 들어갑니다.
또한 TCP처럼 연결을 만드는 절차도 없어서 더 빠르게 응답할 수 있습니다.
DNS는 실패할 경우 자동으로 다시 요청하는 구조라
UDP의 신뢰성 문제도 크게 문제가 되지 않습니다.
다만 응답이 너무 크거나(DNSSEC 등)
보안 검증이 필요한 경우에는 TCP로 전송하기도 합니다.
🔴 DNS 레코드
DNS 레코드는 도메인이 어떤 정보를 가지고 있는지 정의한 데이터입니다.
예를 들어 도메인이 어떤 IP를 가리키는지, 메일 서버가 어디인지,
혹은 다른 도메인으로 연결되는지 같은 설정들이 레코드에 들어 있습니다.
DNS 서버는 이 레코드들을 저장하고 있고,
클라이언트는 필요한 레코드를 조회해 도메인 관련 정보를 얻습니다.
- A 레코드
- 도메인 → IPv4 주소
- AAAA 레코드
- 도메인 → IPv6 주소
- CNAME 레코드
- 하나의 도메인 이름을 다른 도메인의 별칭으로 연결
- 예: api.example.com → backend.example.com
- MX 레코드
- 메일 서버 정보 (메일 수신 시 어디로 보내야 하는지)
- NS 레코드
- 이 도메인을 담당하는 네임 서버 정보
- TXT 레코드
- 자유 텍스트 정보
- SPF 설정, 도메인 소유 증명, 각종 서비스 연동 등에서 많이 사용
'Programming > 컴퓨터 네트워크' 카테고리의 다른 글
| 🔵 네트워크 레이어, IP 프로토콜 (0) | 2025.12.17 |
|---|---|
| 🔵 UDP & TCP (1) | 2025.12.11 |
| 🔵 애플리케이션 레이어 (0) | 2025.12.02 |
| 🔵 HTTP/1.1 vs HTTP/2 vs HTTP3 차이 (0) | 2025.11.25 |
| 🔵 TCP/IP & OSI 7 Layer (0) | 2025.11.20 |