• 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자리 숫자 코드
  1. 1xx (정보 제공 - Informational)

    • 100 Continue: 요청의 시작 부분이 받아들여졌으니 작업을 계속 진행하라.
  2. 2xx (성공 - Successful)

    • 200 OK: 요청이 성공적으로 처리되었다.
    • 201 Created: 요청이 성공하여 새로운 리소스가 생성되었다.
    • 204 No Content: 요청은 성공했으나, 응답으로 보낼 데이터(본문)가 없다.
  3. 3xx (리다이렉션 - Redirection)

    • 301 Moved Permanently: 요청한 리소스의 URL이 영구적으로 변경되었다.
    • 302 Found: 요청한 리소스의 URL이 임시로 변경되었다.
    • 304 Not Modified: 클라이언트가 가진 캐시가 유효하므로, 서버에서 데이터를 새로 다운로드하지 않고 캐시된 자원을 재사용하면 된다.
  4. 4xx (클라이언트 에러 - Client Error)

    • 400 Bad Request: 요청 자체가 잘못되어 서버가 이해할 수 없다.
    • 401 Unauthorized: 해당 리소스에 접근하기 위한 인증(로그인 등)이 필요하거나 실패했다.
    • 403 Forbidden: 서버가 클라이언트의 신원을 알고 있지만, 해당 리소스에 대한 접근 권한이 없다.
    • 404 Not Found: 요청한 리소스를 서버에서 찾을 수 없다.
  5. 5xx (서버 에러 - Server Error)

    • 500 Internal Server Error: 서버 내부의 알 수 없는 오류가 발생했다.
    • 502 Bad Gateway: 게이트웨이나 프록시 서버가 상위 서버로부터 잘못된 응답을 받았다.
    • 503 Service Unavailable: 서버가 일시적인 과부하 또는 점검으로 인해 현재 요청을 처리할 수 없다.

2. 간단한 웹 서버 구현

  • 전체 동작 흐름 (멀티쓰레드 기반) 서버는 accept로 연결을 받을 때마다 _beginthreadex로 쓰레드(RequestHandler)를 생성해 클라이언트 요청을 병렬 처리한다.

  • 핵심 함수 4가지로 구성된다.

2.1. RequestHandler (요청 분석)`

  1. recv로 요청 메시지 수신
  2. 문자열에 "HTTP/"가 없으면 잘못된 요청 → 오류 처리
  3. strtok으로 요청 라인을 파싱해 method가 "GET"인지 확인 (이 예제는 GET만 지원)
  4. 요청 파일 이름을 추출하고 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. 리눅스 기반 구현

  • 윈도우 기반 웹 서버를 단순히 리눅스 환경으로 옮긴 것으로, 입출력 과정에서 표준 입출력 함수를 사용하도록 바꾼 것이 차이점이다.