๐Ÿ˜Ž ๊ณต๋ถ€ํ•˜๋Š” ์ง•์ง•์•ŒํŒŒ์นด๋Š” ์ฒ˜์Œ์ด์ง€?

[๋ฆฌ๋ˆ…์Šค ๋„คํŠธ์›Œํฌ ํ”„๋กœ๊ทธ๋ž˜๋ฐ] HTTP์™€ ์›น ์„œ๋ฒ„ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ณธ๋ฌธ

๐Ÿ‘ฉ‍๐Ÿ’ป IoT (Embedded)/Raspberry Pi

[๋ฆฌ๋ˆ…์Šค ๋„คํŠธ์›Œํฌ ํ”„๋กœ๊ทธ๋ž˜๋ฐ] HTTP์™€ ์›น ์„œ๋ฒ„ ํ”„๋กœ๊ทธ๋ž˜๋ฐ

์ง•์ง•์•ŒํŒŒ์นด 2024. 2. 10. 00:14
728x90
๋ฐ˜์‘ํ˜•

<์„œ์˜์ง„ ๋‹˜์˜ ์‚ฌ๋ฌผ์ธํ„ฐ๋„ท์„ ์œ„ํ•œ ๋ฆฌ๋ˆ…์Šค ํ”„๋กœ๊ทธ๋ž˜๋ฐ with ๋ผ์ฆˆ๋ฒ ๋ฆฌํŒŒ์ด ์„œ์ ์„ ์ฐธ๊ณ ํ•ด์„œ ์ž‘์„ฑํ•˜์˜€์Šต๋‹ˆ๋‹ค :-)>

 

โญ ์›น๊ณผ HTTP

์›น(Web) ์€ ์ธํ„ฐ๋„ท์„ ์œ„ํ•œ ๋„คํŠธ์›Œํฌ ์‹œ์Šคํ…œ์œผ๋กœ ์„œ๋ฒ„์™€ ํด๋ผ์ด์–ธํŠธ๋“ค์ด ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๋Š” ์ง‘ํ•ฉ

์ „ ์„ธ๊ณ„์˜ ๋„คํŠธ์›Œํฌ๊ฐ€ ํ•˜์ดํผํ…์ŠคํŠธ ๋งํฌ๋กœ ์—ฐ๊ฒฐ๋œ ๋ชจ์Šต์ด ๋งˆ์น˜ ๊ฑฐ๋Œ€ํ•œ ๊ฑฐ๋ฏธ์ง‘ (CobWeb) ๋˜๋Š” ๊ฑฐ๋ฏธ์ง‘ ๋ชจ์–‘์˜ ๋ง๊ณผ ๊ฐ™๋‹ค๊ณ  ํ•ด์„œ ๋ถ™์—ฌ์ง„ ์ด๋ฆ„

 

์›น ๊ธฐ์ˆ ์€ HTTP (HyperText Transfer Protocol) ๋ผ๋Š” ํ”„๋กœํ† ์ฝœ ์œ„์—์„œ ๊ตฌ๋™๋˜๋ฉฐ, ์›น๊ณผ ๊ด€๋ จ๋œ ํ‘œ์ค€ํ™”๋Š” ์›”๋“œ ์™€์ด๋“œ ์›น ์ปจ์†Œ์‹œ์›€ (W3C, World Wide Web Consortium) ์—์„œ ์ง„ํ–‰ํ•œ๋‹ค

์›น์€ ์ธํ„ฐ๋„ท์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์›น ์„œ๋ฒ„์™€ ์›น ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์„œ๋ฒ„์™€ ํด๋ผ์ด์–ธํŠธ ๊ตฌ์กฐ๋กœ ๋™์ž‘ํ•œ๋‹ค

TCP๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๋™์ž‘ํ•˜๋ฉฐ 80 ๋ฒˆ ํฌํŠธ๋ฒˆํ˜ธ๋กœ ์‚ฌ์šฉํ•œ๋‹ค

 

HTTP ์˜ ์ฒซ ๋‘ ๊ธ€์ž๋Š” ํ•˜์ดํผํ…์ŠคํŠธ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋ฉฐ, ํ˜„์žฌ ๋ฌธ์„œ์™€ ์—ฐ๊ฒฐ๋œ ๋‹ค๋ฅธ ํŽ˜์ด์ง€๋กœ์˜ ์—ฐ๊ฒฐ์„ ์˜๋ฏธํ•œ๋‹ค

HTTP๋Š” ํ•˜๋‚˜์˜ ํŽ˜์ด์ง€์—์„œ ๋‹ค๋ฅธ ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•˜๋Š” ํ•˜์ดํผํ…์ŠคํŠธ ํ™˜๊ฒฝ์—์„œ ์ด์šฉ๋˜๊ณ  ์žˆ๋Š”๋ฐ, ์ด๋Ÿฌํ•œ HTTP๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์›น์—์„œ์˜ ๋ฌธ์„œ๋ฅผ ๊ธฐ์ˆ ํ•˜๋Š”๋ฐ HTML(HyperText Markup Language) ์ด ์‚ฌ์šฉ๋œ๋‹ค

 

โญ ์›น ๋ธŒ๋ผ์šฐ์ €์™€ ์›น ์—”์ง„

์›น ์„œ๋น„์Šค๋ฅผ ์ด์š”ํ•ด์„œ ์‚ฌ์šฉ์ž์—๊ฒŒ ์ •๋ณด๋ฅผ ๋ณด์—ฌ์ฃผ๊ธฐ ์œ„ํ•ด์„œ๋Š” ์›น ๋ธŒ๋ผ์šฐ์ € ํ”„๋กœ๊ทธ๋žจ์ด ํ•„์š”ํ•˜๋‹ค

