책 이름 : Computer Systems: A Programmer's Perspective, Global Edition (3rd Edition)
저자 : Randal E. Bryant / David R, O'Hallaron
빨간색으로 된 키워드에 관한 글 위주로 글을 읽어 주시면 감사하겠습니다.
전체 코드 및 과제 설명은 https://github.com/hoon25/webproxy-jungle를 참고해 주세요.
listenfd = Open_listenfd(argv[1]); // 듣기 소켓을 오픈
connfd = Accept(listenfd, (SA *)&clientaddr, &clientlen); // 연결소켓을 오픈
1,2번 로직이 합쳐진 Main 함수 전문
int main(int argc, char **argv) { // argc 메인함수 전달 정보 개수, Argv[0] 파일 경로 , [1],[2]... user input
int listenfd, connfd;
char hostname[MAXLINE], port[MAXLINE];
socklen_t clientlen;
struct sockaddr_storage clientaddr;
/* Check command line args */
if (argc != 2) {
fprintf(stderr, "usage: %s <port>\n", argv[0]);
exit(1);
}
listenfd = Open_listenfd(argv[1]); // 듣기 소켓을 오픈
while (1) { // 무한 서버 루프 실행
clientlen = sizeof(clientaddr);
connfd = Accept(listenfd, (SA *)&clientaddr,
&clientlen); // line:netp:tiny:accept // 반복적으로 연결 요청을 접수
Getnameinfo((SA *)&clientaddr, clientlen, hostname, MAXLINE, port, MAXLINE,
0);
printf("Accepted connection from (%s, %s)\n", hostname, port);
doit(connfd); // line:netp:tiny:doit // 트랜잭션 수행
Close(connfd); // line:netp:tiny:close
}
}
사용자의 모든 요청은 문자열로 들어온다.
위의 문자열을 기준으로 파싱하여 정적/동적을 구별하고 클라이언트가 원하는 적절한 작업을 수행하고 반환해주어야한다.
ex) 클라이언트의 요청전문
GET /godzilla HTTP/1.1
Host: *.*.*.*:****
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:10.0.3) Gecko/20120305 Firefox/10.0.3\r\n
등등
소켓은 각 통신의 끝점입니다.
클라이언트는 클라이언트 소켓을 가지고 있고, 서버는 연결 소켓을 가지고 있습니다.
실제로 통신은 소켓에 읽고 쓰는 과정이라는것을 알고있어야 합니다.
1. buf에 응답헤더 문자열을 작성 후
2. clientfd에 buf(응답헤더 문자열)을 입력합니다.
결과적으로 클라이언트는 connfd 소켓의 내용을 읽어오는 방식으로 통신이 이루어짐을 알 수 있습니다.
관련 코드 예시
sprintf(buf, "HTTP/1.1 200 OK\r\n");
sprintf(buf, "%sServer: Tiny Web Server\r\n", buf);
sprintf(buf, "%sConnection: close\r\n", buf);
sprintf(buf, "%sContent-length: %d\r\n", buf, filesize);
sprintf(buf, "%sContent-type: %s\r\n\r\n", buf, filetype);
Rio_writen(connfd, buf, strlen(buf));
참고) 네트워크 소켓에는 표준I/O가 아닌 Unix I/O를 사용해야 합니다.
Rio_writen은 Unix I/O기반으로 만들어진 함수입니다.
왜 네트워크 통신에서 표준 I/O가 아닌 Unix I/O를 사용해야 하나요?
관련 답변은 준비중입니다.
위의 코드를 완료한다면 아래와 같은 원시적인 html 페이지를 확인 할 수 있습니다.