โ† Back

[ํ”„์ ] ๐ŸฆพC์–ธ์–ด๋กœ HTTP ์„œ๋ฒ„ ๋งŒ๋“ค๊ธฐ Ch.2

๊ณจ๋“œ๋ฒ„๊ทธ ์žฅ์น˜ ๋งŒ๋“ค๊ธฐ
์ธ๋„ค์ผ

์ €๋ฒˆ์— ๋งŒ๋“  ์„œ๋ฒ„์˜ ๋ฌธ์ œ์ 

http ์„œ๋ฒ„์ธ๋ฐ ๋ธŒ๋ผ์šฐ์ €์—์„œ ์ ‘์†์„ ํ•  ์ˆ˜ ์—†์—ˆ๋‹ค.ย 

ํ—ค๋”๋ฅผ ์ „์†กํ•˜๋Š” ์ฝ”๋“œ๊ฐ€ ์—†์–ด์„œ ์ ‘์†์ด ์•ˆ๋๋‹ค.ย 

์ด๋ฒˆ์—๋Š” ๋ธŒ๋ผ์šฐ์ €์—์„œ ์ ‘์†ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ—ค๋”๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ ,

๋‹ค์–‘ํ•œ ํŒŒ์ผ์„ ์ ‘์† ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด์„œย 

receive ๋ฌธ์ž์—ด์„ ๋™์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•ด์„œ ๋‹ค์–‘ํ•œ ํŽ˜์ด์ง€๋ฅผ

๋ณผ ์ˆ˜ ์žˆ๋„๋ก ๋งŒ๋“ค ๊ฒƒ์ด๋‹ค

์ฝ”๋“œ

#include <sys/socket.h>    // ์†Œ์ผ“ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์— ํ•„์š”ํ•œ ๊ธฐ๋ณธ ํ—ค๋”
#include <string.h>        // ๋ฌธ์ž์—ด ์ฒ˜๋ฆฌ ํ•จ์ˆ˜๋ฅผ ์œ„ํ•œ ํ—ค๋”
#include <stdio.h>         // ํ‘œ์ค€ ์ž…์ถœ๋ ฅ ํ•จ์ˆ˜๋ฅผ ์œ„ํ•œ ํ—ค๋”
#include <fcntl.h>         // ํŒŒ์ผ ์ œ์–ด๋ฅผ ์œ„ํ•œ ํ—ค๋”
#include <sys/sendfile.h>  // sendfile() ํ•จ์ˆ˜๋ฅผ ์œ„ํ•œ ํ—ค๋”
#include <unistd.h>        // UNIX ํ‘œ์ค€ ํ•จ์ˆ˜๋ฅผ ์œ„ํ•œ ํ—ค๋”
#include <netinet/in.h>    // ์ธํ„ฐ๋„ท ํ”„๋กœํ† ์ฝœ ํ•จ์ˆ˜๋ฅผ ์œ„ํ•œ ํ—ค๋”
#include <time.h>          // ์‹œ๊ฐ„ ๊ด€๋ จ ํ•จ์ˆ˜๋ฅผ ์œ„ํ•œ ํ—ค๋”
#include <sys/stat.h>      // ํŒŒ์ผ ์ƒํƒœ ์ •๋ณด๋ฅผ ์œ„ํ•œ ํ—ค๋”

