주소창에 예를들어 www.naver.com을 입력하게 된다면, 어떤일이 벌어지는가?
면접의 단골 질문이지만, 네트워크를 정확히 모르던 나는 어디서 주워들은 지식과 내가 아는 지식을 짬뽕 할ㄹ 수 밖에 없었다.
이 책에서는 이렇게 표현한다. 책을 보면서 적는게 아니라 명확하지 않을 순 있다.
진짜 압축-축약해서 설명해놓은것 같다. 중간중간 까먹은 건 책을 다시보며 적어봣다!
우리는 이중 처음엔 1번과 2번을 공부할 것이다.
브라우저(클라이언트)가 URL을 요청하면, 브라우저는 URL을 해독한다.
URL의 정확한 정의부터 알아보자
단어 그대로, 자원이 어디있는지를 나타내는 규약이다. 이는 특별한 식별자(Uniform)로 알 수 있다.
가령 http://velog.io/foo라는 URL이 있다고 해보자. 우리는 이걸http, //, velog.io, foo
로 나눠 볼 것이다
http
: 이 자리는 프로토콜...은 아니다. 사실 액세스 방법중 하나를 나타낸다.(http는 프로토콜 맞음)//
: 구분자다. 이것 뒤에 웹서버 명(velog.io)가 온다. velog.io
: 웹서버명. 여기에 어떠한 요청을 한다.foo
: 디렉토리다. 웹서버의 하위 디렉토리중 foo
라는 곳에서 파일을 찾는 거시다. 하지만 파일명이 foo
일 수도있다. 이건 하드웨어가 알아서 판단해서 넘겨준다. 결국 우리는, http
프로토콜을 사용해 velog.io
라는 웹서버의 디렉토리(파일) foo
을 달라는 요청(request)를 하는것이다.
http 프로토콜은 클라이언트와 서버가 어떻게 데이터를 주고받을지 정해놓은 규약이다.
이는 요청(request)과 응답(response)로 이루어져있다.
웹서버에 요청을 보낸다. 이는 http가 정해놓은 규약을 따른다.
request message는 URI와 Method로 이루어져 있다.쉽게 말해, 무엇을 어떻게할 것인지 정해놓은 것임. 부가적인 정보가 필요한 경우도 있는데, 그럴땐 header에 부가정보를 담아 보낸다.
=>부가데이터를 담을 수있는 공간은 사실 header말고 body도 있다. 이는 아래에서 다루겠다.
보통 이렇게 요청한다.
Method URI Httpversion
header
body...
웹서버가 요청을 처리하고, 클라이언트에게 응답을 준다. 응답을 줄땐 결과데이터를 response message에 저장한다. 맨 앞에는 status code를 동봉해서 보내준다.(404 not found 같은...).
참고로 requset는 단 한번의 처리만 한다. 따라서 응답으로 html을 받아 출력할때, 불러와야 할 이미지나 영상이 있으면 다시 requset를 보내 웹서버에서 받아온다.
무엇을에 해당하는게 URI다. 이 녀석은 주로 URL의 뒷부분, 그러니까 디렉토리부분부터 파일명까지를 나타낸다. 물론 URL 전체가 URI인 경우도 있다.
어떻게에 해당하는게 Method다. 종류는 여러가지가 있지만, 자주 사용되는 4가지를 소개하겠다.
requset message에 부가적인 데이터를 전달할 때 사용하는 공간이다. 기본적으로 요청메세지에 header와 body가 존재하고, 클라이언트가 POSt로 요청한게 아니라면 body는 여백이다.
header엔 다양한 부가정보들이 들어간다.
다 외울필요는 없다
IP는 각기 다른 컴퓨터를 구분짓기위한 주소다.
111.222.111.0
에서 111.222.111
은 네트워크 번호를 나타내고, 0
은 호스트 번호를 나타냄.TCP/IP방식은 서브넷이라는 작은 네트워크가 라우터에 접속하여 네트워크가 만들어 진다고 생각하면 된다.
개인 컴퓨터를 묶엇 서브넷. 그걸 라우터가 관리하고, 그렇게 묶인 라우터들은 다시금 서브넷을 이룬다.
서브넷 > 라우터 > 서브넷 > 라우터 > 서브넷...
이때 네트워크번호를 서브넷에 할당한다. 그러면 IP의 마지막 bit로 PC들을 구분한다
=> 111.111.111.1
과 111.111.111.2
는 같은 네트워크상에 있는 것이다.
DNS는 도메인 네임과(우리가 흔히 접하는 URL) 서버의 IP를 매칭시켜준다.
우리가 URL을 입력하는 순간, DNS에 서버의 IP를 조회한다. 이는 Socket이라는 라이브러리에서 이루어진다. socket은 OS에 포함에되어있는 네트워크 기능을 애플리케이션에서 호출할 수 있게 만든것이다.
...
<저장할 메모리 영역> = gethostbyname(url)
...
<http 메시지 송신>
결국 컴퓨터는 socket라이브러리를 사용, DNS에서 IP를 가져와 메모리영역에 저장. 그후 저장된 메모리 영역을 사용해서 Http 송신을 한다.
왜 가끔 컴퓨터가 느리면 구글의 dns서버로 바꾸라던가(8.8.8.8), cloud flare사의 dns서버로 바꾸라던가(1.1.1.1) 하는 말들이 있었다. 그건 수동으로 설정했던고, 기본적으론 통신사에서 dns서버의 ip 주소를 부여해준다.
dns서버는 기본적으로 클라이언트의 요청에 응답하는 구조로 되어있다.
우리가 DNS서버로 요청을 보낼때 3가지 정보를 담아서 보낸다
DNS서버는 DB(정확히는 리소스 레코드)에서 셋 다 일치하는 정보를 찾아 요청한 클라이언트에게 넘겨준다.
사실 사내 PC라던가, 네트워크를 구성하는 크기가 매우 작을 경우 위처럼 어느 DNS서버에 IP를 딱 요청해서 받아올 수 있다. 그러나 현재의 네트워크양은 방대하다. 따라서 정보를 세계 곳곳 DNS버에 분산등록하는 것이 바람직하다.
DNS서버에 등록된 정보에는 도메인 명이라는 계층적 구조를 가진 이름이 붙어잇다.
ex ) www.naver.com
=> com 아래에 naver가 있고 www가 있음.
최상위 계층은 com처럼 보이지만, 사실 눈에 보이지 않는 루트 도메인이 존재한다. 이녀석은 전세계에 13개밖에 존재하지 않아 모든 DNS서버에 주소가 저장되어있다.
=> www.naver.com.(마지막 마침표)
도메인은 계층구조로 나뉘어있고, 각 계층은 DNS서버에 할당되어있다. 마치 자료구조의 트리같은 구조를 가지는데 이를 탐색하는 방법은 쉽다.
주소창에 www.naver.com을 쳐서, DNS서버에 IP를 요청하면 아래의 단계를 거친다.
물론 DNS서버에도 캐시가 존재해서, 캐시를 반환할때도 있다. 이때 캐시에서 보낸 것인지 알려준다.
또한 현실의 DNS서버는 상위, 하위 도메인이 같이 들어있는 경우도 많다. 따라서 위와같이 정석적인 절차를 밟는 경우가 드물다.
다만 캐시는 요청한 주소의 정보가 변했다면 무용지물. 유효기간을 잘 설정해야겠지...?
분명히 말했다. 브라우저에는 네트워크와 물리적으로 송수신 하는 기능이 없다고. 이는 당연한 결과다. 많은 프로그램들이 네트워크와 송수신한다. 따라서 각 프로그램마다 탑재하는 것 보단, 프로그램을 감싸고 있는 OS에서 처리하는 것이 옳다.
이를 도와주는 게 프로토콜 스택이다.
프로토콜 스택은 DNS서버에 IP를 요청할 때 처럼, Socket 라이브러리를 사용한다. 그럼, 어떻게 데이터를 주고받을까?
데이터를 송수신하는 컴퓨터 사이에 파이프가 있다고 생각해보자. 이 파이프를 통해 데이터가 송,수신 된다.
착각하기 쉬운점은 파이프가 원래 존재하는게 아닌, 먼저 파이프부터 연결해야함.
socket()
를 사용하여 소켓 생성connect()
를 사용하여 파이프라인을 연결한다. 이때 필요한 정보는 디스크립터, 서버의 IP, 포트 번호.write()
를 활용해 파이프라인을 타고 데이터를 넘긴다. 그러면 프로토콜 스택이 송신데이터를 서버에 송신! 서버가 로직대로 처리하고 응답메시지를 준다.read()
를 사용해 프로토콜 스택에 수신 동작의뢰. 수신받은 데이터는 수신 버퍼에 할당. 이는 프로그램 내부에 미리 할당되어있음. 이후 수신 버퍼의 내용을 프로그램에 전달.close()
호출. 이 메시지가 클라이언트측에 전달되어서, 클라이언트는 read()
로 close()
가 됐단 사실을 알고, 연결을 끊는다.정리
대부분의 내용은 [ 성공과 실패를 결정하는 1%의 네트워크 원리 ] 라는 책에서 발췌했습니다.
https://www.yes24.com/Product/Goods/90640081