์›น ๋ธŒ๋ผ์šฐ์ €๋Š” ์ธํ„ฐ๋„ท์ƒ์˜ ๋ฌธ์„œ๋‚˜ ๋ฉ€ํ‹ฐ๋ฏธ๋””์–ด ๋“ฑ์„ ํ‘œ์‹œํ•˜๋Š”๋ฐ ์‚ฌ์šฉ, ์›น์—์„œ ์„œ๋ฒ„์™€ ํด๋ผ์ด์–ธํŠธ ๊ฐ„ ํ†ต์‹ ์„ ์œ„ํ•œ ํ”„๋กœํ† ์ฝœ์ธ HTTP ๋‚˜ ์›น์—์„œ ๋ฌธ์„œ๋ฅผ ํ‘œํ˜„ํ•˜๊ธฐ ์œ„ํ•œ ๋งˆํฌ์—… ์–ธ์–ด์ธ HTML ์„ ๋ถ„์„ํ•˜๊ธฐ ์œ„ํ•œ ์›น ๋ธŒ๋ผ์šฐ์ € ์—”์ง„์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค

 

์›นํ‚ท (Webkit) ์€ KDE ํ”„๋กœ์ ํŠธ์˜ ์บ‰์ปค๋Ÿฌ์—์„œ ์‚ฌ์šฉ๋˜์—ˆ๋˜ khtml ๋ Œ๋”๋ง ์—”์ง„์„ ์• ํ”Œ์ด ๊ฐ€์ ธ์™€์„œ ์˜คํ”ˆ ์†Œ์Šคํ™” ํ•œ ๊ฒƒ

ํ˜„์žฌ ๊ฐ€์žฅ ๋งŽ์€ ์ธํ„ฐ๋„ท ํŠธ๋ž˜ํ”ฝ์„ ๊ธฐ๋กํ•˜๋„ ์žˆ๋Š” ์›น ์—”์ง„์œผ๋กœ iOS์™€ masOS ์‚ฌํŒŒ๋ฆฌ, ์‹ฌ๋น„์•ˆ ๋“ฑ์—์„œ ์‚ฌ์šฉ๋จ

์›นํ‚ท๊ณผ ํ•จ๊ป˜ ๋งŽ์ด ์‚ฌ์šฉํ•˜๋Š” ์—”์ง„์ด ๋ฐ”๋กœ ๊ฒŒ์ฝ” (Gecko) ์—”์ง„์ด๋‹ค

๊ฒŒ์ฝ” ์—”์ง„์€ ๋„ค์Šค์ผ€์ดํ”„ ๋„ค๋น„๊ฒŒ์ดํ„ฐ ์›น ๋ธŒ๋ผ์šฐ์ € 6์—์„œ ์‚ฌ์šฉ๋˜๋˜ ์˜คํ”ˆ ์†Œ์Šค ์—”์ง„์œผ๋กœ, ํ˜„์žฌ๋Š” ๋ชจ์งˆ๋ผ ์žฌ๋‹จ์—์„œ ๊ด€๋ฆฌํ•˜๊ณ  ์žˆ์œผ๋ฉฐ ํŒŒ์ด์–ดํญ์Šค ์›น ๋ธŒ๋ผ์šฐ์ €์˜ ์›น ์—”์ง„์œผ๋กœ ์‚ฌ์šฉ๋˜๊ณ  ์žˆ๋‹ค

 

โญ HTTP ์˜ ๊ตฌ์กฐ

HTTP๋Š” ์›น์—์„œ ์‚ฌ์šฉ๋˜๋Š” ํ”„๋กœํ† ์ฝœ๋กœ ์ธํ„ฐ๋„ท์ƒ์—์„œ HTML๋ฌธ์„œ๋ฅผ ์ฃผ๊ณ  ๋ฐ›๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋ฉฐ, TCP์™€ 80๋ฒˆ ํฌํŠธ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค

์›น ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์›น ์„œ๋ฒ„๋กœ ์š”์ฒญํ•˜๊ณ  ์›น ์„œ๋ฒ„๊ฐ€ ์›น ํด๋ผ์ด์–ธํŠธ๋กœ ์‘๋‹ตํ•œ๋‹ค

์‚ฌ์šฉ๋˜๋Š” ํ”„๋กœํ† ์ฝœ์ด HTTP ์ด๋‹ค

HTTP ํด๋ผ์ด์–ธํŠธ์˜ ๋Œ€ํ‘œ์ ์ธ ์˜ˆ๊ฐ€ ์›น ๋ธŒ๋ผ์šฐ์ €์ด๋ฉฐ, ์›น ๋ธŒ๋ผ์šฐ์ €์˜ ์š”์ฒญ์„ ๋ฐ›์•„์„œ ์ฒ˜๋ฆฌํ•˜๋Š” HTTP ์„œ๋ฒ„๋ฅผ ์›น ์„œ๋ฒ„๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค

HTTP๋Š” TCP/IP ์Šคํƒ์˜ ์ƒ์œ„ ๋ ˆ๋ฒจ์ธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ ˆ๋ฒจ์˜ ํ”„๋กœํ† ์ฝœ๋กœ, ์„œ๋ฒ„์™€ ํด๋ผ์ด์–ธํŠธ๋Š” ํ•˜์œ„์˜ TCP/IP ํ”„๋กœํ† ์ฝœ์„ ํ†ตํ•ด ํ†ต์‹ ํ•œ๋‹ค

 