int main() {
    int server_fd = socket(AF_INET, SOCK_STREAM, 0);    // TCP ์†Œ์ผ“ ์ƒ์„ฑ

    int opt = 1;    // ์†Œ์ผ“ ์˜ต์…˜ ๊ฐ’ ์„ค์ •
    setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));    // ์†Œ์ผ“ ์ฃผ์†Œ ์žฌ์‚ฌ์šฉ ์˜ต์…˜ ์„ค์ •

    struct sockaddr_in addr = {    // ์„œ๋ฒ„ ์ฃผ์†Œ ๊ตฌ์กฐ์ฒด ์ดˆ๊ธฐํ™”
        .sin_family = AF_INET,     // IPv4 ์ฃผ์†Œ ์ฒด๊ณ„ ์‚ฌ์šฉ
        .sin_port = htons(8080),   // ํฌํŠธ 8080 ์„ค์ • (ํ˜ธ์ŠคํŠธ ๋ฐ”์ดํŠธ ์ˆœ์„œ๋ฅผ ๋„คํŠธ์›Œํฌ ๋ฐ”์ดํŠธ ์ˆœ์„œ๋กœ ๋ณ€ํ™˜)
        .sin_addr.s_addr = INADDR_ANY    // ๋ชจ๋“  ๋„คํŠธ์›Œํฌ ์ธํ„ฐํŽ˜์ด์Šค์—์„œ ์—ฐ๊ฒฐ ์ˆ˜๋ฝ
    };

    if (bind(server_fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {    // ์†Œ์ผ“์— ์ฃผ์†Œ ๋ฐ”์ธ๋”ฉ
        perror("bind failed");    // ๋ฐ”์ธ๋”ฉ ์‹คํŒจ์‹œ ์—๋Ÿฌ ๋ฉ”์‹œ์ง€ ์ถœ๋ ฅ
        return 1;    // ํ”„๋กœ๊ทธ๋žจ ์ข…๋ฃŒ
    }

    if (listen(server_fd, 10) < 0) {    // ์—ฐ๊ฒฐ ๋Œ€๊ธฐ์—ด 10๊ฐœ๋กœ ์„ค์ •ํ•˜์—ฌ ๋ฆฌ์Šค๋‹ ์‹œ์ž‘
        perror("listen failed");    // ๋ฆฌ์Šค๋‹ ์‹คํŒจ์‹œ ์—๋Ÿฌ ๋ฉ”์‹œ์ง€ ์ถœ๋ ฅ
        return 1;    // ํ”„๋กœ๊ทธ๋žจ ์ข…๋ฃŒ
    }

    printf("Server listening on port 8080...\n");    // ์„œ๋ฒ„ ์‹œ์ž‘ ๋ฉ”์‹œ์ง€ ์ถœ๋ ฅ

    while (1) {    // ๋ฌดํ•œ ๋ฃจํ”„๋กœ ํด๋ผ์ด์–ธํŠธ ์š”์ฒญ ๊ณ„์† ์ฒ˜๋ฆฌ
        int client_fd = accept(server_fd, NULL, NULL);    // ํด๋ผ์ด์–ธํŠธ ์—ฐ๊ฒฐ ์ˆ˜๋ฝ
        if (client_fd < 0) {    // ์—ฐ๊ฒฐ ์ˆ˜๋ฝ ์‹คํŒจ ์ฒดํฌ
            perror("accept failed");    // ์‹คํŒจ์‹œ ์—๋Ÿฌ ๋ฉ”์‹œ์ง€ ์ถœ๋ ฅ
            continue;    // ๋‹ค์Œ ์—ฐ๊ฒฐ ์‹œ๋„
        }

        char buffer[4096] = {0};    // ์š”์ฒญ์„ ์ €์žฅํ•  ๋ฒ„ํผ ์ดˆ๊ธฐํ™”
        ssize_t bytes_read = recv(client_fd, buffer, sizeof(buffer) - 1, 0);    // ํด๋ผ์ด์–ธํŠธ๋กœ๋ถ€ํ„ฐ ๋ฐ์ดํ„ฐ ์ˆ˜์‹ 

        if (bytes_read <= 0) {    // ๋ฐ์ดํ„ฐ ์ˆ˜์‹  ์‹คํŒจ ์ฒดํฌ
            close(client_fd);    // ํด๋ผ์ด์–ธํŠธ ์†Œ์ผ“ ๋‹ซ๊ธฐ
            continue;    // ๋‹ค์Œ ์—ฐ๊ฒฐ ์ฒ˜๋ฆฌ
        }

        char file_path[256] = {0};    // ํŒŒ์ผ ๊ฒฝ๋กœ๋ฅผ ์ €์žฅํ•  ๋ฒ„ํผ ์ดˆ๊ธฐํ™”
        if (sscanf(buffer, "GET /%255s", file_path) != 1) {    // HTTP GET ์š”์ฒญ์—์„œ ํŒŒ์ผ ๊ฒฝ๋กœ ์ถ”์ถœ
            char *response = "HTTP/1.1 400 Bad Request\r\nContent-Type: text/plain\r\n\r\nInvalid Request";    // ์ž˜๋ชป๋œ ์š”์ฒญ ์‘๋‹ต ๋ฉ”์‹œ์ง€
            send(client_fd, response, strlen(response), 0);    // ์—๋Ÿฌ ์‘๋‹ต ์ „์†ก
            close(client_fd);    // ํด๋ผ์ด์–ธํŠธ ์†Œ์ผ“ ๋‹ซ๊ธฐ
            continue;    // ๋‹ค์Œ ์—ฐ๊ฒฐ ์ฒ˜๋ฆฌ
        }

        char *space_pos = strchr(file_path, ' ');    // ํŒŒ์ผ ๊ฒฝ๋กœ์—์„œ ๊ณต๋ฐฑ ๋ฌธ์ž ์ฐพ๊ธฐ
        if (space_pos) *space_pos = '\0';    // ๊ณต๋ฐฑ ๋ฌธ์ž๋ฅผ NULL๋กœ ๋ณ€๊ฒฝํ•˜์—ฌ ๋ฌธ์ž์—ด ์ข…๋ฃŒ

        printf("Requesting file: %s\n", file_path);    // ์š”์ฒญ๋œ ํŒŒ์ผ ๊ฒฝ๋กœ ์ถœ๋ ฅ

        int file_fd = open(file_path, O_RDONLY);    // ์š”์ฒญ๋œ ํŒŒ์ผ ์—ด๊ธฐ
        if (file_fd < 0) {    // ํŒŒ์ผ ์—ด๊ธฐ ์‹คํŒจ ์ฒดํฌ
            printf("Failed to open file: %s\n", file_path);    // ์‹คํŒจ ๋ฉ”์‹œ์ง€ ์ถœ๋ ฅ
            char *response = "HTTP/1.1 404 Not Found\r\nContent-Type: text/plain\r\n\r\n404 File Not Found";    // 404 ์—๋Ÿฌ ์‘๋‹ต
            send(client_fd, response, strlen(response), 0);    // ์—๋Ÿฌ ์‘๋‹ต ์ „์†ก
        } else {
            struct stat file_stat;    // ํŒŒ์ผ ์ •๋ณด๋ฅผ ์ €์žฅํ•  ๊ตฌ์กฐ์ฒด
            if (fstat(file_fd, &file_stat) < 0) {    // ํŒŒ์ผ ์ •๋ณด ๊ฐ€์ ธ์˜ค๊ธฐ
                close(file_fd);    // ํŒŒ์ผ ๋””์Šคํฌ๋ฆฝํ„ฐ ๋‹ซ๊ธฐ
                close(client_fd);    // ํด๋ผ์ด์–ธํŠธ ์†Œ์ผ“ ๋‹ซ๊ธฐ
                continue;    // ๋‹ค์Œ ์—ฐ๊ฒฐ ์ฒ˜๋ฆฌ
            }

            char header[512];    // HTTP ํ—ค๋”๋ฅผ ์ €์žฅํ•  ๋ฒ„ํผ
            sprintf(header, "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nContent-Length: %ld\r\n\r\n", file_stat.st_size);    // HTTP ์„ฑ๊ณต ์‘๋‹ต ํ—ค๋” ์ƒ์„ฑ
            send(client_fd, header, strlen(header), 0);    // HTTP ํ—ค๋” ์ „์†ก

            off_t offset = 0;    // ํŒŒ์ผ ์˜คํ”„์…‹
            ssize_t sent = sendfile(client_fd, file_fd, &offset, file_stat.st_size);    // ํŒŒ์ผ ๋ฐ์ดํ„ฐ ์ „์†ก
            if (sent < 0) {    // ํŒŒ์ผ ์ „์†ก ์‹คํŒจ ์ฒดํฌ
                perror("sendfile failed");    // ์‹คํŒจ์‹œ ์—๋Ÿฌ ๋ฉ”์‹œ์ง€ ์ถœ๋ ฅ
            }

            close(file_fd);    // ํŒŒ์ผ ๋””์Šคํฌ๋ฆฝํ„ฐ ๋‹ซ๊ธฐ
        }

        close(client_fd);    // ํด๋ผ์ด์–ธํŠธ ์†Œ์ผ“ ๋‹ซ๊ธฐ
    }

    close(server_fd);    // ์„œ๋ฒ„ ์†Œ์ผ“ ๋‹ซ๊ธฐ
    return 0;    // ํ”„๋กœ๊ทธ๋žจ ์ข…๋ฃŒ
}

์ด๋ ‡๊ฒŒ ์ฝ”๋“œ๋ฅผ ๊ตฌ์„ฑํ•˜์˜€๋‹ค.ย 

๋ฌด์Šจ ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ–ˆ์„๊นŒ?

  1. ํ—ค๋” ์‚ฝ์ž…

  2. ๋™์ ์ธ receive ์ฒ˜๋ฆฌ

  3. ์˜ˆ์™ธ ์ฒ˜๋ฆฌ

  4. ๋ฌดํ•œ ๋ฃจํ”„ ์ถ”๊ฐ€

์ด๋ ‡๊ฒŒ ํ•˜๋‹ˆ๊นŒ ์›น์„œ๋ฒ„๋ฅผ ๊ตฌ์ถ•ํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.ย 

GPT๊ฐ€ ์•„์ง๊นŒ์ง€๋Š” ๋‚ด ์ฝ”๋“œ๋ฅผ ์ดํ•ดํ•ด์„œ ์–ด๋ ต์ง€ ์•Š๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ์—ˆ๋‹ค

๋‹ค์Œ์€ ์„œ๋ฒ„ ๋ฐฐํฌ๋ฅผ ํ•ด์„œ ๋‹ค๋ฅธ ์ปดํ“จํ„ฐ์—์„œ๋„ ์ด ์„œ๋ฒ„๋ฅผ ์ ‘์† ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋งŒ๋“ค์–ด ๋ณผ ๊ฒƒ์ด๋‹ค.

๋ฌธ์ œ์ 

๋ช…์ƒ‰์ด ์›น์„œ๋ฒ„์ธ๋ฐ ๋‚ด๋ถ€์—์„œ๋งŒ ์ž‘๋™ํ•ด์„œ ์นœ๊ตฌ๋“ค์—๊ฒŒ ๊ณต์œ ํ•ด์ค„ ์ˆ˜ ์—†๋‹ค.

๊ทธ๋ž˜์„œ ์™ธ๋ถ€์—์„œ๋„ ๋‚˜์˜ ์„œ๋ฒ„๋ฅผ ๋ฐฉ๋ฌธํ•  ์ˆ˜ ์žˆ๋„๋ก ํฌํŠธ ๋ฐฉํ™”๋ฒฝ ์„ค์ •์„ ํ•ด๋ณด์ž

์„ค์ •

๋ฐฉํ™”๋ฒฝ ์„ค์ •์„ ํ™•์ธํ•˜๊ณ  ํฌํŠธ 8080์„ ํ—ˆ์šฉํ•ด๋ณด์ž

sudo iptables -A INPUT -p tcp --dport 8080 -j ACCEPT

sudo ufw allow 8080/tcp

์ ‘์†ํ•ด๋ณด์ž

๊ณจ๋“œ๋ฒ„๊ทธ

๊ตณ๊ตณ ์ž˜๋“ค์–ด๊ฐ€์ง„๋‹ค

๋˜๋‹ค๋ฅธ ๋ฌธ์ œ์ 

์ง€๊ธˆ ์ด ์„œ๋ฒ„๋ฅผ ํ•™๊ต WIFI๋กœ ๊ตฌ๋™ํ•˜๊ณ  ์žˆ๋Š”๋ฐ, ํ•™๊ต ์™€์ดํŒŒ์ด์—์„œ๋Š” ํฌํŠธํฌ์›Œ๋”ฉ์ด ๋˜์ง€ ์•Š๋Š”๋‹ค!!

๊ทธ๋ž˜์„œ ๋งค๋ฒˆ ์• ๋“คํ•œํ…Œ ๋‹ค๋ฅธ ์ฃผ์†Œ๋ฅผ ์ „์†กํ•ด์•ผํ•œ๋‹ค ใ…œใ… 

โ†

[ํ”„์ ] ๐ŸฆพC์–ธ์–ด๋กœ HTTP ์„œ๋ฒ„ ๋งŒ๋“ค๊ธฐ Ch.1

๊ณจ๋“œ๋ฒ„๊ทธ ์žฅ์น˜ ๋งŒ๋“ค๊ธฐ

โ†’

[ํšŒ๊ณ ] ๋กœ๋ด‡๊ฒฝ์ง„๋Œ€ํšŒ - ๋ฏธ์…˜ํˆฌ๋งˆ์Šค

์ด๋ฅœ๊ตฌ๋™์ฐจ ๋งŒ๋“ค๊ธฐ