출발점은 브라우저에서 URL을 입력하는 곳
HTTP 프로토콜로 액세스하는 경우
http://user:password@www.cyber.co.kr:80/dir/file1.htm
브라우저가 처음 하는 일은 웹 서버에 보내는 리퀘스트의 메시지를작성하기 위해 이 URL을 해독하는 것
URL의 요소
URL의 예
http://www.lab.cyber.co.kr/dir1/file1.html
http://www.lab.cyber.co.kr/dir/
- 파일명을 생략할 때를 대비하여 파일명을 미리 서버측에 설정하는 페이지 '/dir/index.html'로 이동
http://www.lab.cyber.co.kr/ or http://www.lab.cyber.co.kr
- 디폴트 페이지 'index.html'로 이동
HTTP 프로토콜은 클라이언트와 서버가 주고받는 메시지의 내용이나 순서를 정한 것
응답 메시지의 포맷도 기본적인 개념은 리퀘스트 메시지와 같다.
응답 메시지의 경우 정상 종료했는지, 오류가 발생했는지, 실행결과를 나타내는 스테이터스 코드가 담긴 첫번째 행이 리퀘스트 메시지와 다름
리퀘스트 메시지에 쓰여있는 URI는 한 개만으로 결정되어 있으므로 파을일 한번에 한 개씩만 읽을 수 있기에 파일을 따로따로 읽는다.
ex) 한 문장에 3개의 영상이 포함되어 있다면 총 4회 (문장 + 영상 파일 3개)의 리퀘스트 메시지를 웹 서버에 보내야 한다.
브라우저는 URL을 해독하거나 HTTP 메시지를 만들지만, 메시지를 네트워크에 송출하는 기능은 없으므로 OS에 의뢰해서 송신하는데 URL 안에 쓰여진 서버의 도메인 명에서 IP 주소를 조사해야 한다.
인터넷이나 사내 LAN은 TCP/IP의 개념에 기초하여 만들어졌으므로 이에 맞춰 설명합니다.
TCP/IP는 서브넷이라는 작은 네트워크를 라우터로 접속하여 전체 네트워크가 만들어진다고 생각할 수 있습니다.
네트워크 번호(OO동) + 호스트 번호(XX번지) => IP 주소
IP주소에 따라 엑세스 대상이 어디에 있는지 판단하고 운반
위의 질문을 해결해주는 DNS(Domain Name System)
DNS 서버에 'www.lab.cyber.co.kr'이라는 서버의 IP 주소를 가르쳐주세요 라고 질문한다.
DNS 서버에 조회 메시지를 보내고, 거기에서 반송되는 응답 메시지를 받는다는 것 => DNS 서버에 대해 클라이언트로 동작한다
DNS 클라이언트에 해당하는 것을 리졸버라고 부릅니다.
리졸버의 실체는 Socket 라이브러리에 들어있는 부품화한 프로그램
<메모리 영역> = gethostbyname("www.lab.cyber.co.kr");
이렇게 리졸버를 호출하면 리졸버가 DNS 서버에 조회 메시지를 보내고, DNS 서버에서 응답 메시지가 돌아옵니다. 리졸버는 이를 추출해 브라우저에서 지정한 메모리 영역에 써넣습니다.
브라우저가 웹 서버에 메시지를 보낼 때는 이 메모리 영역에서 IP 주소를 추출하여 HTTP의 리퀘스트 메시지와 함께 OS에 건네주어 송신을 의뢰합니다.
메시지 송신 동작은 리졸버가 스스로 실행하는 것이 아니라 OS의 내부에 포함된 TCP/IP 소프트웨어를 호출하여 실행을 의뢰
DNS 서버의 기본 동작은 클라이언트에서 조회 메시지를 받고 조회의 내용을 응답하는 형태입니다. 조회 메시지에 세가지 정보가 포함되어 있습니다.
ex)
이름 : www.lab.cyber.co.kr
클래스 : IN
타입 : A
=> 클라이언트에 회답하는 항목 : 192.0.2.226
1대의 DNS 서버에 모두 등록하는 것은 불가능합니다. 따라서 정보를 분산시켜 다수의 DNS 서버에 등록하고, 다수의 DNS 서버가 연대하여 어디에 정보가 등록되어 있는지를 찾아내는 구조입니다.
DNS 서버에 등록한 정보에는 모든 도메인명이라는 계층적 구조를 가진 이름이 붙어있습니다.
ex)
www.cyber.co.kr => kr이라는 대한민국에 할당된 도메인 그리고 그 하위에 있는 co는 국내의 도메인을 분류하기 위해 설치된 도메인으로 회사를 나타냅니다. 그 아래에 cyber가 회사에 할당된 도메인이며 www가 서버의 이름입니다.
인터넷에 DNS 서버가 수만 대나 있으므로 일일이 뒤질 수 없습니다.
하위의 도메인을 담당하는 DNS 서버의 IP 주소를 그 상위의 DNS 서버에 등록합니다. 상위의 DNS 서버를 또 그 상위의 DNS서버에 등록하는 식으로 차례대로 등록합니다.
ex) lab.glasscom.com => glasscom.com의 DNS 서버에 등록하고 => glasscom.com의 DNS서버를 com 도메인의 DNS 서버에 등록합니다.
최상위 루트 도메인에서 차례대로 따라간다는 원칙대로 움직이지 않을 수 있습니다. DNS 서버는 한번 조사한 이름을 캐시에 기록할 수 있습니다.
IP주소를 조사했으면 IP 주소의 상대, 여기에서는 액세스 대상 웹 서버에 메시지를 송신하도록 OS의 내부에 있는 프로토콜 스택에 의뢰합니다.
HTTP 메시지는 디지털 데이터 이므로 디지털 데이터를 송신하도록 의뢰한다.
디지털 데이터를 송수신하는 동작은 브라우저 뿐만 아니라 네트워크를 이용하는 애플리케이션 전체에 공통입니다.
데이터를 송수신하는 컴퓨터 사이에 데이터의 통로 같은 것이 있고, 이것을 통해 데이터가 흐르면서 상대 측에 도착한다.
소켓을 만듭니다. (소켓 작성 단계)
서버 측의 소켓에 파이프를 연결합니다. (접속 단계)
데이터를 송수신합니다. (송수신 단계)
파이프를 분리하고 소켓을 말소합니다. (연결 끊기 단계)
<메모리 영역> = gethostbyname("www.lab.cyber.co.kr");
//1. 준비
<디스크립터> = socket(<IPv4 사용>, <스트림형>, ...);
//2. 접속
connect(<디스크립터>, <서버의 IP 주소와 포트 번호>, ...);
//3. 송신
write(<디스크립터>, <송신 데이터>, <송신 데이터 길이>);
//3. 수신
<수신 데이터 길이> = read(<디스크립터>, <수신 버퍼>, ...);
//4. 연결 끊기
close(<디스크립터>);
만든 소켓을 서버 서버측의 소켓에 접속하도록 프로토콜 스택에 의뢰하고 Socket 라이브러리의 connect라는 프로그램 부품을 호출하여 이 의뢰 동작을 실행합니다.
이때, 필요 값은 디스크립터, 서버의 IP 주소, 포트 번호 세가지 입니다.
포트 번호 : IP 주소만으로는 소켓까지 지정할 수 없으므로 포트 번호를 사용, 서버 측의 포트 번호는 애플리케이션의 종류에 따라 미리 결정된 값을 사용
프로토콜 스택에 일을 의뢰합니다.
송신시 포로토콜 스택에 write를 호출하고, 소켓에 연결된 상대 기록되어 있으므로 디스크립터로 소켓을 지정하면 연결된 상대가 판명되어 그곳을 향해 데이터를 송신
수신시 프로토콜 스택에 read에 동작을 의뢰합니다. 수신한 응답 메시지를 저장하기 위해 메모리 영역을 지정(수신 버퍼)
close 라는 프로그램 부품을 호출하여 연결 끊기 단계로 들어가 소켓 사이를 연결한 파이프와 같은 것이 분리되고 소켓도 말소