본문 바로가기
네트워크/컴퓨터 네트워크 수업

2-2. Application-layer protocols(Web & HTTP)(1)

by dustnn 2024. 10. 13.

 

Web 

 

 

우리가 웹페이지에 접속하면 여기저기 파일과 이미지, 비디오 등이 첨부되어 있는 걸 볼 수 있다.

이러한 것들을 object라고 하며, 각자 URL로 지정할 수 있다.

기본 HTML file은 이러한 참조 객체들을 포함하여 페이지 내부의 객체를 그 객체의 URL 주소로 참조하는 역할을 한다.

그런데 이때 HTML file 자체도 객체다.

 

URL은 다음과 같이 호스트 이름과 경로 이름을 포함한다.

 

 

 

HTTP

 

 

HTTP는 application 계층의 프로토콜로, 웹 클라이언트가 웹 서버에게 웹 페이지를 어떻게 요청하는지와 서버가 클라이언트로 어떻게 웹 페이지를 전송하는지를 정의한다.

그리고 HTTP는 TCP를 전송 프로토콜로 사용한다.

 

HTTP 통신 과정

 

 

위 그림처럼

1. 클라이언트가 페이지 내부의 객체에 대한 HTTP 요청 메시지를 서버에게 보내면

=> HTTP 클라이언트는 먼저 서버의 port 80으로 TCP 연결을 요청 메시지를 보낸다. (HTTP의 port#는 80)

=> 서버가 TCP connection 수락

=> 연결이 이루어지면 클라이언트와 서버 모두 각자의 socket interface를 통해 TCP에 접속한다.

**socket interface는 프로세스와 TCP 간 연결 통로임 ('클라이언트 프로세스와 TCP 사이' 그리고 '서버 프로세스와 TCP 사이')

=>클라이언트가 HTTP 요청 메시지를 socket interface로 보낸다.

=> TCP가 그 메시지를 서버에게 보낸다.

 

2. 서버는 요청을 수신하고 객체를 포함하는 HTTP 응답 메시지로 응답한다.

 

 

 

HTTP protocol을 사용하면 PC든 아이폰이든 서로 연결이 가능하다.

HTTP는 stateless protocol이다. stateless하다는 것은 클라이언트에 대한 상태 정보를 유지하지 않는다는 뜻이다. 

그래서 클라이언트가 전에 요청했던 객체를 다시 요청한다고 해도 서버는 이전에 요청했던 사실을 모르기 때문에 다시 보내준다.

이러한 특징은 서버와 클라이언트의 state가 충돌할 때의 문제를 막고 많은 서버에 load balancing이 원활히 이루어지도록 한다.

 

 

HTTP connection의 두 가지 종류

 

 

그럼 object들이 다 전달될 때까지 TCP 연결은 계속 되어 있어야 할까? 

이를 기준으로 두 가지로 나누어진다.

두 가지 HTTP의 과정응답시간(하나의 웹페이지를 전적으로 disply해줄 때까지 필요한 시간)을 중점적으로 알아보자.

 

1. non-persistent HTTP

 

: 요구/응답 쌍이 분리된 연결을 통해 보내짐

 

과정

 

10개의 jpeg 이미지가 부착된 "www.someSchool.edu/someDepartment/home.index" 라는 URL이 있다고 해보자.

이 URL을 클릭했다고 할 때

 

=> 클라이언트는 TCP 연결 요청

=> 서버가 연결 수락

=> 클라이언트가 URL을 포함한 HTTP 연결 요청 메시지 전송

(아까 말했듯 HTTP 메시지는 host가 누군지와 클라이언트가 원하는 object의 경로를 담고 있음)

=> 서버가 메시지 받으면 자신의 storage로부터 response 메시지 골라 socket으로 빠뜨림(application계층 -> transport 계층)

=> 자기 할 일을 마친 서버가 TCP 연결을 끊음

=> 클라이언트가 response 메시지 받아 HTML file 을 파싱하여 10개의 jpeg 이미지 객체를 찾음

=> 10개의 객체들에 대해 여태까지의 단계 반복

 

응답시간

 

RTT(Round Trip Time): 하나의 패킷이 클라이언트에서 서버에 갔다가 다시 돌아올 때까지 걸리는 시간

 

만약 기존 HTTP file 하나의 object만이 존재한다고 할 때 응답시간은

1RTT(TCP 연결할 때) + 1RTT(하나의 object를 위한 HTTP 소통) = 2RTT

 

HTTP file 안에 10개의 object 존재하므로

기본 HTTP file => TCP 연결(1RTT) + HTTP file 위한 HTTP request/response(1RTT) = 2RTT

참조 객체 10개 => 10 * {TCP 연결(1RTT) + 각 객체의 HTTP request/response(1RTT)} = 10*2 RTT = 20RTT

=> 총 22RTTs

 

하지만!! 이렇게 여러 번 반복하는 것은 비효율적이므로 HTTP 1.1 에서는 pipelining 을 통한 병렬적 TCP 연결을 지원한다.

 

10개의 객체가 동시에 병렬적으로 처리되므로

(1+1) + (1+1) = 4RTTs

=> 총 4RTTs

 

 

 

2. persistent HTTP(HTTP 2.0)

 

: 모든 요구와 해당하는 응답들이 같은 TCP 연결상으로 보내짐

 

과정

=> 클라이언트는 TCP 연결 요청

=> 서버가 연결 수락

=> 클라이언트가 URL을 포함한 HTTP 연결 요청 메시지 전송

=> 서버가 메시지 받으면 자신의 storage로부터 response 메시지 골라 socket으로 빠뜨림

=> 서버가 TCP 연결 끊지 않고 유지

=> 아직 끊어지지 않은 TCP 연결을 통해 둘 사이의 요청과 응답이 진행됨

=> 일정 기간 사용되지 않으면 TCP 연결 끊음

모든 객체를 한 번에 처리했기 때문에 더이상 반복하지 않아도 된다 !

 

**non-persistent HTTP 와 다른 것은 서버가 하나의 메시지 처리한 이후에 TCP를 바로 끊지 않는다는 것이다.**

 

응답시간

 

1RTT(TCP 연결) + 1RTT(base HTML file) + 1RTT(object들 한 번에) = 총 3RTTs

 

총 정리해보자면

 

<base HTML file과 n개의 object가 존재할 때>

non-persistent parallel non-persistent(HTTP 1.1) persistent(HTTP 2.0)
2+n*2 RTT 4RTT 3RTT

 

 

HTTP message format

 

 

클라이언트가 서버에게 보내는 request message와 서버가 클라이언트에게 보내는 respond message는 형식이 비슷하지만 첫줄은 다르다. 각각의 형식을 뜯어보자.

 

HTTP request message(client -> server)

 

HTTP request message format

 

"request line => header line => body(선택)" 이라는 기본 형식을 따른다.

다음 예를 통해 자세한 구조를 살펴보자.

 

 

 

1. request line(해당 URL에 해당하는 웹페이지 줘라)

- "message" field: GET/POST/HEAD가 올 수 있지만 주로 GET 사용

- "URL" field: /index.html

- "version" field: HTTP 1.1

- carriage return & line field => 마침표 역할(줄바꿈)

 

 

** "message" field 의 GET/POST/HEAD

- GET

- POST: 아래 body 파트에 form feed할 때 사용하는 명령어 => body부분에 form feed 내용 들어감

- HEAD: URL을 원하는데 보내지는 말고 있는지만 체크하는 명령어(디버깅을 위해 사용)

 

 

2. header lines(client가 server에게 알려주고 싶은 정보들)

- header field name

- value

- carriage return & line field => 마침표 역할(줄바꿈)

 

 

**Keep-Alive: 115 \r\n

Connection: keep-alive\r\n

=> persistent 모드로 동작하자는 얘기(request 받아도 TCP 연결 끊지 말아라!)

 

 

3. body

 

 

HTTP respond message(server -> client)

 

respond message 에서는 request line 이 아니라 status line이다. 

 

 

status line => header lines => body

 

1. status line

- "version" field: HTTP 1.1

- status code: 200

- status phrase: OK

=> client가 요청한 웹페이지 전달이 성공적으로 진행되었는지 보여줌

이때 status code와 status phrase는 같은 의미를 함유하지만 code의 의미를 사용자가 잘 이해할 수 있도록 phrase로 보여주는 것.

 

**몇 개의 대표 status code**

- 200  OK

"요청이 성공했고, 정보가 응답으로 보내졌다."

 

- 301  Moved Permanently

: "요청 객체가 영원히 이동되었다. 새로운 URL은 응답 메시지의 Location: 헤더에 나와있다. 클라이언트 소프트웨어는 자동으로 이 새로운 URL을 추출한다."

 

- 304  Not Modified

: "이 날짜 이후로 수정되지 않았으므로 캐시되어 있는 자원으로 리디렉션해준다."

request message의 'if modified since'와 response message의 'last modified'와 함께 웹캐싱에 사용된다.

=> 처음에는 200 나오지만 이후로 변경사항 없는데 요청을 보내면 304를 받게 된다.

 

- 400  Bad Request

: "서버가 요청을 이해할 수 없다." => 일반 오류 코드

 

- 404  Not Found

: "요청 문서가 서버에 존재하지 않는다."

 

- 505  HTTP Version Not Supported

: "요청 HTTP 프로토콜 버전을 서버가 지원하지 않는다."

 

 

2. header lines(request message와 같은 형식)

- header field name

- value

- carriage return & line field => 마침표 역할(줄바꿈)

 

**Date: 서버가 HTTP response message를 보낸 날짜와 시간

**Server: server의 종류(주로 apache server 사용)

**Last-Modified: 웹페이지가 마지막으로 업데이트된 시간

**Content-Length: 송신되는 객체의 바이트 수 => 예제에서는 2652 bytes

**Content-type: body 내부의 객체 종류 => 예제에서는 body 내부의 객체가 HTML 텍스트임

 

 

3. body

 

 

Cookies(maintaining user/server state)

 

HTTP 서버는 stateless하다고 했다. 그런데 어떨 때는 그 정보를 가지고 있을 필요가 있다. 그럴 때 cookie를 사용한다.

 

 

4가지 구성요소

 

1. HTTP 응답 메시지의 set-cookie header line

: 서버에서 response 메시지 만들면서 set-cookie라는 header line을 포함한다.

2. HTTP 요청 메시지의 cookie header line

: request 메시지의 header line에 cookie를 달고 오면 어떤 사용자인지 알 수 있다.

3. 사용자의 브라우저에 사용자 종단 시스템과 관리를 지속시키는 cookie file

: 웹서버들이 쿠키 번호를 지정했으므로 cookie file을 두어 적어둠

4. 웹사이트의 back-end database

: back-end database는 protocol 자체에 포함되지 않은, external database로, 사용자가 해당 웹사이트를 방문했을 때 어떤 일을 했는지 기록한다.

 

그래서 다음과 같은 과정으로 cookie가 생성 및 사용된다.

 

클라이언트가 웹사이트에 처음 방문

=> 처음 방문한 클라이언트에게 고유한 ID(cookie)를 부여

=> 클라이언트의 cookie 정보가 backend database에 저장되고 response message의 header line에 set-cookie가 들어감

=> 이후에 웹사이트에 방문할 때는 cookie를 header line에 달고 감

=> backend database의 정보를 가져와 cookie-specific action

=> 이후에도 cookie-specific action

 

 

 

그 외 cookie에 대한 comments

 

- cookie는 무엇을 위해 사용되는가?

 

: authorization

: shopping carts => 상품 누르거나 주문할 때마다 서버에 메시지를 보내지만 로그인을 계속 하지는 않음

: recommendations => cookie-specific action할 때마다 사용자에 대한 정보력이 늘어나고 추천기능에 사용됨

: user session state(Web e-mail) => HTTP를 이용해 서버에게 메일을 보내지만 HTTP는 메일 메시지 하나 받으면 TCP 연결을 끊어버리며, persistent의 경우에도 몇 초간만 유지되고 끊긴다. 때문에 session maintain을 위해 사용됨

 

 

- 어떻게 state를 유지하는가?

 

: cookie가 바로 state 정보 => message에 항상 가지고 다님

 

- cookies vs privacy?

 

: cookie는 웹사이트에게 클라이언트에 대한 많은 정보를 제공해서 privacy에 대한 논의는 계속된다.....