HTTP ์š”์ฒญ์„ ๋จผ์ € ์‚ดํŽด๋ณด๋ฉด, ์›น ์„œ๋ฒ„์— ์š”์ฒญํ•˜๋Š” ๊ฐ€์žฅ ์ผ๋ฐ˜์ ์ธ ๋ฐฉ๋ฒ•์€ ๋ฐ”๋กœ ์›น ๋ธŒ๋ผ์šฐ์ €์˜ ์ฃผ์†Œ์ฐฝ์— URL (Uniform Resource Locator) ์„ ์ž…๋ ฅํ•˜๋Š” ๊ฒƒ์ด๋‹ค

HTTP ๋Š” ๋ฉ”์‹œ์ง€๋ฅผ ๋งŒ๋“ค๊ณ  ํ•ด์„ํ•˜๋ฉฐ, ์‹ค์ œ ๋„คํŠธ์›Œํฌ์˜ ์ „์†ก์€ TCP/IP ํ”„๋กœํ† ์ฝœ์ด ๋‹ด๋‹นํ•œ๋‹ค

๋„คํŠธ์›Œํฌ์ƒ์—์„œ ์‚ฌ์šฉํ•˜๋Š” ์ฃผ์†Œ๋Š” ์ˆซ์ž๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•œ IP ์ฃผ์†Œ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค

 

โ˜‘๏ธ HTTP ์š”์ฒญ ๋ฉ”์‹œ์ง€

HTTP ๋Š” ์‚ฌ๋žŒ์ด ์ดํ•ดํ•˜๊ธฐ ์‰ฌ์šด ํ…์ŠคํŠธ ๊ธฐ๋ฐ˜์œผ๋กœ ์—ฌ๋Ÿฌ ๋ผ์ธ์œผ๋กœ ๊ตฌ์„ฑ๋˜๋Š”๋ฐ, ์š”์ฒญ๊ณผ ์‘๋‹ต ๋ถ€๋ถ„์ด ๋‹ค๋ฅด๋‹ค

์›น ๋ธŒ๋ผ์šฐ์ €์—์„œ ์›น ์„œ๋ฒ„๋กœ ๋ณด๋‚ด๋Š” ์š”์ฒ˜์–ด ๋ฉ”์‹œ์ง€๋Š” ์š”์ฒญ ๋ผ์ธ, ๋ฉ”์‹œ์ง€ ํ—ค๋”, ๋ฉ”์‹œ์ง€ ๋ณธ๋ฌธ์˜ ์„ธ ๋ถ€๋ถ„์œผ๋กœ ๊ตฌ์„ฑ๋œ๋‹ค

 

์š”์ฒญ ๋ผ์ธ์€ <๋ฉ”์†Œ๋“œ><๊ณต๋ฐฑ><URI><HTTP ๋ฒ„์ „>

๋ฉ”์†Œ๋“œ : ์›น ์„œ๋ฒ„์— ์š”์ฒ˜์–ดํ•˜๋Š” ์„œ๋น„์Šค์˜ ์ข…๋ฅ˜ (GET, POST, PUT, HEAD, DELETE)

URI : ์„œ๋ฒ„์— ์š”์ฒญํ•  ์ž์›์˜ ์œ„์น˜๋ฅผ ๋ช…์‹œ

HTTP ๋ฒ„์ „ : ํ†ต์‹ ์— ์‚ฌ์šฉ๋˜๋Š” HTTP ํ”„๋กœํ† ์ฝœ์˜ ๋ฒ„์ „

 

โ˜‘๏ธ HTTP ์‘๋‹ต ๋ฉ”์‹œ์ง€

์›น ํด๋ผ์ด์–ธํŠธ์—์„œ ์›น ์„œ๋ฒ„์— ์š”์ฒญ์ด ๋“ค์–ด์˜ค๋ฉด ์›น ์„œ๋ฒ„๋Š” ํด๋ผ์ด์–ธํŠธ์— ์š”์ฒญํ•œ ์„œ๋น„์Šค์— ๋Œ€ํ•œ ์‘๋‹ต์„ ๋ณด๋‚ธ๋‹ค

์‘๋‹ต ๋ฉ”์‹œ์ง€๋„ ์ƒํƒœ ๋ผ์ธ, ๋ฉ”์‹œ์ง€ ํ—ค๋”, ๋ฉ”์‹œ์ง€ ๋ถ€๋ถ„์˜ ์„ธ ๋ถ€๋ถ„์œผ๋กœ ๋‚˜๋‰œ๋‹ค

 

์ƒํƒœ ๋ผ์ธ์€ <HTTP ๋ฒ„์ „>< ๊ณต๋ฐฑ><์ƒํƒœ ์ฝ”๋“œ><๊ณต๋ฐฑ><์ด์œ  ์„ค๋ช…>

HTTP ๋ฒ„์ „ : ํ†ต์‹ ์— ์‚ฌ์šฉ๋˜๋Š” HTTP ํ”„๋กœํ† ์ฝœ์˜ ๋ฒ„์ „

์ƒํƒœ ์ฝ”๋“œ : ์ ์ ˆํ•œ ๋™์ž‘์„ ์ˆ˜ํ–‰ํ•œ๋‹ค

 

โ˜‘๏ธ HTML ๊ณผ ์›น ํŽ˜์ด์ง€

HTML์€ ์ธํ„ฐ๋„ท์˜ ์›น์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๋ฌธ์„œ๋ฅผ ๋‚˜ํƒ€๋‚ด๊ธฐ ์œ„ํ•ด ๊ฐœ๋ฐœ๋œ ์–ธ์–ด

