지난 번 글에서 컴퓨터 네트워크 시스템의 전반적인 틀을 알아보았다면, 이번 글에서는 인터넷 프로토콜 스택의 5개 계층 중 가장 상위에 속하는 애플리케이션 계층에 대해서 알아보고자 한다. 애플리케이션 계층은 우리가 직접 볼 수 있는 표면적인 층이다. 앞선 글에서 언급하였듯이 본 연재는 읽는 이들의 흥미 유발과 이해를 돕기 위해 상위에서 하위 계층으로 내려가는 하향식 접근법을 택하였는데, 애플리케이션 계층은 이 접근법을 채택하였을 때 가장 처음 접하게 되는 층이다. 우리가 이용하고 있는 서비스(인스타그램,페이스북,구글,네이버 메일 등)은 모두 네트워크 애플리케이션의 예들로 이 애플리케이션들이 네트워크 측면에서 어떻게 동작하고 기능하는지 본 글을 통해 소개하겠다.
1. 네트워크 애플리케이션의 원리
네트워크 애플리케이션을 개발할 때 중요한 점 한 가지는 서버와 클라이언트로 구분되는 두 종단 시스템 간에 통신할 수 있는 프로그램을 작성해야 한다는 것이다. 이 때 유의할 점은 우리가 애플리케이션 계층의 개발을 신경 쓸 때, 그 하위 계층의 개발은 신경쓰지 않아도 된다는 것이다. 즉 네트워크의 가장자리에서 작동하는 소프트웨어를 작성할때 링크나 라우터 단의 개발은 거의 작성하지 않아도 된다. 애플리케이션 개발자는 하위 네트워크 구조는 고정되어 있다고 가정하고 개발에 임할 수 있다는 뜻이다. 이러한 계층 간의 단절과 연결이 인터넷 애플리케이션의 발전에 큰 기여를 하였다고 할 수 있다.
애플리케이션 개발자는 애플리케이션을 개발하고자 할 때, 우선 현대 네트워크 시스템에서 사용되는 2가지 '애플리케이션 구조(Application Architecture)' 중 하나를 선택해야 한다. 첫번째 애플리케이션 구조는 '클라이언트-서버 구조(Client-server Architecture)'이다. 흔히 웹사이트, 전자메일, 파일 전송 등에서 널리 쓰고 있는 이 구조는 서로 통신하지 않는 클라이언트 호스트들의 요청을 항상 켜져 있는 서버 호스트가 응답하는 방식으로 통신한다. 서버 호스트는 고정된 IP주소를 가지고 있어 클라이언트 호스트가 항상 같은 주소로 요청을 보낼 수 있도록 한다. 단일 웹서버가 다수의 클라이언트들의 요청을 받아야 하는 구조인 것이다.구글,바이두,네이버같은 거대한 웹사이트들은 무수하게 많은 클라이언트 호스트들의 요청을 받게 되어 단일 웹서버만으로는 요청을 모두 감당하기 힘들 수도 있다. 이때 '데이터 센터(Data Center)'가 웹 서버의 부하를 줄여주는 데 도움을 준다. 두번째 애플리케이션 구조는 'P2P구조(Peer to Peer Architecture)'이다. 위의 클라이언트-서버 구조와는 달리 P2P구조에서는 항상 켜져있는 거대한 서버에 의존하지 않는다. 대신 '피어(peer)'라고 불리우는 호스트들이 서로 직접 통신하도록 한다. 대표적인 예로는 P2P구조를 사용해서 파일 공유를 가능하게 해주는 비트 토렌트가 있다. 이 구조는 호스트들끼리의 통신이 어떠한 서버를 통하지 않고 직접 이루어지므로 어떠한 호스트라도 클라이언트이자 동시에 서버가 될 수 있다.
정확한 서버와 클라이언트의 정의는 다음과 같다.
두 프로세스 간의 통신 세션에서 통신을 초기화하는 프로세스를 클라이언트라 하고, 세션을 시작하기 위해 접속을 기다리는 프로세스를 서버라고 한다.
그렇다면 프로세스(종단 시스템에서 실행되는 프로그램)는 메시지를 어떻게 주고 받을 수 있을까? 우선 프로세스는 소켓을 통해 네트워크로 메시지를 보낸다. 소켓과 프로세스는 종종 출입구와 집으로 비유되는데, 집에서 화물(메시지)을 보내려면 우선 출입구를 통해야 하기 때문이다. 화물을 전달받은 집 또한 출입구를 통해 화물을 집으로 들일 것이다. 소켓을 통해 네트워크로 떠난 메시지는 목적지를 향해 이동한다. 이때 메시지는 목적지 호스트의 IP주소와 포트 번호를 통해 올바른 목적지를 알 수 있다. 포트 번호는 같은 호스트에서 사용하고 있는 프로세스가 다수일 수도 있기 때문에(출입문이 여러개 일수도 있기 때문에) 그 문 중 어떤 문이 자기가 갈 곳인지 식별하기 위해 필요하다. 이렇게 목적지를 향해 가는 메시지를 안전하게 통과시키는 역할은 애플리케이션 계층 아래의 트랜스포트 계층이 맡는다. 이 트랜스포트 계층의 트랜스포트 프로토콜은 애플리케이션에게 메시지가 올바르게 전달될 수 있도록 다양한 서비스를 제공할 수 있다. 이 서비들은 크게 4가지로 나누어진다.
1. 신뢰적 데이터 전송
2. 처리량
3. 시간
4. 보안
애플리케이션 개발자들은 애플리케이션에게 위의 4가지 서비스를 제공하거나 제공할 수 없는 2가지의 트랜스포트 프로토콜 중 하나를 선택할 수 있다. 이 2가지는 'TCP(Transmission control protocol) '과 'UDP(User datagram protocol)' 이다. 이 중 TCP 서비스는 애플리케이션에게 연결지향형 서비스와 신뢰적 데이터 전송을 제공해줄 수 있다. 연결지향형 서비스란 두 호스트들이 '핸드셰이킹(HandShaking)'이라고 불리우는 전송 제어 정보 교환 과정 후에 연결을 유지함으로써 두 프로세스가 동시에 메시지를 주고받을 수 있게 해주는 서비스이다. 신뢰적 데이터 전송은 후에 자세히 알아보겠지만 통신 프로세스가 전송한 데이터를 순서에 맞게, 손실되지 않게 목적 프로세스까지 안전하게 전달함을 보장하는 서비스이다. 이것이 어떻게 가능한지는 차후에 알아보도록 하자. 이 외에도 TCP는 혼잡 제어와 공평성 유지 서비스도 제공한다. UDP 서비스는 최소한의 서비스만을 제공하는 간단한 트랜스포트 프로토콜이다. UDP는 비연결형으로 TCP의 핸드셰이킹 과정이 필요없으며 비신뢰적으로 출발한 메시지가 안전하게 도착함을 보장하지 않는다.
트랜스포트 계층 프로토콜에 대하여 알아보았음으로 이제 본 글의 주제인 애플리케이션 계층으로 돌아오자. 애플리케이션 계층은 트랜스포트 프로토콜에게 메시지를 전달하기 전에 메시지를 구성해야 할 필요가 있는데, 이 역할은 애플리케이션 계층 프로토콜이 수행한다(화물을 보내기 전에 화물을 적절히 포장하고 송장을 붙이는 것처럼). 현재 애플리케이션 프로토콜로는 'HTTP(hyper text tranport protocol)', 'FTP(file transfer protocol)','DNS(domain name service)' 등이 있다.
2. HTTP
웹의 애플리케이션 계층 프로토콜인 HTTP는 클라이언트 프로그램과 서버 프로그램이 HTTP 메시지를 교환하여 통신할 수 있게 해준다. HTTP는 웹 클라이언트가 웹 서버에게 웹 페이지를 어떻게 요청하는지, 서버가 클라이언트에게 어떻게 웹 페이지를 전송하는지를 정의한다. 이 HTTP는 TCP를 트랜스포트 프로토콜로 사용한다. 위에서 기술한 대로, 클라이언트 호스트는 TCP라는 소켓 인터페이스로 HTTP 메시지를 보내고 받게 된다. 또한 웹은 클라이언트-서버 구조를 가지는데, 이로인해 웹 서버는 항상 켜져 있고 고정 IP주소를 가지며 다수 호스트들의 요청에 응답한다. 이때 HTTP서버는 클라이언트가 보낸 메시지와 상태를 기억하지 않으므로 HTTP를 '비상태 프로토콜(stateless protocol)'이라고 한다.
HTTP가 TCP 서비스를 이용함으로써 생기는 2가지 선택사항이 있다. 이는 호스트끼리의 요구와 응답이 같은 연결상으로 보내지는 지속 연결 방식인지, 혹은 다른 연결을 사용하는 비지속 연결로 나누어진다. 우선 비지속 연결은 HTTP 클라이언트와 서버가 주고받는 한 쌍의 요구와 응답이 끝나면, TCP 연결이 끊어진다. 즉 각 객체의 전송에 대한 각각의 연결이 설정되어야 한다는 뜻이고, 수많은 클라이언트들의 요청을 다루어야 하는 웹 서버에게는 큰 부담이 된다. 반면에 지속 연결에서는 한 번의 연결이 성사되면 다음 객체를 전송할 때도 같은 연결을 사용해 일정 기간 사용되지 않거나, 두 호스트 중 하나가 연결을 끊을 때까지 계속 연결이 유지된다.
그렇다면 HTTP를 통해 보내는 메시지는 무엇으로 이루어져 있을까. 우선 요청 메시지부터 알아본다. 요청메시지는 크게 요청 라인과 헤더 라인으로 나누어진다. 요청 라인은 GET,POST,HEAD,PUT,DELETE 등을 포함하는 방식 필드와 객체 주소를 적는 URL 필드, HTTP 버전 필드를 갖는다. 헤더 라인은 객체가 존재하는 Host 라인, 지속/비지속 연결을 설정하는 Connection 라인, 브라우저 타입을 명시하는 User-agent 라인, 사용언어를 명시하는 Language 라인 등으로 이루어져 있다. 헤더 라인의 CR,LF(carriage return, line feed) 이후에는 '개체 몸체(entity body)'가 존재한다. 응답 메시지는 상태 라인과 헤더 라인, 그리고 개체 몸체로 이루어져 있다. 상태 라인은 프로토콜 버전 필드, 상태 코드, 상태 메시지를 갖는다. 상태 코드는 유명한 404 not request를 포함한 여러 코드를 포함한다. 상태 메세지는 OK의 경우 모든 것이 양호함을 나타낸다.
앞서 HTTP 서버는 클라이언트의 상태를 저장하지 않는 비상태 프로토콜을 사용한다고 했다. 하지만 사이트가 사용자를 추적할 필요가 있을 때에는 '쿠키(cookie)'를 사용한다. 쿠키는 HTTP 메시지에 set-cookie 헤더를 사용해 사용자를 추적한다. 이 과정은 특정 사용자에게 식별 번호를 부여해 사용자가 방문한 페이지, 활동을 알 수 있도록 함으로써 가능하다. 인터넷 쇼핑 사이트에서 장바구니에 담은 물건이 다음 페이지에 가서도 유지되는 것은 쿠키의 존재 덕분에 가능한 상황이다.
3. 인터넷 전자메일
인터넷 전자메일에 사용되는 대표적인 애플리케이션 프로토콜은 'SMTP(simple mail transfer protocol)'이 있다. SMTP는 송신자의 메일 서버로부터 수신자의 메일 서버로 메시지를 전송하는 역할을 한다. SMTP는 고전적인 프로토콜이기 때문에 ASCII로 데이터를 변환해야 하는 번거로움이 있지만 여전히 현재에도 전자메일 프로토콜의 중심에 있다. SMTP로 전자메일이 발송되고 수신되는 과정을 알아보자.
1. 우선 전자메일 송신자의 사용자 에이전트가 그의 메일 서버에 보낼 메일을 메시지 큐에 올린다.
2. SMTP의 클라이언트 측은 수신자의 SMTP 메일 서버에게 TCP 연결을 설정한다.
3. TCP에서 이루어지는 핸드셰이킹 이후 클라이언트는 TCP연결을 통해 메일을 서버로 발송한다.
4. 수신자의 메일 서버에서 메시지를 수신하고, 이를 메일 박스로 보낸다.
5. 수신자는 원하는 시간에 그의 사용자 에이전트를 통해 메일을 읽는다.
이 과정에서 중요한 것은 메일 서버와 메일 박스의 존재, 그리고 수신자는 자신이 원할 때 메일을 읽을 수 있다는 점이다.
메일 수신자는 메일박스에서 메시지를 읽을 수 있지만 자신의 로컬 PC로 메시지를 이동시키지는 못한다. SMTP는 메시지를 가져오는 Pull 동작을 못하는 Push 프로토콜이기 때문이다. 이를 가능하게 해주는 것은 메일 접속 프로토콜이다. 메일 접속 프로토콜은 POP3,IMAP이 있다.
마지막으로 HTTP와의 비교를 통해 깊은 이해를 가져보자. 우선 HTTP와 SMTP는 모두 TCP 지속 연결을 사용한다는 공통점이 있다. 하지만 HTTP는 원칙적으로 Pull 프로토콜이다. 즉 클라이언트가 서버에게서 원하는 객체를 가져오는 방식이다. 그에 비해 SMTP는 Push 프로토콜으로, 송신 서버가 메일을 수신 서버로 보내는 방식이다. 또 HTTP는 텍스트와 이미지, 미디어를 각각의 개체로 다루는데 비해, SMTP는 이 모두를 하나의 메시지로 만든다. 마지막으로 SMTP는 ASCII 타입의 문자만을 사용해 이외의 메시지는 인코딩이 필요한 반면 HTTP는 이같은 과정이 불필요하다.
4. DNS-인터넷 디렉터리 서비스
우편이나 화물이 올바르게 전송되려면 목적지 주소를 정확하게 알아야 한다. 웹 상에서 이 주소역할을 하는 것은 호스트 네임이다. 하지만 호스트 네임은 인간에겐 친숙하지만 라우터나 링크 등의 2진법 사용자들에겐 처리하기가 곤란한 문제가 있다. 이를 해결하기 위해 나온 주소가 IP주소이다. DNS 서비스는 이 호스트 네임과 IP 주소간의 괴리를 좁혀주기 위해 나타난 서비스이다. DNS는 우리에게 친숙한 호스트 네임을 IP주소로 변환하는 역할을 한다. 이 외에도 DNS는 호스트 앨리어싱(같은 IP 주소의 여러 개의 호스트 네임 지원), 메일 서버 앨리어싱(호스트 네임과 메일 서버 간의 전환),부하 분산(같은 IP주소 요청으로 들어오는 질의의 분산) 등의 역할을 한다. 그렇다면 DNS가 구체적으로 어떻게 동작하는지 알아보자. 우선 클라이언트 호스트가 서버 호스트의 목적지를 알고 싶다고 가정하고, 호스트 네임만을 알고 있다고 하자. 우선 요청 호스트인 클라이언트는 호스트 네임을 포함한 질의를 보낸다. 이 메시지는 로컬 DNS 서버가 중간에 가로챈다. 그 후 해당 메시지를 루트 DNS 서버에게 전달한다. 루트 DNS서버는 호스트 네임 중 일정 부분을 파악해(ex: edu,com 등) 그 주소를 TLD 서버로 보낸다. TLD 서버는 해당 주소를 책임지는 책임 DNS 서버의 IP주소를 로컬 DNS 서버에게 응답한다. 그 후 로컬 DNS 서버는 전달받은 IP주소를 사용해 질의를 보내고, 마지막으로 목적지 주소의 IP 주소를 파악하게 된다. 이 긴 여정에서 클라이언트 호스트가 전달한 질의를 전달받은 서버가 같은 질의를 통해 다른 서버로 보내는 질의를 재귀적 질의라 하고, 전달받은 질의를 다시 클라이언트 호스트에게 IP주소를 알고 있는 다른 DNS서버의 주소를 알려주는 질의를 반복적 질의라고 한다.
DNS에 대한 단락을 마치면서 마지막으로 우리가 특정한 웹 사이트를 방문하려할 때 어떤 상황이 진행되는지 알아보자. 우선 클라이언트가 메시지를 보낼 호스트 주소를 적어서 보낸다. 다음 로컬DNS 서버가 호스트 네임의 IP 주소를 알기 위해 해당 메시지를 가로챈다. 로컬 DNS서버는 TLD서버에 해당 질의를 다시 보내(TLD 서버는 보통 com 형식을 책임지는 서버일 경우가 많을 것이다) 질의 메시지의 IP주소를 알고 있는 IP주소를 받는다. 최종적으로 로컬 DNS서버는 클라이언트 호스트에게 원하는 목적지의 IP 주소를 대답해 TCP 프로토콜이 해당 IP주소로 연결을 유지하도록 해준다.
이상으로 애플리케이션 계층의 다양한 구성요소들을 살펴보았다. 해당 장을 통해서 네트워크의 가장자리단에 속하는 애플리케이션 계층이 어떤 역할을 하며, 어떤 프로토콜을 가지고 있고, 이들이 어떻게 작동하는지 알 수 있을 것이다. 본 글에서 언급한 HTTP,SMTP,DNS 프로토콜 말고도 비디오 스트리밍,CDN에 대한 논의도 활발하게 진행되고 있으며 흥미로운 주제이다. 다음은 애플리케이션 계층의 하단에 존재하는 트랜스포트 계층에 대한 주제로 글을 진행하고자 한다. 다음 장에서 TCP와 UDP에 대한 더 깊은 논의가 이루어지며, 본 글에서 언급했던 TCP의 신뢰적 데이터 전송,혼잡 제어 등의 기능들이 어떻게 동작하는지 알아보고자 한다.
'Network' 카테고리의 다른 글
용어를 확실히 - stateful vs stateless (0) | 2019.12.24 |
---|---|
컴퓨터 네트워크 4-2. 네트워크 계층 : 제어 평면 (0) | 2019.12.15 |
컴퓨터 네트워크 4-1. 네트워크 계층 : 데이터 평면 (0) | 2019.12.14 |
컴퓨터 네트워크 3. 트랜스 포트 계층 (0) | 2019.12.12 |
컴퓨터 네트워크 1. 네트워크란? (0) | 2019.12.06 |