반응형
Chapter 1. 웹브라우저가 메시지를 만든다.
01. HTTP 리퀘스트 메시지를 작성한다.
1. 탐험 여행은 URL 입력부터 시작한다.
- 브라우저에서 URL을 입력하는 것으로부터 여행이 시작된다.
- URL은 http:로부터 시작하는 것, ftp:로 시작하는 것, mailto:로 시작하는 것 등 여러가지가 있다.
- 이들은 모두 프로토콜이며 통신 동작의 규칙을 정한 것이다.
- 웹 서버나 FTP 서버에 액세스 하는 경우에는 서버의 도메인 명이나 액세스하는 파일의 경로, 서버 포트 번호 등을 URL에 포함한다.
- 도메인은 google.com, www.naver.com 등을 말한다.
2. 브라우저는 먼저 URL을 해독한다.
- 브라우저가 처음 하는 일은 웹 서버에 보내는 리퀘스트의 메시지를 작성하기 위해 URL을 해독하는 것이다.
- http://www.lab.cyber.co.kr/dir1/index.html 이라는 URL이 있다고 가정하자.
- http:는 프로토콜을 의미한다.
- //는 나중에 이어지는 문자열이 서버의 이름임을 나타낸다.
- www.lab.cyber.co.kr은 웹 서버명으로 도메인이다.
- /dir1은 디렉토리명이고 /index.html은 접근할 파일의 이름이다. 즉 /dir1/index.html은 웹 서버에서 접근할 파일의 경로를 나타낸다.
3. 파일명을 생략한 경우
- http://www.lab.cyber.co.kr/dir/ 같은 URL이 있다.
- 끝이 /로 끝난 것은 다음에 써야 할 파일명을 쓰지 않고 생략한 것이다. 이와 같이 생략하는 것도 URL 규칙에서 어긋나지 않는다.
- 하지만 파일명을 쓰지 않으면 어느 파일에 액세스해야 할지 모른다.
- 그래서 파일명을 생략할 때를 대비해 파일명을 미리 서버측에서 설정한다. 대부분의 서버가 index.html로 설정하는 것이 관례다.
- http://www.lab.cyber.co.kr처럼 모두 생략한 URL도 가능하다.
4. HTTP의 기본 개념
- HTTP 프로토콜은 클라이언트와 서버가 주고받는 메시지의 내용이나 순서를 정한 것이다.
- 먼저 클라이언트에서 서브를 향해 리퀘스트 메시지를 보낸다. 리퀘스트 메시지의 안에는 '무엇을', '어떻게 해서' 하겠다는 내용이 쓰여있다.
- '무엇을'에 해당하는 것을 URI라고 한다.
- 그 다음 '어떻게 해서'에 해당하는 것이 메소드다. 이 메소드에 의해 웹 서버에 어떤 동작을 하고 싶은지를 전달한다. (GET, POST 등이 있다.)
- HTTP의 메시지에는 보충 정보를 나타내는 헤더 파일도 있다. 전달할 데이터가 담긴 바디 부분도 있다.
- 리퀘스트 메시지가 웹 서버에 도착하면 웹 서버는 그 속에 쓰여있는 내용을 해독하고, 요청에 따라 작업을 수행한다.
- 그러면 결과 데이터를 응답 메시지에 저장하는데, 응답 메시지의 맨 앞부분에는 실행 결과가 정상 종료되었는지 또는 이상이 발생했는지를 나타내는 상태 코드가 있다.
- 응답 메시지가 클라이언트에게 도착하면 HTTP의 동작은 끝난다.
5. HTTP의 리퀘스트 메시지를 만든다.
- 브라우저는 URL을 해독하고 웹 서버와 파일명을 판단하면 이것을 바탕으로 HTTP의 리퀘스트 메시지를 만든다.
- 먼저 리퀘스트 메시지의 첫 번째 행에서 요청 라인을 쓴다.
- 요청 라인은 <메서드><공백><URI><공백><HTTP 버전>으로 구성된다.
- 그 다음은 필드명과 필드 값으로 구성된 HTTP 헤더를 쓰고 헤더가 끝나면 공백 행을 둔 후 메시지 본문을 작성한다.
- HTTP 헤더(메시지 헤더)에는 부가적인 자세한 정보가 들어간다. 날짜, 클라이언트에서 취급하는 데이터의 종류, 언어 압축 형식 등.
- 메시지 본문은 송신할 데이터를 보통 작성한다.
6. 리퀘스트 메시지를 보내면 응답이 되돌아온다.
- 리퀘스트 메시지를 보내면 웹 서버에서 응답 메시지가 되돌아온다.
- 응답 메시지의 첫 번째 행은 응답 라인이다.
- 응답 라인은 <HTTP 버전><공백><상태 코드><공백><응답 문구>로 이뤄진다.
- 상태 코드는 요청이 정상 종료했는지, 아니며 오류가 발생했는지 알려준다.
- 응답 문구는 문장으로 쓰여있으며 사람에게 실행 결과를 알리는 것이 목적이다.
- 이후에는 HTTP 헤더가 들어가고 헤더가 끝나면 공백 행을 둔 후 메시지 본문을 작성한다.
- 응답 메시지가 되돌아오면, 그때부터 데이터를 추출한 후 화면에 표시하여 웹 페이지를 눈으로 볼 수 있다.
02. 웹 서버의 IP 주소를 DNS 서버에 조회한다.
1. IP 주소의 기본
- HTTP의 메시지를 만들면 다음에는 이것은 OS에 의뢰하여 액세스 대상의 웹 서버에게 송신한다.
- 브라우저는 URL을 해독해 요청 메시지를 만들지만, 메시지를 네트워크에 송출하는 기능은 없다.
- 이때 URL에 있는 서버의 도메인 명에서 IP 주소를 조사해야 한다.
- OS에 송신을 의뢰할 때는 도메인 명이 아니라 IP 주소로 메시지를 받을 상대를 지정해야 하기 때문이다.
TCP/IP
- TCP/IP는 서브넷이라는 작은 네트워크를 라우터로 접속하여 전체 네트워크가 만들어진다.
- 서브넷은, 허브에 몇 대의 PC가 접속된 것이라고 생각해도 무방하다.
- 이것을 한 개의 단위로 생각하면 '서브넷'이라 부르고, 라우터에서 연결하면 네트워크 전체가 완성된다.
IP 주소와 넷마스크
- IP 주소는 네트워크에 존재하는 각 컴퓨터를 식별하기 위해 각각에 서로 다른 값을 할당한 것이다.
- IP 주소는 32비트의 디지털 데이터다. 이것을 8비트씩 점으로 구분해 10진수로 표기한다.
- IP 주소만 작성하고 보면 어느 부분이 네트워크 번호인지 호스트 번호인지 알 수 없다.
- 네트워크 번호인지 호스트 번호인지 알기 위해 어떤 정보를 IP 주소에 덧붙이는데, 이 정보를 '넷마스크'라고 한다.
- 넷마스크는 IP 주소에서 32비트 부분의 디지털 데이터이며, 왼쪽에 1이 나열되고 오른족에 0이 나열된 값이 된다.
- 그리고 넷마스크가 1인 부분은 네트워크를 나타내고, 넷마스크가 0인 부분은 호스트 번호를 나타낸다.
- 호스트 번호 부분이 모두 0인 IP 주소는 각각의 기기를 나타내는 것이 아니라 서브넷 전체를 나타낸다.
- 호스트 번호 부분이 모두 1이면 서브넷에 있는 기기 전체에 패킷을 보내는 프로드 캐스트를 나타낸다.
- 서브넷을 나타내는 주소: 10.11.12.0/24
- 서브넷의 브로드캐스트를 나타내는 주소: 10.11.12.255/24
IP 주소 예시
- IP 주소: 10.1.2.3
- 넷마스크: 255.255.255.0
- 네트워크 번호: 10.1.2
- 호스트 번호: 3
2. 도메인과 IP 주소를 구분하여 사용하는 이유
- TCP/IP의 네트워크는 IP 주소롤 통신 상대를 지정한다. IP 주소를 모르면 상대에게 메시지를 전달할 수 없다.
- 그러므로 OS에 메시지 송신을 의뢰할 때는 IP 주소를 조사해야 한다.
- URL 안에는 서버명이 아니라 IP 주소를 쓰면 좋을 것 같지만, 숫자를 나열한 IP 주소를 기억하기는 어렵다.
- 그러므로 IP 주소가 아니라 서버의 이름을 쓸 수 있도록 하는 쪽이 좋다.
- 그러면 IP 주소 같은 것은 그만두고 이름을 상대를 지정해 통신하는 것이 좋다는 의견이 나올 수도 있다.
- 결론만 말하자면 IP 주소는 32비트지만, 도메인명은 적어도 수십 바이트부터 최대 255바이트나 있으므로 라우터가 부하되어 데이터를 운반하는 동작에 더 많은 시간이 걸리면서 네트워크의 속도가 느려진다.
- 이름을 알면 IP 주소를 알 수 있어야 하는데 이때 사용하는 것이 DNS다.
3. Socket 라이브러리가 IP 주소를 찾는 기능을 제공한다.
- IP 주소를 조사하는 법은 바로 가장 가까운 DNS 서버에 서버의 도메인 명과 매치하는 IP 주소를 가르쳐달라고 요청을 보내면 된다.
- 그러면 DNS가 서버의 도메인 명과 매치하는 IP 주소를 알려준다.
- 결국 DNS 서버에 조회하는 것은 DNS 서버에 조회 메시지를 보내고 DNS 서버로부터 응답 메시지를 받는 것이다.
- 이 동작은 DNS 클라이언트라고 말할 수 있는데 DNS 리졸버 또는 리졸버라고 부른다.
- 그리고 DNS의 원리를 사용해 IP 주소를 조사하는 것을 네임 리졸루션이라고 하는데, 이 리졸루션을 실행하는 것이 리졸버다.
- 리졸버의 실체는 Socket 라이브러리에 들어있는 부품화한 프로그램이다.
- Socket 라이브러리는 OS에 포함되어 있는 네트워크의 기능을 애플리케이션에서 호출하기 위한 부품을 모아놓은 것이다.
- 리졸버는 그 속에 들어있는 프로그램 부품의 하나이다.
- 정리하면 Socket 라이브러리는 네트워크의 기능을 호출하기 위한 프로그램의 부품집이다.
4. 리졸버를 이용해 DNS 서버를 조회한다.
- 브라우저 등의 애플리케이션 프로그램을 만들 때 리졸버 프로그램명과 웹 서버의 이름을 쓰기만 하면 리졸버를 호출할 수 있다.
- 리졸버를 호출하면 리졸버가 DNS 서버에 조회 메시지를 보내고, DNS 서버에서 응답 메시지가 돌아온다.
- 이 응답 메시지 속에 IP 주소가 있으므로 리졸버는 이것을 추출해 브라우저에서 지정한 메모리 영역에 넣는다.
- 이럼 IP 조회의 동작이 끝난다.
- 정리하면 도메인명에서 IP 주소를 조사할 때 브라우저는 Socket 라이브러리의 리졸버를 이용한다.
5. 리졸버 내부의 작동
- 내트워크 애플리케이션이 리졸버를 호출하면 제어가 리졸버의 내부로 넘어간다.
- 리졸버로 제어가 넘어가면 DNS 서버에 문의하기 위한 요청 메시지를 만든다.
- 메시지를 DNS 서버에 보낸다. 메시지 송신 동작은 리졸버가 스스로 실행하는 것이 아니라 OS 내부에 포함된 프로토콜 스택을 호출하여 실행을 의뢰한다.
- 리졸버도 브라우저와 같이 네트워크에 대해 데이터를 송,수신하는 기능이 없기 때문이다.
- 리졸버가 프로토콜 스택을 호출하면 제어가 리졸버에게 넘어가고 여기에서 메시지를 보내는 동작을 실행하여 LAN 어댑터를 통해 메시지가 DNS 서버를 향해 송신된다.
- 조회 메시지가 DNS 서버에 도착하고 DNS 서버는 메시지에 쓰여있는 조회 내용을 조사하여 답을 찾는다.
- 액세스 대상의 웹 서버가 DNS 서버에 등록되어 있으면 답이 발견되므로 답을 응답 메시지에 써서 반송한다.
- 그러면 메시지는 네트워크를 통해 클라이언트 측에 도착하고, 프로토콜 스택을 경유하여 리졸버에 건네져서 리졸버가 내용을 해독한 후 여기에서 IP 주소를 추출하여 애플리케이션에 IP 주소를 건넨다. 실제로는 리졸버를 호출할 때 지정한 메모리 영역에 IP 주소를 저장한다.
- 이러면 리졸버 동작이 끝나고 제어가 애플리케이션에게 돌아오면서, 애플리케이션은 메모리 영역에 저장된 IP 주소를 사용한다.
- DNS 서버에 메시지를 송신할 때도 DNS 서버의 IP 주소가 필요한데, 이는 보통 컴퓨터에 미리 설정되어 있다.
03. 전세계의 DNS 서버가 연대한다.
1. DNS 서버의 기본 동작
- DNS 조회 메시지는 이름, 클래스, 타입과 같은 3가지 정보가 들어있다.
- 이름은 서버나 메일 배송 목적지와 같은 이름이다.
- 클래스는 DNS의 구조를 고안했을 때 인터넷 이외에도 네트워크에서의 이용까지 검토하여 이것을 식별하기 위해 준비한 정보다. 그러나 지금은 인터넷 이외의 네트워크는 소멸되었으므로 클래스는 항상 'IN'라는 값이다.
- 타입은 이름에 어떤 타입의 정보가 지원되는지를 나타낸다. 아래는 타입 예시 종류다.
- Type A: 호스트명에 대응하는 IP 주소
- Type CNAME: 호스트명에 대응하는 별칭
- Type MX: 도메인명에 대응하는 메일 서버
- Type NS: 도메인을 관리하는 DNS 서버
- DNS 서버에는 이들 세 가지 정보에 대응하여 클라이언트에 회답하는 항목을 등록했다. 이 정보들을 리소스 레코드라고 부른다.
- 이 등록 내용에서 조회 메시지에 해당하는 것을 찾아 클라이언트에게 회답한다.
- 정리하면 DNS 서버는 서버에 등록된 도메인명과 IP 주소의 대응표를 조사하여 IP 주소를 회답한다.
2. 도메인의 계층
- 전세계의 막대한 인터넷 서버 수들을 1대의 DNS 서버에 등록하는 것은 불가능하다.
- 그러므로 정보를 분산시켜서 다수의 DNS 서버에 등록하고, 다수의 DNS 서버가 연대하여 어디에 정보가 등록되어 있는지를 찾아내는 구조다.
- 우선 DNS 서버에 등록한 정보에는 모든 도메인명이라는 계층적 구조를 가진 이름이 붙여져 있다.
- DNS에서 취급하는 이름은 www.lab.cyber.co.kr처럼 점으로 구분되어 있다.
- kr이라는 도메인 아래에 co라는 도메인이 있고 co라는 도메인 아래에 cyber라는 도메인이 있으며 그 아래에 lab이라는 도메인이 있다. 최하위의 www가 서버의 이름이다.
- 이렇게 계층화된 도메인의 정보를 서버에 등록하는데, 이때 하나의 도메인을 일괄적으로 취급한다.
- 즉 한 개의 도메인 정보를 일괄적으로 DNS 서버에 등록하고 도메인 한 대의 정보를 분할하여 복수의 DNS 서버에 등록하는 것은 불가능하다.
- 단 DNS 서버와 도메인은 항상 1대 1이 아니라 한대의 DNS 서버에 복수 도메인의 정보를 등록할 수 있다.
- 즉 한 대의 DNS 서버에 도메인 한 대를 등록한다고 생각하면 된다.
- 회사의 도메인이 example.co.kr 이라는 여러 하위 도메인을 할당할 수도 있다. sub1.example.co.kr, sub2.example.co.kr 등.
3. 담당 DNS 서버를 찾아 IP를 가져온다.
- 인터넷에는 DNS 서버가 수만 대나 있으므로 닥치는 대로 뒤지면서 다닐 수 없다. 그래서 다음과 같은 방법이 있다.
- 먼저 하위의 도메인을 담당하는 DNS 서버의 IP 주소를 그 상위의 DNS 서버에 등록한다.
- 그리고 상위의 DNS 서버를 또 그 상위의 DNS 서버를 등록하는 식으로 차례대로 등록한다.
- 이렇게 하면 상위의 DNS 서버에 가면 하위의 DNS 서버의 IP 주소를 알 수 있고, 거기에서 조회 메시지를 보낼 수도 있다.
- 인터넷의 도메인은 com이나 kr의 상위에 또 하나의 루트 도메인이라는 도메인이 있다.
- 루트 도메인이 존재하므로 DNS 서버에 com이나 co의 DNS 서버를 등록한다.
- 이렇게 해서 하위의 DNS 서버를 상위의 DNS 서버에 등록하여 루트 도메인에서 차례로 아래쪽으로 거슬러 내려갈 수 있다.
- 한 가지 준비 사항이 더 있다. 루트 도메인 DNS 서버를 인터넷에 존재하는 DNS 서버에 전부 등록해야 한다.
- 이렇게 해서 어느 DNS 서버도 루트 도메인에 액세스할 수 있게 된다. 그럼 클라이언트에서 어딘가의 DNS 서버에 액세스하면 여기에서부터 루트 도메인을 경유하여 도메인 계층 아래로 찾아가서 최정적으로 원하는 DNS 서버에 도착한다.
- 루트 도메인의 DNS 서버에 할당된 IP 주소는 전 세계에 13개 밖에 없고 좀처럼 변경되지 않으므로 이것을 각 DNS에 등록하는 작업은 어렵지 않다.
- DNS 메세지를 컴퓨터에 등록된 제일 가까운 DNS 서버로 보내면 그 서버에서 루트 도메인 DNS로 이동한다.
이후 하위 도메인을 비교하면서 DNS 요청 메시지에 적힌 목표 IP를 획득한다.
4. DNS 서버는 캐시 기능으로 빠르게 회답할 수 있다.
- DNS 서버는 한 번 조사한 이름을 캐시에 기록할 수 있다.
- 조회한 이름에 해당하는 정보가 캐시에 있으면 그 정보를 회답한다.
- 그러면 그 위치에서 계층 구조를 아래로 향하여 찾을 수 있다. 루트 도메인부터 찾기 시작하는 것보다 편리하다.
- 캐시에도 주의점이 임ㅆ다.
- 캐시에 정보를 저장한 후 등록 정보가 변경되는 경우도 있으므로 캐시 안에 정보가 늘 옳다고 말할 수 없다.
- 그러므로 캐시에 유효시간을 설정하고, 캐시에 유효 시간이 지나면 삭제한다.
- 또 조회에 회답할 때 정보가 캐시에 저장된 것인지, 아니면 등록처 DNS 서버가 회답한 것인지 알려줘야 한다.
04. 프로토콜 스택에 메시지 송신을 의뢰한다.
1. 데이터 송,수신 동작의 개요
- OS 내부의 프로토콜 스택에 메시지 송신 동작을 의뢰할 때는 Socket 라이브러리 프로그램 부품을 결정된 순번대로 호출한다.
- 데이터 송, 수신 동작은 아래 4가지 동작으로 요약할 수 있다.
- 소켓을 만든다. (먼저 서버에서 소켓을 만들고, 소켓에 클라이언트가 파이프를 연결하기를 기다린다.)
- 클라이언트가 서버측의 소켓에 파이프를 연결한다.
- 데이터를 송, 수신한다.
- 파이프를 분리하고 소켓을 말소한다. (어느쪽이 파이프를 분리해도 상관없다. 클라이언트의 소켓을 말소.)
- 이 단계에 따라 Socket 라이브러리 안의 프로그램 부품을 호출하여 데이터의 송, 수신 동작을 실행한다.
- 이 4가지 동작을 실행하는 것은 모두 OS 내부의 프로토콜 스택이다.
- 이 동작은 Socket 라이브러이에 넣은 프로그램 부품을 호출하여 실행하면, 실질적인 작업은 프로토콜 스택이 진행한다.
2. 소켓의 작성 단계
- 클라이언트의 소켓은 Socket 라이브러리를 이용해서 만든다.
- 소켓이 생기면 디스크립터라는 것이 돌아온다. 이를 메모리에 기록해 둔다.
- 디스크립터는 소켓을 식별하기 위해 사용하는 것이다. 복수의 소켓이 존재할 가능성을 대비한 것이다.
- 쉽게 말해 애플리케이션은 디스크립터라는 번호표 같은 것을 이용해, 소켓을 식별한다.
3. 파이프를 연결하는 접속 단계
- 이제 만든 소켓을 서버측에 소켓에 접속하도록 프로토콜 스택에 의뢰한다.
- 이 의뢰를 진행할 때 디스크립터, 서버의 IP 주소, 포트 번호라는 3가지 정보가 필요하다.
- 디스크립터는 애플리케이션이 소켓을 식별하는 것이다.
- IP와 포트 번호를 사용해야 서버의 어느 소켓에 접속할지를 지정할 수 있다.
- 포트 번호의 규칙은 전 세계적으로 통일되어 있다. 예를 들어 웹은 80번, 메일은 25번이다.
- 이제 위에서 필요한 3가지 정보를 가지고 프로토콜 스택이 접속 동작을 실행한다.
- 그리고 상대와 연결되면 프로토콜 스택은 연결된 상대의 IP 주소나 포트 번호 등의 정보를 소켓에 기록한다. 이제 데이터 송,수신이 가능해진 것이다.
4. 메시지를 주고받는 송, 수신 단계
- 소켓이 상대측과 연결되면 소켓에서 데이터를 쏟아 부으면 상대측의 소켓에 데이터가 도착한다.
- 그러면 애플리케이션은 소켓을 직접 다룰 수 있으므로 Socket 라이브러리를 통해 프로토콜 스택에 그 일을 의뢰한다.
- 우선 애플리케이션은 송신 데이터를 메모리에 준비하고 사용자가 입력한 URL을 바탕으로 HTTP의 리퀘스트 메시지 즉, 송신 데이터를 만든다.
- 그리고 write 메서드를 호출할 때 디스크립터와 송신 데이터를 지정한다.
- 그러면 프로토콜 스택이 송신 데이터를 서버에게 송신한다.
- 소켓에는 연결된 상대가 기록되어 있으므로 디스크립터로 소켓을 지정하면 연결된 상대가 판명되어 그곳을 향해 데이터를 송신한다.
- 이때 송신 데이터는 네트워크를 통해 전부 그대로 액세스 대상의 서버에 도착한다.
- 그러면 서버는 수신 동작을 실행하여 받은 데이터의 내용을 조사하고 적절한 처리를 실행하여 응답 메시지를 반송한다.
- 이때 수신한 응답 메시지를 저장하기 위해 메모리 영역을 지정하는데, 이 메모리 영역을 수신 버퍼라고 부른다.
- 응답 메시지가 돌아왔을 때 read 메서드를 통해 수신 버퍼에 저장한다.
- 수신 버퍼는 애플리케이션 프로그램의 내부에 마련된 메모리 영역이므로 수신 버퍼에 메시지를 저장하는 시점에서 메시지를 애플리케이션에 건네준다.
5. 연결 끊기 단계에서 송, 수신이 종료된다.
- 브라우저가 데이터 수신을 완료하면 송,수신 동작은 끝난다.
- 그 후 Socket 라이브러리의 close라는 프로그램 부품을 호출하여 연결 끊기 단계로 들어가도록 의뢰한다.
- 그러면 소켓 사이를 연결한 파이프와 같은 것이 분리되고 소켓도 말소된다.
- 웹에서 사용하는 HTTP 프로토콜은 서버가 응답 메시지를 송신 완료하면 웹 서버에서 연결 끊기 동작을 행하므로 먼저 서버측에서 close를 호출해 연결을 끊는다.
- 그러면 이것이 클라이언트측에 전달되어 클라이언트의 소켓은 연결 끊기 단계로 들어간다.
- 그러면 read가 이것을 알고 송,수신 동작이 완료되었다는 사실을 브라우저에 통지한다.
- 그러면 브라우저도 close를 호출해 연결 끊기 단계에 들어간다.
이상으로 포스팅을 마칩니다. 감사합니다.
참고자료
컴퓨터 네트워킹 하향식 접근 제 7판
성공과 실패를 결정하는 1%의 네트워크 원리
https://product.kyobobook.co.kr/detail/S000000559964
반응형
댓글