์›น ํŽ˜์ด์ง€๋Š” HTML ํƒœ๊ทธ์™€ ์ด๋ฏธ์ง€ ๋“ฑ์˜ ๋ฉ€ํ‹ฐ๋ฏธ๋””์–ด๋กœ ์ด๋ฃจ์–ด์ง„ ์›น ๋ธŒ๋ผ์šฐ์ €๋ฅผ ํ†ตํ•ด์„œ ํ‘œํ˜„๋˜๋Š” ๋™์ ์˜ ๋ฌธ์„œ

 

CSS ๋Š” ๊ณ„๋‹จํ˜„ ์Šคํƒ€์ผ์‹œํŠธ๋ผ๊ณ ๋„ ํ•œ๋‹ค

HTML์€ ๋ฌธ์„œ์˜ ์™ธ๊ด€์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์„ ๋ฟ ๋ณด๋‹ค ์„ธ๋ฐ€ํ•œ ์Šคํƒ€์ผ์€ ๋ถ€์—ฌํ•  ์ˆ˜ ์—†๋‹ค

CSS ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํ•˜๋‚˜์˜ CSS ํŒŒ์ผ์„ ์—ฌ๋Ÿฌ HTML ์— ์ ์šฉํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ํ™ˆํŽ˜์ด์ง€ ์ „์ฒด์— ํ†ต์ผ์„ฑ์„ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค

// webserver.c
// HTTP ํ”„๋กœํ† ์ฝœ๊ณผ ์Šค๋ ˆ๋“œ, ์†Œ์ผ“ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ์ด์šฉํ•ด์„œ ์›น ๋ธŒ๋ผ์šฐ์ €์™€ ํ†ต์‹ ํ•  ์ˆ˜ ์žˆ๋Š” ์›น ์„œ๋ฒ„
// ์›น ์„œ๋ฒ„์— ์Šค๋ ˆ๋“œ๋ฅผ ์ด์šฉํ•˜๋ฉด ์—ฌ๋Ÿฌ ์›น ๋ธŒ๋ผ์šฐ์ €์—์„œ ๋™์‹œ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <pthread.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>

/* ์Šค๋ ˆ๋“œ ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•œ ํ•จ์ˆ˜ */
static void *clnt_connection(void *arg);
int sendData(FILE* fp, char *ct, char *filename);
void sendOk(FILE* fp);
void sendError(FILE* fp);

