I : 웹 브라우저가 메시지를 만든다
1% 네트워크 원리 을 읽고 정리한 문서입니다 ;)
HTTP 리퀘스트 메시지를 작성한다
브라우저가 가장 먼저 하는 일은 입력된 URL을 해석하는 것이다.
- 입력된 URL을 잘게 파츠별로 나눈다.
- 맨 앞 부분은 해당 URL에 액세스하는 방법을 명시하며, 이에 따라 후속 해석도 결정된다.
- 이 해석을 통해 어디에 액세스해야하는지가 판명나게 된다.
- 이러한 액세스 지점은 파일명이나 CGI 프로그램 파일명이다.
- 이 액세스 대상을 통칭하는 말이 URI 이다.
URL : Uniform Resource Locator
URI : Uniform Resource Identifier
HTTP프로토콜은 웹서버에서 클라이언트와 서버가 주고받는 메시지와 순서를 정한 것이다.
HTTP 메서드로는 리소스에 액세스 후 읽기를 요청하는 GET 과, 폼에 데이터를 사용하여 웹 서버에 송신하는 POST 가 주로 쓰인다.
리퀘스트 메시지 본문은 GET 메서드인 경우에는 빈 칸으로 보내지게 된다.
HTML 응답 메시지에서 태그라는 제어 정보를 만나게 되면, 해당 공간을 비워둔 다음, 그 태그마다 개별적으로 또다시 리퀘스트 메시지를 보내고 응답을 받아 데이터를 표시한다.
정리
- 브라우저는 유저가 입력한 URL을 잘게 파츠로 나누어 맨 앞 액세스 방법대로 해석해낸다.
- 이후 원하는 URI가 판명이 나면, 적합한 메서드와 URI 를 조합하여 리퀘스트 메시지를 만든다.
- 리퀘스트 메시지 첫 라인에는 메서드와 URI 및 버전이 명시되고, 메시지 헤더와 본문이 뒤따른다.
웹서버의 IP주소를 DNS서버에 조회한다
OS에 네트워크 메시지 전송을 의뢰할 때에는 IP주소를 지정해야 하기 때문에, HTTP 메시지를 만든 이후의 작업은 서버의 IP를 알아내는 것이다.
IP주소는 32비트로 표시되는 네트워크상의 고유한 주소로서, 네트워크 번호와 호스트 번호로 구성되어 있다. 하지만 어느 부분까지가 네트워크 번호인지를 알 수 없기에, 이 내역을 나타내는 정보를 필요에 따라 IP주소에 덧붙이는데, 이를 넷마스크 라고 한다.
호스트 번호가 0인 IP주소는 네트워크 주소 (서브넷 주소) 그 자체를, 호스트 번호가 모두 1인 IP 주소는 해당 네트워크의 브로드캐스트 주소를 의미한다.
사람은 이름을 사용하고 라우터를 위시한 네트워크 장비들은 IP주소를 사용하기에, 이름을 알면 IP 주소를 알 수 있도록 하는 시스템이 필요한데, 이것이 DNS 원리를 이용한 것이다.
DNS서버에 조회한다는 것은 DNS 서버에 대한 클라이언트가 되어서 조회 메시지를 보내고 응답을 받는 것이다.
이러한 기능을 해 주는 것을 DNS 리졸버 혹은 리졸버 라고 부르고, 이를 통해 IP주소를 조사하는 것을 네임 리졸루션 이라고 한다.
이러한 리졸버는 소켓 라이브러리에 들어있는 부품화된 프로그램이다.
DNS서버에 요청을 보낼 때에도 당연히 DNS 서버의 IP가 필요한데, 이는 OS 네트워크 설정에 기본적으로 설정되어있다.
리졸버는 OS의 내부에 포함된 프로토콜 스택 (네트워크 제어용 소프트웨어 혹은 TCP/IP 소프트웨어)에 송수신을 요청하게 된다.
정리
- 사용자가 요청한 URL 도메인 이름으로부터 IP를 알아내기 위해 DNS 리졸버를 사용한다.
- 브라우저가 OS 소켓 라이브러리의 리졸버를 이용해 IP 주소 질의를 요청한다.
- 리졸버는 OS의 프로토콜 스택에 DNS 메시지를 전송한다.
전 세계의 DNS 서버가 연대한다
DNS서버는 클라이언트들로부터 조회 메시지를 받아 이에 답하는 식으로 동작한다.
클라이언트로부터 받는 조회 메시지에는 세 가지 정보가 포함된다.
- 이름 : 서버나 메일 목적지와 같은 이름이다.
- 클래스 : DNS를 인터넷 이외에서도 쓰고자 클래스 필드가 존재했지만, 지금은 인터넷을 의미하는 IN 만 사용된다.
- 타입 : 이름에 어떤 타입의 정보가 지원되는지를 나타낸다. 타입이 A라면 이름에 IP주소가 지원되는 것을 나타내며, MX이면 이름에 메일 목적지가 지원된다는 뜻이다.
DNS서버는 이 세 가지가 모두 일치하는 것을 찾고 그 행에 등록되어 있는 회답 항목을 리턴한다.
리소스 레코드 에는 여러 가지 타입이 존재하는데, 대표적인 것은 다음과 같다.
- A 레코드 : 이름으로부터 주소 (Address) 를 리턴
- MX 레코드 : 이름으로부터 메일서버를 리턴
- PTR 레코드 : IP로부터 이름을 리턴
- CNAME 레코드 : 이름에 닉네임 (Alias) 를 붙인다
- NS 레코드 : 네임서버 (DNS서버) 의 IP주소를 등록한다
- SOA 레코드 : 도메인 자체의 속성 정보를 담는다
도메인명은 점(.) 을 기준으로 계층이 나누어진다. [www.hotfoxy.com](http://www.hotfoxy.com)
의 경우 com이 최상위 계층, hotfoxy 가 도메인 이름, www 가 서버의 이름이 된다.
액세스 대상의 웹 서버 도메인이 어느 DNS 서버에 등록되어있는지를 찾아야 한다.
인터넷의 도메인에는 com
이나 kr
의 상위에, 루트 도메인 이라는 것이 존재하지만, 여기에는 도메인명이 없기에 편의상 URL에 맨 마지막에 . 을 적지 않는 것 뿐이다.
이 루트 도메인의 DNS 서버에 할당된 IP주소는 전 세계에 13개만 존재하므로, 이 서버들에 DNS 서버를 등록하는 것은 어렵지 않다.
클라이언트에게 요청을 받은 DNS 서버는, 자신의 DNS 리소스 레코드와 비교 후, 가장 최상단인 루트 도메인에 DNS 질의 요청을 보낸다. 그렇게 된다면 최상단 루트 도메인 DNS 서버는 하위 DNS 서버의 주소를 리턴할 것이고, 질의를 보냈던 DNS 서버는 다시 질의를 전달받은 그 주소로 보내는 작업을 반복하여, 결과를 얻어낸 뒤 클라이언트에게 리턴한다.
하나의 DNS 서버에 다양한 계층의 도메인을 등록하기도 하고, 캐싱을 사용하기 때문에 이보다 더욱 간결하고 빠르게 동작되는 것이 일반적이다.
정리
- DNS서버에 질의가 들어오게 되면, 우선 자신이 가진 캐시와 DNS 리소스 레코드와 비교한다.
- 만일 데이터가 없다면, 루트 도메인 DNS 서버에 질의를 보내고, 포워딩을 여러 번 받아 원하는 레코드를 알아내어 요청했던 클라이언트에게 되돌려준다.
프로토콜 스택에 메시지 송신을 의뢰한다
OS 내부의 프로토콜 스택에 메시지 송신을 의뢰할 때에는 소켓 라이브러리의 기능들을 순차적으로 호출해야 한다.
데이터를 송수신 할 때에 양자 사이를 파이프로 연결하는 동작이 선행되어야 한다. 이 파이프의 양 끝단 출입구는 소켓 이라고 부른다.
일반적으로 서버측에서 소켓을 열어 두고 파이프의 연결을 기다리며, 연결 종료는 서버나 클라이언트 중 어느쪽이 먼저 되든 상관은 없지만 어플리케이션 프로토콜에서 정해지곤 한다.
따라서 데이터의 송 수신 동작은 다음 네 단계로 이루어진다.
- 소켓을 만든다 (소켓 작성 단계)
- 서버측의 소켓에 파이프를 연결한다 (접속 단계)
- 데이터를 송수신한다 (송 수신 단계)
- 파이프를 분리하고 소켓을 말소한다 (연결 끊기 단계)
소켓을 만들게 되면, 소켓 하나 하나를 식별할 수 있게 해주는 디스크립터 라는 것이 돌아오므로, 어플리케이션에서는 이를 가지고 사용한다.
파이프를 연결하는 접속 단계에서는, 소켓 라이브러리의 connect
를 호출하게 되는데, 이 때 디스크립터, 상대의 IP 주소, 포트 번호 라는 세 가지 값이 필요하다.
클라이언트에서 소켓을 만들 때, 프로토콜 스택은 적당한 포트를 골라 할당하게 되고, 이후 서버에 접속할 때 이를 서버측에 통지한다.
데이터의 송신은 소켓의 write
에 디스크립터와 송신 데이터를 넣어 이루어지고, 데이터의 수신은 소켓의 read
를 통해 수신 버퍼 메모리로 읽어들이고 어플리케이션으로 메시지를 전달하게 된다.
연결 끊기 단계는 소켓의 close
를 통해 이루어지고, HTTP의 경우 웹 서버측에서 연결 끊기를 먼저 시도하고 확인하게 된다.
HTTP 프로토콜의 경우 하나 하나의 리소스를 별도로 취급하여 개별로 접속, 송수신, 연결 끊기를 반복하게 되는데, 이를 개선하고자 HTTP 버전 업이 이루어지고 있다.
정리
- OS의 프로토콜 스택에서의 네트워크 송수신은 네 가지 단계로 이루어진다.
socket
을 만들게 되면 디스크립터가 리턴되어 이를 사용할 수 있는데, 이후 연결이 수립되게 되면 상대방의 IP주소와 포트가 이 디스크립터에 기록된다.socket.connect
를 통해 상대의 IP, 포트를 지정하여 연결을 수립한다.socket.write
를 통해 데이터를 송신하고,socket.read
를 통해 수신 버퍼를 거쳐 메시지를 수신한다.socket.close
로 연결을 끊게 되는데, 이때 끊는 주체는 프로토콜에 따라 다를 수 있다.
'공부한 이야기 > 네트워크' 카테고리의 다른 글
1% 네트워크 II-I IP와 이더넷의 패킷 송수신 동작 (0) | 2023.04.29 |
---|---|
1% 네트워크 II : TCP/IP의 데이터를 전기 신호로 만들어 보낸다 (0) | 2023.04.29 |
모두의 네트워크 IX : 무선 랜 이해하기 (0) | 2023.04.29 |
모두의 네트워크 VIII : 네트워크의 전체 흐름 살펴보기 (0) | 2023.04.29 |
모두의 네트워크 VII : 응용 계층 (0) | 2023.04.29 |