HTTP
์น ๋ธ๋ผ์ฐ์ ์ ์น ์๋ฒ ์ฌ์ด์์ HTML ๋ฌธ์ ๋ฑ์ ์ ์กํ ๋ ์ฌ์ฉํ๋ ํ๋กํ ์ฝ
์น ๋ธ๋ผ์ฐ์ ๊ฐ ์น ์๋ฒ์ ์ฐ๊ฒฐํด์ HTTP ํ๋กํ ์ฝ์ ๊ท์ฝ์ ๋ฐ๋ผ HTML ๋ฌธ์๋ฅผ ์์ฒญํ๋ฉด ์น์๋ฒ๋ ์ด ์์ฒญ์ ๋ถ์ํ ํ ์น ๋ธ๋ผ์ฐ์ ๋ก ํด๋นํ๋ HTML ๋ฌธ์๋ฅผ ๋ฐํํ์ฌ ์๋ตํ๋ค.
์น ๋ธ๋ผ์์ ๋ ์น ์๋ฒ๋ก๋ถํฐ ๋ฐ์ HTML ๋ฌธ์๋ฅผ ํด์ํด์ GUI๋ฅผ ํตํด ์ฌ์ฉ์์๊ฒ ๋ณด๋ด์ค๋ค.
์ถ์ฒ ์น์ ๊ตฌ๋์๋ฆฌ
์น ๋ธ๋ผ์ฐ์ ๋ URL(Uniform Resource Locator)์ ๋ช ์๋ ์๋ฒ์ ์ฃผ์๋ก ์ฐ๊ฒฐํ๋ค. ์ฐ๊ฒฐํ ์๋ฒ์ ํฌํธ ๋ฒํธ๊ฐ ๋ช ์๋์ด ์์ผ๋ฉด ํด๋น ํฌํธ๋ก ์ฐ๊ฒฐ์ ์์ฒญํ๊ณ , ๊ทธ๋ ์ง ์์ผ๋ฉด 80๋ฒ ํฌํธ๋ก ์ฐ๊ฒฐ์ ์์ฒญํ๋ค.
์น ๋ธ๋ผ์ฐ์ ์ ์น ์๋ฒ ์ฌ์ด์ ํต์ ์ฑ๋์ด ์ฐ๊ฒฐ๋๋ฉด, ์น ๋ธ๋ผ์ฐ์ ๋ ๋ด๋ถ์ ์ผ๋ก HTTP ๊ท์ฝ์ ๋ฐ๋ฅด๋ ์์ฒญ ๋ฉ์์ง(Request Message)๋ฅผ ์์ฑํด์ ์น ์๋ฒ๋ก ์ ์กํ๋ค. ์์ฒญ ๋ฉ์์ง๋ ์์ฒญ๋ผ์ธ, ์์ฒญ ํค๋, ๋ฐ๋ ๋ฑ์ผ๋ก ๊ตฌ์ฑ
์น ์๋ฒ๋ ์น ๋ธ๋ผ์ฐ์ ๋ก๋ถํฐ์ ์์ฒญ ๋ฉ์์ง๋ฅผ ๋ถ์ํ๊ณ ํด๋นํ๋ ๋ฌธ์๋ฅผ ์ฐพ๋๋ค. HTTP ๊ท์ฝ์ ๋ถํฉํ๋ ์๋ต ๋ฉ์์ง๋ฅผ ๊ตฌ์ฑํด์ ์น ๋ธ๋ผ์ฐ์ ์๊ฒ ์ ์กํ๋ค. ์๋ต ๋ฉ์์ง๋ ์ํ๋ผ์ธ, ์๋ต ํค๋, ๋ฐ๋ ๋ฑ์ผ๋ก ๊ตฌ์ฑ๋๋ค. ์ฌ๊ธฐ์ ์๋ต ํค๋๋ ์ฑ๊ณต/์คํจ ์ฌ๋ถ, ์ ์กํ ๋ฐ์ดํฐ ์ ํ ๋ฑ์ผ๋ก ๊ตฌ์ฑ๋๋ฉฐ, ์ค์ ๋ฐ์ดํฐ๋ ์๋ต ํค๋์ ์ด์ด์ ์ ์กํ๋ค.
์น ์๋ฒ๋ ์๋ต ๋ฉ์์ง๋ฅผ ์ ์กํ ์งํ, ๊ฐ์ ๋ก ์ฐ๊ฒฐ์ ์ข ๋ฃํ๋ค.
์น ๋ธ๋ผ์ฐ์ ๋ ์น ์๋ฒ๊ฐ ์ ์กํ ์๋ต ๋ฉ์์ง๋ฅผ ๋ถ์ํด์ ์น ๋ธ๋ผ์ฐ์ ๋ฅผ ํตํด ์ฌ์ฉ์์๊ฒ ๋ณด์ฌ์ค๋ค.
๋ง์ผ ์น ์๋ฒ๊ฐ ์ ์กํ ์๋ต ๋ฉ์์ง์ ๋ค์๊ณ ๊ฐ์ด ์ด๋ฏธ์ง ํ์ผ๊ณผ ๊ฐ์ ์ฐธ์กฐ๊ฐ ์์ผ๋ฉด ์น ๋ธ๋ผ์ฐ์ ๋ ์๋ฒ์ ๋ค์ ์์ฒญํด์ ์ด ํ์ผ์ ๋ฐ์ ์จ๋ค. ์ด๋ ์น ๋ธ๋ผ์ฐ์ ๋ ์น ์๋ฒ๋ก ๋ค์ ์ฐ๊ฒฐํ๊ฒ ๋๊ณ , ๋ฐ์ ๋ค์์์ผ ๋น๋ก์ ์น ๋ธ๋ผ์ฐ์ ๋ก ์ถ๋ ฅํ๋ค.
ex)
<img src ="image.jpg">
- HTML ๋ฌธ์์ 10๊ฐ์
ํ๊ทธ๊ฐ ์๋ค๋ฉด, HTML ๋ฌธ์์ ๋ํ ์์ฒญ 1ํ, ์ด๋ฏธ์ง ํ์ผ์ ๋ํ ์์ฒญ 10ํ๋ฅผ ํฌํจ, ์ด 11ํ ์น ์๋ฒ์ ์ฐ๊ฒฐํด์ ํ์ผ์ ๋ฐ์์ผ ํ๋ค. ๊ทธ๋์ผ๋ง ํด๋น ๋ฌธ์๋ฅผ ์ถ๋ ฅํ ์ ์๋ค.
- ํ์ผ์ ๋ฐ๊ธฐ ์ํด์ ์ด๋ฃจ์ด์ง๋ ์๋ฒ์์ ์ฐ๊ฒฐ๊ณผ ์๋ฃ ์ก์์ ์ ํธ๋์ญ์
์ด๋ผ ํ๋๋ฐ, ์์์ ์ด 11ํ์ ํธ๋์ญ์
์ด ์ด๋ฃจ์ด์ง๊ฒ ๋๋ค.
์น ์๋ฒ์ ๊ตฌํ
- ์๋ฒ๋ GET ๋ฐฉ์์ ์์ฒญ๋ง์ ์ฒ๋ฆฌ
- ๋ค์๊ณผ ๊ฐ์ ํ์์ ํ์ผ์ ๋ํด ์๋น์ค๋ฅผ ์ ๊ณต
- ์ ์ ์น ํ์ด์ง(html, htm), ์ด๋ฏธ์ง ํ์ผ(gif, png, jpg, jpeg), ์์ถ ์ด์ง ํ์ผ์ด๋ ์์นด์ด๋ธ(zip, gz, tar)
- HTML ๋ฌธ์์ 10๊ฐ์
ํ๋ก๊ทธ๋จ ๊ตฌํ ๊ณผ์
- 1 ์น ๋ธ๋ผ์ฐ์ ๋ก ์ํ์น ์น ์๋ฒ์ ์ฐ๊ฒฐํ๋ค. HTTP ๊ท์ฝ์ ๋ฐ๋ผ ์น ์๋ฒ๋ก index.html ํ์ผ์ ์์ฒญํ๊ณ , ์ด๋ฅผ ๋ฐ์ ์น ๋ธ๋ผ์ฐ์ ๋ก ์ถ๋ ฅํ๋ ๊ณผ์
- url : http//127.0.0.1/index.html
- 2 ์น ๋ธ๋ผ์ฐ์ ๋์ ์ ์์์์ telnet ๋ช
๋ น์ผ๋ก ์ํ์น ์น ์๋ฒ์ ์ฐ๊ฒฐํ๊ณ , http ๊ท์ฝ์ ๋ฐ๋ผ ์น ์๋ฒ๋ก index.html ํ์ผ์ ์์ฒญํ๊ณ , ์๋ฒ์ ์๋ต์ ๊ด์ฐฐํ๋ค.
$ telnet 127.0.9.1 80
GET / index.html HTTP/1.0
- 3 HTTP ๊ท์ฝ์ผ๋ก ์น ์๋ฒ์ ์น ๋ฌธ์๋ฅผ ์์ฒญํ๋ ์น ํ๋ก๊ทธ๋จ์ ์ง์ ๊ตฌํํ๊ณ , ์ํ์น ์น ์๋ฒ์ ์ฐ๊ฒฐํด์ ์น ๋ฌธ์๋ฅผ ์์ฒญํ๊ณ ๋ฐ๋ ๊ณผ์ ์ ๊ด์ฐฐ
- 4 HTTP ๊ท์ฝ์ ๋ฐ๋ฅธ ์์ฒญ์ ์ฒ๋ฆฌํ๋ ์น ์๋ฒ ํ๋ก๊ทธ๋จ์ ์ง์ ๊ตฌํํ์ฌ 9000๋ฒ ํฌํธ์ ์ฐ๊ฒฐํด์ ์คํ ํ, ์น ์๋ฒ์ ๊ธฐ๋ณธ ๋์์ด ์ ๋๋ก ๊ตฌ๋๋๋์ง ์์์์ telnet ๋ช ๋ น์ผ๋ก ๊ฒ์ฆํ๋ค.
- 5 ์ฐ๋ฆฌ๊ฐ ๊ตฌํํ ์น ํด๋ผ์ด์ธํธ์ ์น ์๋ฒ ํ๋ก๊ทธ๋จ์ผ๋ก HTTP ๊ท์ฝ์ ๋ฐ๋ผ ์น ๋ฌธ์๋ฅผ ์์ฒญํ๊ณ ์๋ต์ ๊ด์ฐฐ
- 6 ์น ๋ธ๋ผ์ฐ์ ์์ ์ฐ๋ฆฌ๊ฐ ๊ตฌํํ ์น ์๋ฒ๋ก HTTP ๊ท์ฝ์ ๋ฐ๋ผ ์์ฒญ์ ๋ณด๋ด๊ณ , ์ฒ๋ฆฌํ๋ ๊ณผ์ ์ ๊ด์ฐฐ
$ yum install httpd
๋ก ์ค์น
ํ ๋๋ ํ ๋ฆฌ
- ์น ์๋ฒ์ ํ ๋๋ ํ ๋ฆฌ๋ ํ๊ฒฝ ๋ณ์ ServerRoot์ ์ค์ ๋์ด ์๋ค. grep ๋ช
๋ น์ด๋ฅผ ์ด์ํ์ฌ ServerRoot๊ฐ ์ค์ ๋์ด ์๋ ๊ฒฝ๋ก๋ฅผ ์ ์ ์๋ค.
- ์น ์๋ฒ์ Listen ํฌํธ๋ ์ ์ ์๋ค.
๋ฌธ์ ํ์ผ์ ํ ๋๋ ํ ๋ฆฌ
ํ ๋ท์ ์ด์ฉํ์ฌ ์ํ์น ์น ์๋ฒ์ ์น ๋ฌธ์ ์์ฒญ
- ํ
๋ท์ผ๋ก 127.0.0.1์ 80๋ฒ ํฌํธ๋ก ์ฐ๊ฒฐํ๊ณ , HTTP ๊ท์ฝ์ ๋ฐ๋ผ
GET /inde.html HTTP/1.0\r\n\r\n
๊ณผ ๊ฐ์ ๋ฌธ์ ์์ฒญ ๋ฉ์์ง๋ฅผ ์น์๋ฒ๋ก ์ ์กํ๋ฉด ์น์๋ฒ๋ ํ๊ฒฝ ๋ณ์ DocumentRoot์ ์ค์ ๋ ๋ฌธ์ ํ์ผ ํ ๋๋ ํ ๋ฆฌ์์ ํด๋น ํ์ผ ๋ฌธ์(/usr/local/apache/htdocs/index.html)๋ฅผ ์ฝ์ด์ ํด๋ผ์ด์ธํธ์๊ฒ ๋ณด๋ด์ค๋ค. - telnet ๋ช
๋ น์ผ๋ก ์ํ์น ์น ์๋ฒ์ HTML ๋ฌธ์๋ฅผ ์์ฒญํ ๊ฒฐ๊ณผ
webServer.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/resource.h>
#include <netinet/in.h>
#include <signal.h>
#include <sys/stat.h>
#define LOG 100
#define ERROR 200
#define CODE200 200
#define CODE404 404
#define PHRASE200 "OK"
#define PHRASE404 "FILE NOT FOUND"
char documentRoot[ ] = "/etc/httpd/htdocs";
void do_web(int);
void web_log(int, char[ ], char[ ], int);
int log_fd;
int
main(int argc, char *argv[ ]) {
struct sockaddr_in s_addr, c_addr;
int s_sock, c_sock;
int len, len_out;
unsigned short port;
int status;
struct rlimit resourceLimit;
int i;
int pid;
if(argc != 2){
printf("usage: webServer port_number");
return -1;
}
if(fork( ) != 0)
return 0; // parent return to shell
(void)signal(SIGCLD, SIG_IGN); // ignore child death
(void)signal(SIGHUP, SIG_IGN); // ignore terminal hangup
resourceLimit.rlim_max = 0;
status = getrlimit(RLIMIT_NOFILE, &resourceLimit);
for(i = 0; i < resourceLimit.rlim_max; i++) {
close(i);
}
web_log(LOG, "STATUS", "web server start", getpid( ));
if((s_sock=socket(PF_INET, SOCK_STREAM, 0))<0){
web_log(ERROR, "SYSCALL", "web server listen sockek open error", s_sock);
}
port=atoi(argv[1]);
if(port > 60000)
web_log(ERROR, "ERROR", "invalid port number", port);
memset(&s_addr, 0, sizeof(s_addr));
s_addr.sin_family = AF_INET;
s_addr.sin_addr.s_addr = htonl(INADDR_ANY);
s_addr.sin_port = htons(port);
if(bind(s_sock, (struct sockaddr *) &s_addr, sizeof(s_addr)) <0)
web_log(ERROR, "ERROR", "server cannot bind", 0);
listen(s_sock, 10);
while(1){
len = sizeof(c_addr);
if((c_sock = accept(s_sock, (struct sockaddr *) &c_addr, &len)) < 0)
web_log(ERROR, "ERROR", "server accept error", 0);
if((pid = fork( )) < 0) {
web_log(ERROR, "ERROR", "server fork error", 0);
} else if(pid == 0) {
close(s_sock);
do_web(c_sock);
} else {
close(c_sock);
}
}
}
void
do_web(int c_sock)
{
char sndBuf[BUFSIZ+1], rcvBuf[BUFSIZ+1];
char uri[100], c_type[20];;
int len;
int len_out;
int n, i;
char *p;
char method[10], f_name[20];
char phrase[20] = "OK";
int code = 200;
int fd; // file discriptor
char file_name[20];
char ext[20];
struct stat sbuf;
struct {
char *ext;
char *filetype;
} extensions [ ] = {
{"gif", "image/gif" },
{"jpg", "image/jpeg"},
{"jpeg","image/jpeg"},
{"png", "image/png" },
{"zip", "image/zip" },
{"gz", "image/gz" },
{"tar", "image/tar" },
{"htm", "text/html" },
{"html","text/html" },
{0,0} };
memset(rcvBuf, 0, sizeof(rcvBuf));
if((n = read(c_sock, rcvBuf, BUFSIZ)) <= 0)
web_log(ERROR, "ERROR", "can not receive data from web browser", n);
web_log(LOG, "REQUEST", rcvBuf, n);
p = strtok(rcvBuf, " ");
if(strcmp(p, "GET") && strcmp(p, "get"))
web_log(ERROR, "ERROR", "Only get method can support", 0);
p = strtok(NULL, " ");
if(!strcmp(p, "/"))
sprintf(uri, "%s/index.html", documentRoot);
else
sprintf(uri, "%s%s", documentRoot, p);
strcpy(c_type, "text/plain");
for(i=0; extensions[i].ext != 0; i++) {
len = strlen(extensions[i].ext);
if( !strncmp(uri+strlen(uri)-len, extensions[i].ext, len) ) {
strcpy(c_type, extensions[i].filetype);
break;
}
}
if((fd = open(uri, O_RDONLY)) < 0) {
code = CODE404;
strcpy(phrase, PHRASE404);
}
p = strtok(NULL, "\r\n "); // version
// send Header
sprintf(sndBuf, "HTTP/1.0 %d %s\r\n", code, phrase);
n = write(c_sock, sndBuf, strlen(sndBuf));
web_log(LOG, "RESPONSE", sndBuf, getpid( ));
sprintf(sndBuf, "content-type: %s\r\n\r\n", c_type);
n = write(c_sock, sndBuf, strlen(sndBuf));
web_log(LOG, "RESPONSE", sndBuf, getpid( ));
if(fd >=0 ) {
while((n = read(fd, rcvBuf, BUFSIZ)) > 0) {
write(c_sock, rcvBuf, n);
}
}
close(c_sock);
exit(-1);
}
void
web_log(int type, char s1[ ], char s2[ ], int n)
{
int log_fd;
char buf[BUFSIZ];
if(type == LOG) {
sprintf(buf, "STATUS %s %s %d\n", s1, s2, n);
} else if(type == ERROR) {
sprintf(buf, "ERROR %s %s %d\n", s1, s2, n);
}
if((log_fd = open("web.log", O_CREAT|O_WRONLY|O_APPEND, 0644)) >= 0) {
write(log_fd, buf, strlen(buf));
close(log_fd);
}
if(type == ERROR) exit(-1);
}
webClient.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#define BUF_LEN 128
int main(int argc, char *argv[ ])
{
int s, n, len_in, len_out;
struct sockaddr_in server_addr;
char *haddr;
char buf[BUF_LEN+1];
int port;
if(argc==3) {
port=80;
} else if(argc==4) {
port=atoi(argv[3]);
} else {
printf("usage : webClient server_addr URL [port_number]");
return -1;
}
haddr=argv[1];
if((s=socket(PF_INET, SOCK_STREAM, 0)) < 0) {
printf("can not create socket\n");
return -1;
}
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family=AF_INET;
server_addr.sin_addr.s_addr=inet_addr(haddr);
server_addr.sin_port=htons(port);
if(connect(s, (struct sockaddr *) &server_addr, sizeof(server_addr)) < 0) {
printf("can not connect");
return -1;
}
sprintf(buf, "GET %s HTTP/1.0\r\n\r\n", argv[2]);
write(s, buf, strlen(buf));
memset(buf, 0, sizeof(buf));
while((n = read(s, buf, BUF_LEN)) > 0) {
printf("%s", buf);
memset(buf, 0, sizeof(buf));
}
close(s);
}
[์ถ์ฒ] ์ ์์ฉ์ tcp/ip ์์ผ ํ๋ก๊ทธ๋๋ฐ | ํ๋ก์ ํธ - ์น ์๋ฒ
'TIL (Today I Learned) > Linux' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Linux] pthread join๊ณผ detach (0) | 2021.09.03 |
---|---|
[Linux]Symbolic/Hard link (0) | 2021.08.31 |
[Linux] Shell์ ๊ฐ๋ (0) | 2021.08.30 |
[Linux] ํ๊ฒฝ๋ณ์ (0) | 2021.08.27 |
[Linux] make์ Makefile (0) | 2021.08.25 |