- HTTP는 “요청-응답-연결종료”로 동작하는 stateless 프로토콜이며,
- 간단한 웹 서버는 GET 요청을 파싱해 해당 파일을 적절한 헤더와 함께 전송한 뒤 연결을 끊는 구조로 만들 수 있다.
1. HTTP 개요
-
웹 서버의 기능
- HTTP 프로토콜을 기반으로 웹 페이지에 해당하는 파일을 클라이언트에게 전송하는 역할을 하는 서버이다.
- HTTP는 Hypertext의 전송을 목적으로 설계된 애플리케이션 레벨의 프로토콜이다.
- Hypertext란 마우스 클릭을 통해 이동이 가능한, 일반적으로 HTML로 이뤄진 텍스트를 뜻한다.
-
HTTP의 핵심 특성 — Stateless
- HTTP의 기본 통신 방식은 “데이터 요청 → 데이터 응답 → 연결 종료”의 흐름으로 이뤄진다.
- 한 번의 요청·응답이 끝나면 연결을 끊어버리기 때문에 클라이언트의 상태 정보를 유지하지 않는(stateless) 프로토콜이다.
1.1. HTTP 요청과 응답 메시지
-
요청(Request) 메시지 구조
- 요청 라인: 요청 방식·파일·프로토콜 정보 (예:
GET /index.html HTTP/1.1) - 메시지 헤더: 부가 정보 (예:
User-Agent,Accept) - 공백 라인
- 메시지 몸체: POST 방식 요청 시에만 삽입된다.
- 요청 라인: 요청 방식·파일·프로토콜 정보 (예:
-
응답(Response) 메시지 구조
- 상태 라인: 프로토콜과 상태코드 (예:
HTTP/1.1 200 OK) - 메시지 헤더:
Server,Content-type,Content-length등 - 공백 라인
- 메시지 몸체: 실제 전송할 HTML 등의 데이터
- 상태 라인: 프로토콜과 상태코드 (예:
(1) HTTP 상태 코드
- HTTP 상태 코드 (HTTP Status Code)
- 클라이언트(웹 브라우저 등)가 보낸 요청에 대해 서버가 어떻게 처리했는지를 알려주는 3자리 숫자 코드
-
1xx (정보 제공 - Informational)
- 100 Continue: 요청의 시작 부분이 받아들여졌으니 작업을 계속 진행하라.
-
2xx (성공 - Successful)
- 200 OK: 요청이 성공적으로 처리되었다.
- 201 Created: 요청이 성공하여 새로운 리소스가 생성되었다.
- 204 No Content: 요청은 성공했으나, 응답으로 보낼 데이터(본문)가 없다.
-
3xx (리다이렉션 - Redirection)
- 301 Moved Permanently: 요청한 리소스의 URL이 영구적으로 변경되었다.
- 302 Found: 요청한 리소스의 URL이 임시로 변경되었다.
- 304 Not Modified: 클라이언트가 가진 캐시가 유효하므로, 서버에서 데이터를 새로 다운로드하지 않고 캐시된 자원을 재사용하면 된다.
-
4xx (클라이언트 에러 - Client Error)
- 400 Bad Request: 요청 자체가 잘못되어 서버가 이해할 수 없다.
- 401 Unauthorized: 해당 리소스에 접근하기 위한 인증(로그인 등)이 필요하거나 실패했다.
- 403 Forbidden: 서버가 클라이언트의 신원을 알고 있지만, 해당 리소스에 대한 접근 권한이 없다.
- 404 Not Found: 요청한 리소스를 서버에서 찾을 수 없다.
-
5xx (서버 에러 - Server Error)
- 500 Internal Server Error: 서버 내부의 알 수 없는 오류가 발생했다.
- 502 Bad Gateway: 게이트웨이나 프록시 서버가 상위 서버로부터 잘못된 응답을 받았다.
- 503 Service Unavailable: 서버가 일시적인 과부하 또는 점검으로 인해 현재 요청을 처리할 수 없다.
2. 간단한 웹 서버 구현
-
전체 동작 흐름 (멀티쓰레드 기반) 서버는
accept로 연결을 받을 때마다_beginthreadex로 쓰레드(RequestHandler)를 생성해 클라이언트 요청을 병렬 처리한다. -
핵심 함수 4가지로 구성된다.
2.1. RequestHandler (요청 분석)`
recv로 요청 메시지 수신- 문자열에
"HTTP/"가 없으면 잘못된 요청 → 오류 처리 strtok으로 요청 라인을 파싱해 method가"GET"인지 확인 (이 예제는 GET만 지원)- 요청 파일 이름을 추출하고 Content-type을 확인한 뒤
SendData호출
2.2. ContentType (콘텐츠 타입 판별)
- 파일 이름에서 확장자를 분리해,
html/htm이면text/html, 그 외에는text/plain을 반환한다.
2.3. SendData (정상 응답)
- 응답 헤더(
HTTP/1.0 200 OK,Server,Content-length,Content-type)를 차례로 전송하고, 요청한 파일을 열어fgets로 한 줄씩 읽어send로 전송한다. - 파일 열기에 실패하면 오류 메시지를 보낸다.
- 응답 후
closesocket으로 연결을 종료한다. (HTTP 특성)
2.4. SendErrorMSG (오류 응답)
HTTP/1.0 400 Bad Request헤더와 함께 오류 안내 HTML을 전송한 뒤 연결을 종료한다.
3. 리눅스 기반 구현
- 윈도우 기반 웹 서버를 단순히 리눅스 환경으로 옮긴 것으로, 입출력 과정에서 표준 입출력 함수를 사용하도록 바꾼 것이 차이점이다.