๐ ๊ณต๋ถํ๋ ์ง์ง์ํ์นด๋ ์ฒ์์ด์ง?
[๋ฆฌ๋ ์ค ๋คํธ์ํฌ ํ๋ก๊ทธ๋๋ฐ] HTTP์ ์น ์๋ฒ ํ๋ก๊ทธ๋๋ฐ ๋ณธ๋ฌธ
[๋ฆฌ๋ ์ค ๋คํธ์ํฌ ํ๋ก๊ทธ๋๋ฐ] HTTP์ ์น ์๋ฒ ํ๋ก๊ทธ๋๋ฐ
์ง์ง์ํ์นด 2024. 2. 10. 00:14<์์์ง ๋์ ์ฌ๋ฌผ์ธํฐ๋ท์ ์ํ ๋ฆฌ๋ ์ค ํ๋ก๊ทธ๋๋ฐ 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 ์ ๋ฑ๋กํด์ ์ฌ์ฉํ๋ฉด ๋๋ค.