int main(int argc, char **argv)
{
    int ssock;
    pthread_t thread;
    struct sockaddr_in servaddr, cliaddr;
    unsigned int len;

    /* ํ”„๋กœ๊ทธ๋žจ์„ ์‹œ์ž‘ํ•  ๋•Œ ์„œ๋ฒ„๋ฅผ ์œ„ํ•œ ํฌํŠธ ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅ๋ฐ›๋Š”๋‹ค. */
    if(argc!=2) {
        printf("usage: %s <port>\n", argv[0]);
        return -1;
    }

    /* ์„œ๋ฒ„๋ฅผ ์œ„ํ•œ ์†Œ์ผ“์„ ์ƒ์„ฑํ•œ๋‹ค. */
    ssock = socket(AF_INET, SOCK_STREAM, 0);
    if(ssock == -1) {
        perror("socket()");
        return -1;
    }

    /* ์ž…๋ ฅ๋ฐ›๋Š” ํฌํŠธ ๋ฒˆํ˜ธ๋ฅผ ์ด์šฉํ•ด์„œ ์„œ๋น„์Šค๋ฅผ ์šด์˜์ฒด์ œ์— ๋“ฑ๋กํ•œ๋‹ค. */
    memset(&servaddr, 0, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port = (argc != 2)?htons(8000):htons(atoi(argv[1]));
    if(bind(ssock, (struct sockaddr *)&servaddr, sizeof(servaddr))==-1) {
        perror("bind()");
        return -1;
    }
    
    /* ์ตœ๋Œ€ 10๋Œ€์˜ ํด๋ผ์ด์–ธํŠธ์˜ ๋™์‹œ ์ ‘์†์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋„๋ก ํ๋ฅผ ์ƒ์„ฑํ•œ๋‹ค. */
    if(listen(ssock, 10) == -1) {
        perror("listen()");
        return -1;
    }

    while(1) {
        char mesg[BUFSIZ];
        int csock;

        /* ํด๋ผ์ด์–ธํŠธ์˜ ์š”์ฒญ์„ ๊ธฐ๋‹ค๋ฆฐ๋‹ค. */
        len = sizeof(cliaddr);
        csock = accept(ssock, (struct sockaddr*)&cliaddr, &len);

        /* ๋„คํŠธ์›Œํฌ ์ฃผ์†Œ๋ฅผ ๋ฌธ์ž์—ด๋กœ ๋ณ€๊ฒฝ */
        inet_ntop(AF_INET, &cliaddr.sin_addr, mesg, BUFSIZ);
        printf("Client IP : %s:%d\n", mesg, ntohs(cliaddr.sin_port));

        /* ํด๋ผ์ด์–ธํŠธ์˜ ์š”์ฒญ์ด ๋“ค์–ด์˜ค๋ฉด ์Šค๋ ˆ๋“œ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ํด๋ผ์ด์–ธํŠธ์˜ ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•œ๋‹ค. */
        pthread_create(&thread, NULL, clnt_connection, &csock);
        pthread_join(thread, NULL);
    }
    return 0;
}
    
void *clnt_connection(void *arg)
{
    /* ์Šค๋ ˆ๋“œ๋ฅผ ํ†ตํ•ด์„œ ๋„˜์–ด์˜จ arg๋ฅผ int ํ˜•์˜ ํŒŒ์ผ ๋””์Šคํฌ๋ฆฝํ„ฐ๋กœ ๋ณ€ํ™˜ํ•œ๋‹ค. */
    int csock = *((int*)arg);
    FILE *clnt_read, *clnt_write;
    char reg_line[BUFSIZ], reg_buf[BUFSIZ];
    char method[BUFSIZ], type[BUFSIZ];
    char filename[BUFSIZ], *ret;

    /* ํŒŒ์ผ ๋””์Šคํฌ๋ฆฝํ„ฐ๋ฅผ FILE ์ŠคํŠธ๋ฆผ์œผ๋กœ ๋ณ€ํ™˜ํ•œ๋‹ค. */
    clnt_read = fdopen(csock, "r");
    clnt_write = fdopen(dup(csock), "w");

    /* ํ•œ ์ค„์˜ ๋ฌธ์ž์—ด์„ ์ฝ์–ด์„œ reg_line ๋ณ€์ˆ˜์— ์ €์žฅํ•œ๋‹ค. */
    fgets(reg_line, BUFSIZ, clnt_read);
    
    /* reg_line ๋ณ€์ˆ˜์— ๋ฌธ์ž์—ด์„ ํ™”๋ฉด์— ์ถœ๋ ฅํ•œ๋‹ค. */
    fputs(reg_line, stdout);

    /* ' ' ๋ฌธ์ž๋กœ reg_line์„ ๊ตฌ๋ถ„ํ•ด์„œ ์š”์ฒญ ๋ผ์ธ์˜ ๋‚ด์šฉ(๋ฉ”์†Œ๋“œ)๋ฅผ ๋ถ„๋ฆฌํ•œ๋‹ค. */
    ret = strtok(reg_line, "/ ");
    strcpy(method, (ret != NULL)?ret:"");
    if(strcmp(method, "POST") == 0) { 		/* POST ๋ฉ”์†Œ๋“œ์ผ ๊ฒฝ์šฐ๋ฅผ ์ฒ˜๋ฆฌํ•œ๋‹ค. */
        sendOk(clnt_write); 			/* ๋‹จ์ˆœํžˆ OK ๋ฉ”์‹œ์ง€๋ฅผ ํด๋ผ์ด์–ธํŠธ๋กœ ๋ณด๋‚ธ๋‹ค. */
        goto END;
    } else if(strcmp(method, "GET") != 0) {	/* GET ๋ฉ”์†Œ๋“œ๊ฐ€ ์•„๋‹ ๊ฒฝ์šฐ๋ฅผ ์ฒ˜๋ฆฌํ•œ๋‹ค. */
        sendError(clnt_write); 			/* ์—๋Ÿฌ ๋ฉ”์‹œ์ง€๋ฅผ ํด๋ผ์ด์–ธํŠธ๋กœ ๋ณด๋‚ธ๋‹ค. */
        goto END;
    }

    ret = strtok(NULL, " "); 			/* ์š”์ฒญ ๋ผ์ธ์—์„œ ๊ฒฝ๋กœ(path)๋ฅผ ๊ฐ€์ ธ์˜จ๋‹ค. */
    strcpy(filename, (ret != NULL)?ret:"");
    if(filename[0] == '/') { 			/* ๊ฒฝ๋กœ๊ฐ€ '/'๋กœ ์‹œ์ž‘๋  ๊ฒฝ์šฐ /๋ฅผ ์ œ๊ฑฐํ•œ๋‹ค. */
        for(int i = 0, j = 0; i < BUFSIZ; i++, j++) {
            if(filename[0] == '/') j++;
            filename[i] = filename[j];
            if(filename[j] == '\0') break;
        }
    }

    /* ๋ฉ”์‹œ์ง€ ํ—ค๋”๋ฅผ ์ฝ์–ด์„œ ํ™”๋ฉด์— ์ถœ๋ ฅํ•˜๊ณ  ๋‚˜๋จธ์ง€๋Š” ๋ฌด์‹œํ•œ๋‹ค. */
    do {
        fgets(reg_line, BUFSIZ, clnt_read);
        fputs(reg_line, stdout);
        strcpy(reg_buf, reg_line);
        char* buf = strchr(reg_buf, ':');
    } while(strncmp(reg_line, "\r\n", 2)); 	/* ์š”์ฒญ ํ—ค๋”๋Š” ‘\r\n’์œผ๋กœ ๋๋‚œ๋‹ค. */

    /* ํŒŒ์ผ์˜ ์ด๋ฆ„์„ ์ด์šฉํ•ด์„œ ํด๋ผ์ด์–ธํŠธ๋กœ ํŒŒ์ผ์˜ ๋‚ด์šฉ์„ ๋ณด๋‚ธ๋‹ค. */
    sendData(clnt_write, type, filename);

END:
    fclose(clnt_read); 				/* ํŒŒ์ผ์˜ ์ŠคํŠธ๋ฆผ์„ ๋‹ซ๋Š”๋‹ค. */
    fclose(clnt_write);
    pthread_exit(0); 				/* ์Šค๋ ˆ๋“œ๋ฅผ ์ข…๋ฃŒ์‹œํ‚จ๋‹ค. */

    return (void*)NULL;
}
    
int sendData(FILE* fp, char *ct, char *filename)
{
    /* ํด๋ผ์ด์–ธํŠธ๋กœ ๋ณด๋‚ผ ์„ฑ๊ณต์— ๋Œ€ํ•œ ์‘๋‹ต ๋ฉ”์‹œ์ง€ */
    char protocol[ ] = "HTTP/1.1 200 OK\r\n";
    char server[ ] = "Server:Netscape-Enterprise/6.0\r\n";
    char cnt_type[ ] = "Content-Type:text/html\r\n";
    char end[ ] = "\r\n"; 			/* ์‘๋‹ต ํ—ค๋”์˜ ๋์€ ํ•ญ์ƒ \r\n */
    char buf[BUFSIZ];
    int fd, len;

    fputs(protocol, fp);
    fputs(server, fp);
    fputs(cnt_type, fp);
    fputs(end, fp);

    fd = open(filename, O_RDWR); 		/* ํŒŒ์ผ์„ ์—ฐ๋‹ค. */
    do {
        len = read(fd, buf, BUFSIZ); 		/* ํŒŒ์ผ์„ ์ฝ์–ด์„œ ํด๋ผ์ด์–ธํŠธ๋กœ ๋ณด๋‚ธ๋‹ค. */
        fputs(buf, fp);
    } while(len == BUFSIZ);

    close(fd); 					/* ํŒŒ์ผ์„ ๋‹ซ๋Š”๋‹ค. */

    return 0;
}
    
void sendOk(FILE* fp)
{
    /* ํด๋ผ์ด์–ธํŠธ์— ๋ณด๋‚ผ ์„ฑ๊ณต์— ๋Œ€ํ•œ HTTP ์‘๋‹ต ๋ฉ”์‹œ์ง€ */
    char protocol[ ] = "HTTP/1.1 200 OK\r\n";
    char server[ ] = "Server: Netscape-Enterprise/6.0\r\n\r\n";

    fputs(protocol, fp);
    fputs(server, fp);
    fflush(fp);
}
    
void sendError(FILE* fp)
{
    /* ํด๋ผ์ด์–ธํŠธ๋กœ ๋ณด๋‚ผ ์‹คํŒจ์— ๋Œ€ํ•œ HTTP ์‘๋‹ต ๋ฉ”์‹œ์ง€ */
    char protocol[ ] = "HTTP/1.1 400 Bad Request\r\n";
    char server[ ] = "Server: Netscape-Enterprise/6.0\r\n";
    char cnt_len[ ] = "Content-Length:1024\r\n";
    char cnt_type[ ] = "Content-Type:text/html\r\n\r\n";

    /* ํ™”๋ฉด์— ํ‘œ์‹œ๋  HTML์˜ ๋‚ด์šฉ */
    char content1[ ] = "<html><head><title>BAD Connection</title></head>";
    char content2[ ] = "<body><font size=+5>Bad Request</font></body></html>";
    printf("send_error\n");

    fputs(protocol, fp);
    fputs(server, fp);
    fputs(cnt_len, fp);
    fputs(cnt_type, fp);
    fputs(content1, fp);
    fputs(content2, fp);
    fflush(fp);
}

/*
๋ฉ”์ธ ํ•จ์ˆ˜ : ์„œ๋ฒ„๋ฅผ ์ดˆ๊ธฐํ™”ํ•˜๊ณ  ํด๋ผ์ด์–ธํŠธ ์š”์ฒญ์ด ๋“ค์–ด์˜ค๋ฉด ์Šค๋ ˆ๋“œ๋ฅผ ์ƒ์„ฑ
์Šค๋ ˆ๋“œ ์ฒ˜๋ฆฌ ํ•จ์ˆ˜์—์„œ๋Š” ํด๋ผ์ด์–ธํŠธ์—์„œ ๋ฉ”์‹œ์ง€๋ฅผ ์ฝ๊ณ  HTTP ํ—ค๋”๋ฅผ ๋ถ„์„ํ•˜์—ฌ ํ•ด๋‹น ๋‚ด์šฉ์„ ์ฒ˜๋ฆฌํ•œ๋‹ค

ํด๋ผ์ด์–ธํŠธ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์š”์ฒญํ•˜๋ฉด sendData() ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๊ณ  ํŒŒ์ผ์„ ์ฝ์–ด์„œ ํ•ด๋‹น ๋ฐ์ดํ„ฐ๋ฅผ ํด๋ผ์ด์–ธํŠธ๋กœ ๋ณด๋‚ธ๋‹ค
sendOK() ํ•จ์ˆ˜๋Š” ์š”์ฒ˜์–ด๋œ ๋‚ด์šฉ์— ๋ฌธ์ œ๊ฐ€ ์—†๊ณ  ๋‹จ์ˆœ ์š”์ฒญ์ธ ๊ฒฝ์šฐ ์ด๋ฅผ ์ฒ˜๋ฆฌํ•˜์—ฌ ์ƒํƒœ ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด๋‚ธ๋‹ค
sendError() ํ•จ์ˆ˜๋Š” ์š”์ฒญ๋œ ๋‚ด์šฉ์— ๋ฌธ์ œ๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ ์—๋Ÿฌ ์‘๋‹ต ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด๋‚ธ๋‹ค

main() ํ•จ์ˆ˜์—์„œ๋Š” ์›น ์„œ๋น„์Šค๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ์†Œ์ผ“์„ ์ƒ์„ฑํ•˜๊ณ  ์šด์˜์ฒด์ œ์— ์„œ๋น„์Šค๋ฅผ ๋“ฑ๋กํ•œ๋‹ค
์„œ๋ฒ„์˜ ์ฃผ์†Œ์— INADDR_ANY ๊ฐ’์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ„๋‹จํžˆ ์„œ๋ฒ„ ์ฃผ์†Œ๋ฅผ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๊ณ , ์ž…๋ ฅ๋ฐ›์€ ํฌํŠธ ๋ฒˆํ˜ธ๋ฅผ ์ด์šฉํ•œ๋‹ค
์ตœ๋Œ€ 10๋Œ€์˜ ํด๋ผ์ด์–ธํŠธ์˜ ๋™์‹œ ์ ‘์†์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋„๋ก ๋Œ€๊ธฐ ํ๋ฅผ ์ƒ์„ฑํ•œ ํ›„ ํด๋ผ์ด์–ธํŠธ๋ฅผ ๊ธฐ๋‹ค๋ฆฐ๋‹ค

ํด๋ผ์ด์–ธํŠธ์˜ ์š”์ฒญ์ด ๋“ค์–ด์˜ค๋ฉด ์ ‘์†๋œ ํด๋ผ์ด์–ธํŠธ์˜ ์ •๋ณด๋ฅผ ์ถœ๋ ฅํ•˜๊ณ  ์ƒˆ๋กœ์šด ์Šค๋ ˆ๋“œ๋ฅด ์ƒ์„ฑํ•œ๋‹ค
์Šค๋ ˆ๋“œ๋ฅผ ์ƒ์„ฑํ•  ๋•Œ ์ƒˆ๋กœ ๋“ค์–ด์˜จ ํด๋ผ์ด์–ธํŠธ์˜ ์†Œ์ผ“์„ ์Šค๋ ˆ๋“œ์˜ ์ธ์ž๋กœ ๋„˜๊ฒจ, ์Šค๋ ˆ๋“œ ์ฒ˜๋ฆฌ ํ•จ์ˆ˜์—์„œ ํ•ด๋‹น ํด๋ผ์ด์–ธํŠธ์™€ ํ†ต์‹ ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•จ

clnt_connection() ํ•จ์ˆ˜๋Š” ํด๋ผ์ด์–ธํŠธ์˜ ์ ‘์†์„ ์ฒ˜๋ฆฌํ•˜๋Š” ํ•จ์ˆ˜
ํด๋ผ์ด์–ธํŠธ ์†Œ์ผ“์„ ์Šค๋ ˆ๋“œ์˜ ์ธ์ž๋กœ ๋„˜๊ฒจ๋ฐ›์•„์„œ int ํ˜•์˜ ํŒŒ์ผ ๋””์Šคํฌ๋ฆฝํ„ฐ๋กœ ๋ณ€ํ™˜ํ•œ ํ›„, ๋‹ค์‹œ fdopen() ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด ํŒŒ์ผ ์ŠคํŠธ๋ฆผ์œผ๋กœ ๋ณ€ํ™˜ํ•œ๋‹ค
HTTP์˜ ํ—ค๋”๋“ค์€ ์ค„ ๋‹จ์œ„๋กœ ์ฒ˜๋ฆฌ๋˜๋Š”๋ฐ, ํŒŒ์ผ ์ŠคํŠธ๋ฆผ์„ ์ค„ ๋‹จ์œ„๋กœ ์ฒ˜๋ฆฌํ•˜๋Š” fgets() ํ•จ์ˆ˜๋กœ ์‚ฌ์šฉํ•˜๋ฉด ํŽธ๋ฆฌํ•˜๋‹ค

๋จผ์ € HTTP ์š”์ฒญ ๋ผ์ธ์„ ์ฝ๊ณ  ๋ถ„์„ํ•œ๋‹ค. ์š”์ฒญ ๋ผ์ธ์€ ๋ฉ”์†Œ๋“œ, ๊ฒฝ๋กœ, HTTP ๋ฒ„์ „์œผ๋กœ ๊ตฌ์„ฑ๋จ
๋ฌธ์ž์—ด์€ strtok() ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•ด์„œ ๋ถ„์„ํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ ๊ณต๋ฐฑ์„ ์ธ์ž๋กœ ์‚ฌ์šฉํ•ด์„œ ๋ถ„๋ฆฌํ•œ๋‹ค

์š”์ฒญ ๋ผ์ธ์˜ ์ฒซ ๋ฒˆ์žฌ ์š”์†Œ๋Š” ๋ฉ”์†Œ๋“œ, POST ๋ฉ”์†Œ๋“œ์— ๋Œ€ํ•ด์„œ๋Š” ๊ฐ„๋‹จํ•˜๊ฒŒ ํ™•์ธ ์‘๋‹ต๋งŒ ํด๋ผ์ด์–ธํŠธ๋กœ ๋ณด๋‚ด๊ณ , GET ๋ฉ”์†Œ๋“œ์— ๋Œ€ํ•ด์„œ๋Š” ์š”์ฒญํ•œ ๊ฒฝ๋กœ์˜ ํŒŒ์ผ์„
์ฝ์–ด์„œ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ๋ณด๋‚ด์ค€๋‹ค
ํ˜„์žฌ์˜ ์›น ์„œ๋ฒ„๋Š” GET, POST ๋ฉ”์†Œ๋“œ๋งŒ ์ฒ˜๋ฆฌํ•˜๋Š”๋ฐ, ํด๋ผ์ด์–ธํŠธ์ด ๋‘ ๋ฉ”์†Œ๋“œ๊ฐ€ ์•„๋‹Œ ๊ฒฝ์šฐ์—๋Š” ์—๋Ÿฌ ๋ฉ”์‹œ์ง€๋ฅผ ํด๋ผ์ด์–ธํŠธ๋กœ ๋ณด๋‚ธ๋‹ค

์š”์ฒญ ๋ผ์ธ ๋’ค์—๋Š” ๋ฉ”์‹œ์ง€ ํ—ค๋”๊ฐ€ ์˜ค๋Š”๋ฐ ์•ž์˜ ์›น ์„œ๋ฒ„์—์„œ๋Š” ์ด๋ฅผ ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ C์–ธ์–ด์˜ ์ˆœํ™˜๋ฌธ์„ ํ†ตํ•ด์„œ ์ „๋ถ€ ๋ฌด์‹œํ•œ๋‹ค
๋ฉ”์‹œ์ง€ ๋ณธ๋ฌธ์œผ๋กœ ์˜ค๋Š” ๋ฌธ์„œ์˜ ํฌ๊ธฐ๋ฅผ ์•Œ๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ, Content-Length ํ•ญ๋ชฉ์„ ์‚ฌ์šฉํ•˜๋ฉด ๋˜๋Š”๋ฐ, ๊ด€๋ จ ์‚ฌํ•ญ์€ ์ˆœํ™˜๋ฌธ ์•ˆ์— ๊ตฌํ˜„ํ•˜๋ฉด ๋œ๋‹ค
์š”์ฒญ ํ—ค๋”๋Š” '\r\n' ์œผ๋กœ ๋๋‚˜๊ณ  ํ—ค๋”์™€ ๋ฉ”์‹œ์ง€ ๋ณธ๋ฌธ์„ ๊ตฌ๋ถ„ํ•œ๋‹ค
ํด๋ผ์ด์–ธํŠธ์— ๋Œ€ํ•œ ์ฒ˜๋ฆฌ๊ฐ€ ๋๋‚˜๋ฉด ์ŠคํŠธ๋ฆผ์„ ๋‹ซ๊ณ  ์Šค๋ ˆ๋“œ๋ฅผ ์ข…๋ฃŒํ•œ๋‹ค
sendData() ํ•จ์ˆ˜๋Š” ์š”์ฒญํ•œ ํŒŒ์ผ์„ ์—ด์–ด ๋‚ด์šฉ์„ ์ฝ๊ณ  ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ๋ณด๋‚ธ๋‹ค. ํŒŒ์ผ ๋‚ด์šฉ์„ ๋ณด๋‚ด๊ธฐ ์ „์— HTTP ์— ๋Œ€ํ•œ ์‘๋‹ต ํ—ค๋”๋ฅผ ๋ณด๋‚ด๋ฉฐ
๊ทธ ๋’ค์— ํŒŒ์ผ ๋‚ด์šฉ์„ ํ•จ๊ป˜ ๋ณด๋‚ธ๋‹ค. ํŒŒ์ผ์˜ ์‚ฌ์š”์ด ๋๋‚˜๋ฉด ์—ด์—ฟ๋˜ ํŒŒ์ผ์„ ๋‹ซ๊ณ  ํ•จ์ˆ˜๋ฅผ ์ข…๋ฃŒํ•œ๋‹ค

-lpthread ์˜ต์…˜์„ ์ค˜์„œ ์Šค๋ ˆ๋“œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋ณ„๋„๋กœ ๋งํฌํ•ด์•ผ ํ•œ๋‹ค
์›น ์„œ๋ฒ„ ์‹คํ–‰ ์‹œ, ์›น ์„œ๋น„์Šค์—์„œ ์‚ฌ์šฉํ•  ํฌํŠธ ๋ฒˆํ˜ธ๋ฅผ ์ง€์ •ํ•œ๋‹ค

index.html ๊ณผ ํ•จ๊ป˜ ์‹คํ–‰ํ•œ๋‹ค

gani@gani:~/raspi/NetworkProgramming $ gcc -o webserver webserver.c -lpthread
gani@gani:~/raspi/NetworkProgramming $ ./webserver 8080
*/
<HTML>

<HEAD>
    <TITLE>Hello World</TITLE>
</HEAD>

<BODY>
    <H1>Hello World!</H1>
</BODY>

</HTML>
gcc -o webserver webserver.c -lpthread
./webserver 8080

 

โ˜‘๏ธ ๋ถ€ํŒ… ์‹œ ์›น ์„œ๋ฒ„์˜ ์‹คํ–‰

์›น ์„œ๋ฒ„๋ฅผ ๋ผ์ฆˆ๋ฒ ๋ฆฌ ํŒŒ์ด์˜ ๋ถ€ํŒ… ์‹œ ์‹คํ–‰ํ•˜๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋‹ค

์ด๋ฅผ ์œ„ํ•ด systemd ์™€ ํ•จ๊ฒŒ ์›น ์„œ๋ฒ„๋ฅผ ์‹คํ–‰ํ•˜๊ฒŒ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค

์„œ๋น„์Šค ํŒŒ์ผ์„ systemd ์˜ ์„ค์ • ๋””๋ ‰ํ„ฐ๋ฆฌ์ธ /etc/systemd/system ์— ์ž‘์„ฑํ•œ๋‹ค

 

์‹œ์Šคํ…œ ๋ถ€ํŒ… ๊ณผ์ •์—์„œ systemd ๋ฐ๋ชฌ์„ ์‹คํ–‰ํ•œ๋‹ค. ์ด ๋ฐ๋ชฌ์ด ์‹คํ–‰๋˜๋ฉด์„œ ๊ด€๋ จ ์„œ๋น„์Šค๋ฅผ ์‹œ์ž‘ํ•˜๋„๋ก ํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ, ๊ด€๋ จ ํŒŒ์ผ์„ ๋งŒ๋“ค์–ด์„œ systemd ์— ๋“ฑ๋กํ•ด์„œ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

 

728x90
๋ฐ˜์‘ํ˜•
Comments