Post Lists

2019년 2월 16일 토요일

Networking Chapter2 : Application Layer

network applications의 개념적 측면과 구현 측면을 공부
어플리케이션, 클라이언트와 서버, 프로세스들, transport-layer interfaces를 포함하여
주된 application-layer 개념 정의
Web, e-mail, DNS, P2P file distribution을 포함하여 몇 가지 네트워크 어플리케이션 상세히 조사
TCP와 UDP 둘 다에 대해 네트워크 어플리케이션 개발을 다룸.
특히 socket API를 공부하고, 몇 가지 간단한 클라이언트-서버 프로그램을 파이썬으로 다룸.

* Principles of Network Applications
  • 다른 end systems에서 작동하고 네트워크에 대해 서로 의사소통하는 프로그램을 작성하는 것이 네트워크 어플리케이션 개발의 핵심이다. 중요하게도, 너는 라우터 또는 link-layer switches 같은 network 핵심 장치에 대해 작동하는 소프트웨어를 쓸 필요는 없다.
- Network Application Architectures
  • application 개발자의 관점에서, 네트워크 아키텍쳐는 고정되어있고, 어플리케이션에 특정한 서비스들의 집합을 제공한다. 반면에 application architecture는 어플리케이션 개발자에 의해 설계되고, 그 어플리케이션이 다양한 end systems에 대해 어떻게 구조화될지를 지배한다. 그 어플리케이션 아키텍쳐를 고를 때, 어플리케이션 개발자는 현대의 네트워크 어플리케이션에서 사용되는 두 개의 우세한 아키텍쳐 패러다임 중의 하나위에 그릴 가능성이 높다: the client-server architecture or peer-to-peer (P2P) architecture.
  • client-server architecture에서, server라고 불려지는 always-on host가 있다. 그것은 clients라고 불려지는 많은 다른 호스트들로부터 요청을 서비스해준다. client-server 아키텍쳐에서, 클라이언트들은 서로 직접적으로 의사소통 하지 않는다는 것에 주목해라. client-server architecture의 또 다른 특징은 그 서버가 고정되고 잘 알려진 주소인 IP address라고 불려지는 것을 가지고 있다. 그 서버가 고정되고 잘 알려진 주소를 가지고 있고, 항상 켜져있기 때문에, 한 클라이언트는 그 서버의 IP 주소에 한 packet을 보내서 그 버서에 항상 접근할 수 있다. client-server 아키텍쳐를 가진 더 잘 알려진 어플리케이션들은 Web, FTP, Telnet, e-mail을 포함한다.
  • P2P architecture에서 데이터 센터에 있는 전용 서버에 대한 최소한의 (또는 전혀 없다) 의존성이 있다. 대신에 그 어플리케이션은 peers라고 불리는 간헐적으로 연결된 호스트들의 쌍 사이의 직접적인 의사소통을 이용한다. 그 peers들은 서비스 제공자에 의해서 소유되지 않지만, 대신에 대부분의 사용자들이 집, 대학, 사무실에 거주하면서 사용자들에 의해서 통제되는 데스크탑과 랩탑이다. 그 peers들은 전용 서버를 통해 넘기는 것 없이 의사소통 하기 때문에, 그 아키텍쳐는 peer-to-peer라고 불려진다. 오늘날의 가장 인기있고 traffic이 많은 어플리케이션 대부분의 P2P 아키텍쳐들이다. 이러한 어플리케이션들은 file sharing (예를들어, BitTorrent), peer-assisted download acceleration (e.g., Xunlei), Internet Telephony (e.g., Skype), and IPTV (e.g., Kankan and PPstream).  어떤 어플리케이션들은 클라이언트-서버와 P2P 요소들을 둘 다 합하여 hybrid 아키텍쳐를 가진다. 예를들어, 많은 인스턴트 메세징 어플리케이션에 대해, 서버들은 사용자들의 IP 주소를 추적하기 위해 사용되지만, 사용자간 메세지들은 user hosts 사이에 직접적으로 보내진다 (중간 서버를 거치지 않고).
  • P2P architectures의 가장 강력한 특징 중의 하나는 그것들의 self-scalability이다. 예를들어, P2P file-sharing application에서, 각 peer가 파일들을 요청하여 workload를 생성할지라도, 각 peer는 files을 다른 peers에게 분배하여 그 시스템에 또한 service capacity를 더한다. P2P 아키텍쳐는 또한 비용 효과적이다. 왜냐하면 그것들은 보통 주요한 서버 인프라와 server bandwidth를 요구하지 않기 때문이다 (데이터 센터들을 가진 클라이언트-서버 설계와 대조적으로). 그러나, 미래 P2P 어플리케이션들은 세 가지 중대한 어려움에 직면한다 :
    • 1. ISP Friendly. 대부분의  residential ISPs (DSL과 ISPs를 포함하는) "asymmetrical" bandwidth usage를 위해, 즉 upstream traffic보다는 더 많은downstream을 위해 크기가 정해졌다. 그러나 P2P video streaming과 file distribution applications는 서버에서 residential ISPs로 가는 upstream traffic을 옮기고, 그것으로 인해 ISPs에 많은 부담을 준다. 미래 P2P 어플리케이션들은 그것들이 ISPs에 친화적으로 설계될 필요가 있다.
    • 2. Security. 그것들의 매우 분산되고 open nature 때문에, P2P 어플리케잇녀들은 보안에 위험이 될 수 있다.
    • 3. Incentives. 미래 P2P 어플리케이션들의 성공은 또한 incentive design의 어려움인 bandwidth, storage, 어플리케이션에 대한 연산 자원을 무료로 봉사하도록 사용자들을 설득하는 것에 달려있다.
  • 실제로 의사소통 하는 것은 프로그램들이 아니라 processes이다.한 프로세스는 한 end system에서 작동하는 한 프로그램으로서 생각되어질 수 있다. 프로세스들이 같은 end system에서 작동할 때, 그것들은 interprocess communiation으로 의사소통할 수 있고, end system의 운영체제에 의해 지배받는 규칙을 사용한다. 그러나 우리는 다른 hosts에서 작동하는 프로세스들이 어떻게 의사소통 하는지에 관심이 있다 (잠재적으로 다른 운영체제를 가진). 두 개의 다른 end systems에서 프로세스들은 computer network를 가로질러 messages를 교환하여 서로 의사소통 한다. 보내는 프로세스가 메세지를 만들고 네트워크에 보낸다; 받는 프로세스는 이러한 메세지들을 받고, 가급적 메세지를 다시보내어 반응한다.
  • network application은 한 네트워크에 대해 서로 메세지를 보내는 프로세스들의 쌍들로 구성된다. 예를들어, 웹 어플리케이션에서, 클라이언트 브라우저 프로세스는 Web server process와 메세지를 교환한다. P2P file-sharing 시스템에서, 한 파일은 한 peer에 있는 프로세스로 부터 다른 peer에 있는 프로세스로 전송된다. 의사소통 하는 프로세스들의 각 쌍에 대해, 우리는 일반적으로 두 프로세스들 중 하나에 client를 다른 것에 server를 label한다. Web으로는, 브라우저가 client process이고 web server가 server process이다. 우리는 client와 server processes를 다음으로 정의한다:
    • 프로세스들의 한 쌍 사이의 communication session의 맥락에서, 그 communication을 시작하는 (즉, 초기에 그 세션의 시작에서 다른 프로세스에 접촉하는) 프로세스가 client라고 labeled 된다. session을 시작하기 위해 접촉되어지길 기다리는 process는 server이다.
  • 한 프로세스에서 또 다른 것으로 보내진 어떤 메세지든 밑에 있는 네트워크를 거쳐야만 한다. 한 프로세스는 socket이라고 불려지는 소프트웨어 인터페이스를 통해 네트워크에, 네트워크로부터 메세지를 주고 받는다. 프로세스와 소켓을 이해하는데 돕는 비유를 고려해보자. 프로세스는 집과 비슷하고, 그것의 소켓은 그것의 문과 비슷하다. 한 프로세스가 다른 호스트에 있는 다른 프로세스에 메세지를 보내길 원할 때, 그것은 그것의 메세지를 그것의 문 밖으로 (socket) 밀쳐낸다. 이 sending process는 그것의 문의 다른 쪽에 그 메세지를 목적지 프로세스의 door까지 전송하는 transportation infrastructure가 있다고 가정한다. 그 메세지가 destination host에 도착했다면, 그 메세지는 receiving process의 door(socket)을 지나고 그 receiving process는 그러고나서 그 메세지에 대해 반응한다. 한 socket은 한 host 내에서 application layer와 transport layer 사이의 interface이다. 그것은 application과 network사이의 Application Programming Interface라고 언급되는데, socket이 네트워크 어플리케이션에 만들어지는 프로그래밍 인터페이스이기 때문이다. 그 어플리케이션 개발자는 소켓의 application-layer side에서 모든 것을 통제하지만, socket의 transport-layer side에 대한 통제권이 없다. application 개발자가 transport-layer side에 대해 가지는 유일한 통제권은 transport protocol의 선택과 아마도 maximum buffer와 maximum segments sizes같은 transport-layer 파라미터들을 고치는 능력이다.
  • 특정한 목적지에 우편을 보내기 위해서, 그 목적지는 한 주소를 가질 필요가 있다. 유사하게, 한 호스트에서 작동하는 한 프로세스가 다른 호스트에서 작동하는 한 프로세스에 패킷들을 보내기 위해서, 그 receiving process는 주소를 가질 필요가 있다. receiving process를 인식하기 위해, 두 개의 정보가 명시될 필요가 있다: (1) host의 주소와 destination host에서 receiving process를 명시하는 (2) identifier. Internet에서 그 host는 IP address에 의해 확인된다 (Chapter 4). IP 주소는 유일하게 호스트를 인식하는 것으로 생각할 수 있는 32-bit quantity이다. sending process는 또한 host에서 작동중인 receiving process를 (좀 더 명확하게, receiving socket을) 확인해야만 한다. 일반적으로 한 host는 많은 네트워크 어플리케이션을 작동시킬 수 있기 때문에 이 정보가 필요하다. destination port number가 (Chapter 3) 이 목적을 한다. 인기있는 어플리케이션들은 특정한 포트 번호를 할당 받아왔다. 예를들어, Web server는 port number 80으로 확인된다. mail server process (SMTP protocol을 사용하는)는 port number 25로 확인된다.
  • socket이 application process와 transport-layer protocol 사이의 interface라는 것을 회상해라. socket의 다른 쪽에서, transport-layer protocol은 receiving process의 socket으로 메세지를 보내는 책임이 있다. 우리는 4개의 수치에 따라 transport-layer protocol이 제공할 수 있는 가능한 서비스들을 분류한다 : reliable data transfer, throughput, timing, and security
  • 패킷들은 컴퓨터 네트워크 내에서 손실될 수 있다. 예를들어, 한 패킷은 한 라우터에 있는 버퍼에서 overflow될 수 있거나, 비트들이 corrupted 된 후에 host나 router에 의해 버려질 수 있다.  전자메일, 파일 전송, 원격 호스트 접근, 웹 문서 전송, 재무 어플리케이션 같은 많은 어플리케이션에 대해, 데이터 손실은 엄청난 결과를 가질 수 있다. 따라서 이러한 어플리케이션을 지원하기 위해, 어플리케이션의 한 끝에서 보내진 데이터가 정확하고 완전하게 그 어플리케이션의 다른 끝에 보내지는 것을 보증하도록 무언가가 처리되어야만 한다. 만약 한 프로토콜이 그러한 보장된 데이터 전달 서비스를 제공한다면, reliable data transfer를 제공한다고 말해진다. transport-layer 프로토콜이 잠재적으로 한 어플리케이션에 제공할 수 있는 한 가지 중요한 서비스는 process-to-process reliable data transfer이다. transport protocol이 이 서비스를 제공할 때, 그 sending process가 그것의 데이터를 socket으로 보낼 수 있고, 그 데이터가 receiving process에 에러없이 도착할 것이라는 완전한 자신감을 가지고 알게 될 수 있다. 그렇지 않을 때, sending process에 의해 보내진 data는 receiving process에 도착하지 않을지도 모른다. 이것은 어떤 데이터 손실 양의 참을 수 있는 대와 오디오/비디오 같은 멀티미디어 어플리케이션 같은 loss-tolerant applications에 대해 수용가능할지도 모른다.
  • available throughput은 한 network 경로를 따라 두 프로세스 사이의 communication session의 맥락에서, sending process가 receiving process에 비트들을 보낼 수 있는 비율이다. 다른 세션들이 그 네트워크 경로를 따라 bandwidth를 공유할 것이고, 이러한 다른 세션들이 오고 갈 것이기 때문에, 이용가능한 throughput은 시간에 따라 요동칠 수 있다. 이러한 관찰들은 transport-layer protocol이 이름하여 어떤 명시된 비율로 보증된 이용가능한 throughput을 제공할 수 있는 또 다른 당연한 서비스를 이끌게 한다. 그러한 서비스로, 어플리케이션은 r bits/sec의 보증된 throughput을 요청할 수 있고, 그 transport protocol은 그러고나서 그 이용가능한 throughput이 항상 적어도 r bits/sec가 되도록 보증할 것이다. throughput 요구사항을 가진 어플리케이션들은 bandwidth-sensitive applications이라고 말해진다. 많은 현재 multimedia applications들은 bandwidth sensitive하다. 비록 어떤 multimedia applications들은 현재 이용가능한 throughput을 match하는 비율로 digitized voice or video를 인코딩하는 adaptive coding technique을 사용할지도 모른다. bandwidth-sensitive applications들이 특정한 throughput requirements를 가질지라도, elastic applications은 이용가능한 많은 또는 적은 throughput을 이용할 수 있다. 전자우편, file transfer, Web transfers가 모두 elastic applications이다.
  • transport-layer protocol은 또한 timing guarantees를 제공할 수 있다. 한 example guarantee는 sender가 socket에 보내는 모든 비트가 receiver의 socket에 100msec가 안되어서 도착하도록 하는 것일지도 모른다. 그러한 서비스는 Internet telephony, 가상 환경, teleconferencing, 멀티플레이어 게임 같은 interactive real-time applications에 매력적일 것이다. 그러한 모든 것은 효과적이기 위해 data 전송에 있어서 tight timing constraints를 요구한다.
  • transport-layer protocol은 한 개 이상의 security services를 어플리케이션에 제공할 수 있다. 예를들어, sending host에서, transport protocol은 sending process에서 전송된 모든 데이터를 암호화 할 수 있고, receiving host에서, transport-layer는 그 데이터가 receiving process에 전달되기 전에 그 데이터를 복호화할 수 있다. 비록 그 데이터가 어느정도 sending and receiving processes 사이에서 관찰될지라도, 그러한 서비스는 두 프로세스 사이에서 기밀성을 제공할 것이다. transport protocol은 또한 confidentiality 외에도, data integrity, end-point authentication같은 다른 security services를 제공할 수 있다.
  • 그 Internet(그리고, 좀 더 일반적으로, TCP/IP 네트워크)은 두 개의 protocols이 어플리케이션에 이용가능하게 만든다: UDP and TCP. 너가 (어플리케이션 개발자로서) 그 Internet을 위해 새로운 네트워크 어플리케이션을 만들 때, 너가 해야할 첫 번째 결정 중의 하나는 UDP or TCP를 쓸지 이다.
  • TCP 서비스 모델은 연결지향 서비스 (connection-oriented service)와 신뢰할만한 데이터 전송 서비스(reliable data transfer service)를 포함한다. 한 어플리케이션이 그것의 transport protocol로 TCP를 요청할 때, 그 어플리케이션은 TCP로부터 이러한 서비스 둘 다를 받는다
    • Connection-oriented service. TCP는 application-level messages가 흐르기 시작하기 전에 서로 client and server exchange transport layer control information을 갖는다. 이 소위 handshaking procedure는 클라이언트와 서버에 경로를 주고, 그들이 패킷들의 맹습에 대해 준비하도록 한다. handshaking phase 이후에, TCP connection은 두 프로세스들의 소켓들 사이에 존재한다고 말해진다. 그 connection은 두 프로세스들이 동시에 그 연결 위에 서로에게 메세지를 보낼 수 있다는 점에서 full-duplex connection이다. 그 어플리케이션이 메세지 보내는 것을 마무리할 때, 그것은 그 연결을 없앤다.
    • Reliable data transerfer service. 의사소통 하는 프로세스들은 에러 없이,그리고 적절한순서로 모든 데이터를 전달하기 위해 TCP에 의존할 수 있다. 그 어플리케이션의 한 쪽이 한 스트림의 바이트들을 한 소켓에 보낼 때, 그것은 놓치거나 중복되는 바이트 없이, receiving socket에 같은 stream의 bytes를전달하기위해 TCP를 믿을 수 있다.
  • TCP는 또한 congestion-control mechanism을 포함하는데, 그것은 의사소통하는 프로세스들의 직접적인 이익이라기 보다는 Internet의 일반적인 welfare를 위한 서비스이다. TCP congestion-control mechanism은 그 네트워크가 sender와 receiver 사이에서 혼잡할 때, 그 보내는 프로세스(client or server)를 압박할 수 있다. TCP congestion control은 또한 network bandwidth의 그것의 공평한 목으로 각 TCP 연결을 제한하려고 한다.
  • UDP는 최소한의 서비스를 제공하는 장식이 없는(no-frills), 가벼운 transport protocol이다. UDP는 connectionless이다. 그래서 그 두 프로세스들이 커뮤니케이션을 시작하기 전에 어떠한 handshaking이 없다. UDP는 unreliable data transfer service를제공한다 - 즉, 한 프로세스가 한 메세지를 UDP 소켓에 보낼때, UDP는 그 메세지가 receiving process에 도착할 거라는 보장을 하지 않는다. 게다가, 그 receiving process에 도착하는 메세지들은 순서없이 도착할지도 모른다. UDP는 congestion-control mechanism을 포함하지 않는다. 그래서, UDP은 sending side는 그것이 원하는 어떤 속도로 아래의 layer에 (network layer) 데이터를 넣을 수 있다. (그러나, 실제 end-to-end throughput은 이 속도보다 더 작을 수 있다. 간섭하는 links의 제한된 전송 능력에 의해 또는 congestion에 의해).
  • 오늘날의 Internet은 종종 time-sensitive applications에 만족적인 서비스를 제공 할수 있지만, 어떤 timing or throughput guarantees든지를 제공할 수 없다.
  • application-layer protocol은 다른 end systems에서 작동하는 한 어플리케이션의 프로세스들이 어떻게 서로에게 메세지를 보낼 수 있는지를 정의한다. 특히, 한 application-layer protocol은 다음을 정의한다 :
    • 예를들어 교환되는 메세지의 유형은 요청 메세지와 반응 메세지이다.
    • 다양한 메세지 종류의 syntax. 메세지에서의 fields와 그 필드들이 어떻게 기술되어있는지 같은.
    • fields의 semantics. 즉, fields에서 그 정보의 의미
    • 한 프로세스가 언제 그리고 어떻게 메세지를 보내고 메세지에 반응할지를 결정하는 규칙
  • 어떤 application-layer protocols은 RFCs에서 명시되어있고, 그러므로 public domain에 있다. 예를들어 Web의 application-layer protocol인 HTTP(HyperText Transfer Protocol)은 RFC로서 이용가능 하다. 만약 한 브라우저 개발자가 HTTP RFC의 규칙을 따른다면, 그 브라우저는 HTTP RFC의 규칙을 또한 따르는 어느 웹 서버로 부터 웹 페이지를 가져올 수 있다. 많은 다른 application-layer protocols은 사유권이 있고, 의도적으로 public domain에서 이용가능하지 않다. 예를들어, Skype는 proprietary application-layer protocols을 사용한다.
  • 이 챕터에서, 우리는 5개의 중요한 어플리케이션들을 이야기 한다 : Web, file transfer, electronic mail, directory service, P2P applications. Web -> HTTP. FTP <-> HTTP. electronic mail. DNS (a directory service for the Internet).
* The Web and HTTP
- Overview of HTTP
  • HyperText Transfer Protocol (HTTP)인 Web의 application-layer protocol은 Web의 심장에 있다. 그것은 RFC 1945와 RFC 2616에서 정의된다. HTTP는 두 개의 프로그램으로 구성된다 : client program and server program. 다른 end systems에서 실행되는 client/server proram은 HTTP 메세지들을 교환하여 서로에게 이야기 한다. HTTP는 이러한 메세지들의 구조를 정의하고, client와 server가 어떻게 메세지를 교환하는지를 정의한다. 
  • 각 URL은 두 개의 컴포넌트들을 가진다 : 그 object와 object의 경로 이름을 포함하는 서버의 hostname. Web browsers (Internet Explorer와 Firefox같은)들은 HTTP의 client side를 Web의 맥락에서 구현하기 떄문에, 우리는 browser와 client 단어를 혼용하여 사용할 것이다. HTTP의 서버 단을 구현하는 Web servers는 URL로 addressable할 수 있는 각 웹 오브젝트를 포함한다. 인기있는 Web servers는 Apache와 Microsoft Internet Information Server를 포함한다.
  • HTTP는 Web clients가 Web servers로부터 Web pages를 어떻게 요청하는지와 servers가 Web pages를 clients에게 어떻게 전송하는지를 정의한다. 
  • HTTP는 그것의 밑에 있는 transport protocol로서 TCP를 사용한다 (UDP 위에서 작동하기 보다). HTTP 클라이언트는 처음에 서버와 TCP 연결을 시작한다. 그 연결이 확립되기만 한다면, 브라우저와 서버 프로세스들은 그들의 socket interfaces를 통해 TCP에 접근한다. 클라이언트는 HTTP 요청 메세지를 그것의 소켓 인터페이스에 보내고, 그것의 소켓 인터페이스로부터 HTTP 반응 메세지를 받는다. 유사하게, HTTP 서버는 그것의 소켓 인터페이스로 부터 요청 메세지를 받고, 반응 메세지를그것의 소켓 인터페이스에 보낸다.
  • 클라이언트가 메세지를 그것의 소켓 인터페이스에 보내기만 한다면, 그 메세지는 클라이언트의 손에서 떠나 TCP의 손에 있게 된다. 이것은 클라이언트 프로세스에 의해 보내진 각 HTTP 요청메세지가 결국에 그 서버에 온전하게 도착한다는 것을 암시한다; 윳하게, 각 서버 프로세스에 의해 보내진 각 HTTP response message는 결국에 클라이언트에 온전하게 도착한다. 여기에서 우리는 layered architecture의 훌륭한 장점들중 하나를 보게 된다 - HTTP는 손실된 데이터 또는 TCP가 손실로부터 어떻게 복구하는지 네트워크 내에서 데이터의 재순서화를 어떻게 하는지에 걱정할 필요가 없다. 그것은 TCP와 protocol stack에서 더 낮은 layers에 있는 프로토콜들의 일이다.
- Non-Persistent and Persistent Connections
  • 많은 인터넷 어플리케이션에서, 클라이언트와 서버는 장시간 커뮤니케이션을 하게 되는데, 클라이언트는 일련의 요청을 하게 되고, 서버는 그 요청들 각각에 반응하게 된다. 어플리케이션과 그 어플리케이션이 어떻게 사용되는지에 따라, 그 일련의 요청들은 다시 만들어질 것이다, 규칙적인 간격에서 주기적으로 또는 간헐적으로. 이러한 클라이언트-서버 상호작용이 TCP에 대해 발생할 때, 그 어플리케이션 개발자는 중요한 결정을 할 필요가 있다 - 각 request/response pair가 separate TCP connection를 통해 보내져야 하는지 또는, 모든 요청과 그것들의 대응되는 반응이 same TCP connection를 통해 보내저야 하는지. 전자의 접근법에서, 그 어플리케이션은 non-persistent connections을 사용한다고 말해진다; 후자의 접근법에서는 persistent connections이다.
  • HTTP 명세는 오직 client HTTP program과 server HTTP program사이의 communication protocol만을 정의한다.  위의 명시된 단계에서, 우리는 의도적으로 그 클라이언트가 10개의 연속 TCP 연결에 대해 10개의 JPEG를 받을지 또는 그 JPEG들 중 어떤 것만 parallel TCP connections을 통해 얻어질지를 애매하게 했다. 사실, 사용자들은 parallelism의 정도를 제어하기 위해 현대 브라우저들을 설정할 수 있다. 그것들의 기본 모드에서, 대부분의 브라우저들은 5 ~ 10개의 parallel TCP connections을 열고, 이러한 연결들 각각은 한 개의 request-response transaction을다룬다. parallel connections의 사용은 response time을 줄여준다.
  • 우리는 round-trip time (RTT)를 작은 패킷이 클라이언트에서 서버로 이동하고 다시 클라이언트로 이동하는데 걸리는 시간으로 정의한다. 그 RTT는 packet-propagation delays, 중간 routers와 switches에서의 packet-queuing delays, packet-processing delays를 포함한다. 
  • 이제 사용자가 하이퍼링크를 클릭할 때 무엇이 발생하는지보자. 이것은 그 브라우저가 브라우저와 웹 서버 사이에 TCP 연결을 시작하게 한다; 이것은 "three-way handshake"를 포함하게 된다 - 즉, 그 클라이언트는 그 서버에 작은 TCP segment를 보내고, 그 서버는 알아보고 작은 TCP segment로 반응하고, 마지막으로 그 클라이언트는 그 서버에 다시 응답한다. 그 three-way handshake의 처음 두 번째 부분은 하나의 RTT를가진다. 그 hand-shake의 처음 두 개의 부분들을 완료하고나서, 그 클라이언트는 three-way handshake의 세 번째 부분과 결합된 HTTP 요청 메세지를 TCP 연결에 보낸다. 그 요청 메세지가 그 서버에 도착하고나서, 그 서버는 HTML 파일을 TCP connection에 보낸다. 이 HTTP request/response는 또 다른 RTT를 차지한다. 따라서 대강 총 response time은 두 개의 RTT에 HTML 파일의 서버에서 전송 시간을 더한 것이다.
  • Non-persistent connections은 어떤 단점을 가진다. 첫 째로, 새로운 connection이 만들어져야 하고, 각 requested object에 대해 유지되어야 한다. 이러한 연결들 각각에 대해, TCP buffers가 할당되어야 하고, TCP 변수들은 클라이언트와 서버 둘 다에서 유지되어야 한다. 이것은 Web server에 큰 부담을 줄 수 있다. 왜냐하면 그 서버는 동시에 수백 개의 다른 클라이언트로부터 요청을 수행중일지도 모르기 때문이다. 둘 째로, 각 오브젝트는 두 개의 RTT의 delivery delay를 겪는다 - TCP connection을 만드는 하나의 RTT와 한 오브젝트를 요청하고 받는 한 개의 RTT)
  • persistent connections으로, 그 서버는 한 response를 보낸 후에도 TCP connection을 열린 채로 둔다. 그 같은 클라이언트와 서버 사이의 차후의 요청과 반응은 같은 연결을 통해 보내질 수 있다. 특히 전체 웹 페이지는 단일의 persistent TCP connection을 통해 보내질 수 있다. 게다가, 같은 서버에 있는 여러 웹 페이지들은 서버에서 같은 클라이언트로 단일의 persistent TCP 연결을 거쳐서 보내질 수 있다. 오브젝트들에 대한 이러한 요청들은 다시 만들어질 수 있다, 답장이 요청을 막도록 기다리는 것 없이. 일반적으로 HTTP 서버는 그것이 어떤 시간 동안 사용되지 않을 때 (설정 가능한 timeout interval), 연결을 닫는다. 그 서버가 back-to-back 요청을 받을 때, 그것은 objects를 back-to-back 보낸다. HTTP의 기본 모드는 pipelining을가진 persistent connections을 사용한다.
- HTTP Message Format
  • HTTP 명세는 HTTP 메시지 포맷의 정의를 포함한다. HTTP 메세지의 두 가지 유형이 있는데, request message와 response message이다.
GET /somedir/page.html HTTP/1.1
HOST: www.someschool.edu
Connection: close
User-agent: Mozilla/5.0
Accept-language: fr
  • 우선 메세지가 일반 ASCII 문자로 쓰여져 있어서, 사람이 읽을 수 있다. 둘 째로, 그 메세지가 다 섯 줄로 이루어져있다. 이 특정한 요청 메세지가 5줄을 가질지라도, 한 요청 메세지는 더 많은 라인 또는 한 라인만 가질 수 있다. HTTP 요청 메세지의 첫 번째 라인은 request lines이라고 불려진다; 그 다음 라인들은 header lines이라고 불려진다. 그 request line은 세 가지 필드를 가진다: method field, URL field, HTTP version field. 그 method field는 몇 가지 다른 값을 취할 수 있는데, GET, POST, HEAD, PUT, DELETE를 포함한다. 대부분의 HTTP request messages들은 GET method를사용한다. 브라우저가 한 오브젝트를 요청할 때, URL field에서 요청된 오브젝트가 확인되어 GET method가 사용된다. version은 self-explanatory이다.
  • header line HOST : ~~는 그 오브젝트가 있는 host를 명시한다. 너는 host에 대해 배치된 TCP 연결이 이미 있기 떄문에 이 헤더라인이 불필요하다고 생각할지도 모른다. 그러나 그 host header line에 의해 제공되는 정보는 Web proxy caches에 의해 요구된다. Connection:close header line을 포함하여, 그 브라우저는 그 서버에게 그것은 persistent connections을 원하지 않는다고 말한다; 그것은 그 요청된 오브젝트를 보낸 후에 서버가 연결을 닫기를 원한다. User-agnet: header line은 user agent를 명시한다. 즉, 그 서버에 요청을 하는 브라우저의 종류이다. 이 헤더라인은 서버가 실제로 사용자 에이전트의 다른 유형에 대해 같은 오브젝트의 다른 버전을 보낼 수 있기 때문에 유용하다. 마지막으로 Accept-language: header는 HTTP에서 이용가능한 많은 content negotiation headers들 중의 하나이다.
  • 헤더라인 이후에 (carriage return과 linefeed 후에), "entity body"가 있다. 그 entity body는 GET method와는 비어있지만, POST method와 사용된다. HTTP client는 사용자가 한 form을 채울 때 POST method를 사용한다. POST message로, 그 사용자는 여전히 서버로부터 Web page를 요구하고 있다. 그러나 그 웹 페이지의 특정한 내용들은 그 상요자가 form fields에 입려갛는 것에 달려있다. 만약 그 method field의 값이 POST라면, 그 entity body는 그 사용자가 form fields에 입력한 것을 포함한다. HTML forms이 GET 방식을 사용한다면 요청된 URL에 그 입력된 데이터를 포함시킨다.
  • HEAD method는 GET method와 비슷하다. 한 서버가 HEAD method로 요청을 받을 때, 그것은 HTTP message로 반응하지만, 그것은 요청된 오브젝트들을 보낸다. 어플리케이션 개발자는 종종 디버깅을 위해 HEAD method를 사용한다. PUT method는 종종 Web publishing tools과 함꼐 사용된다. 그것은 한 상요자가 한 오브젝트를 특정한 웹 서버의 특정한 경로에 업로드하도록 한다. PUT method는 또한 웹 서버에 오브젝트를업로드 할 필요가 있는 어플리케이션들에 의해 사용된다. DELETE method는 한 사용자 또는 어플리케이션이 Web server에 있는 한 오브젝트를 삭제하도록 한다.
  • 아래에서 우리는 일반적인 HTTP response mssage를  제공한다. 
HTTP/1.1 200 OK
Connection: close
Date: Tue, 09 Aug 2011 15:44:04 GMT
Server: Apache/2.2.3 (CentOS)
Last-Modified: Tue, 09 Aug 2011 15:11:03 GMT
Content-Length : 6821
Content-Type : text/html
  • 그것은 세 개의 섹션을 가진다 : 초기 status line, 6개의 header lines, 그러고나서 entity body. 그 entity body는 그 message의 meat이다- 그것은 그 요청된 오브젝트 그 자체를 포함된다. status line은 세 개의 fields를갖는다: protocol version field, status code, 대응되는 status message. 이 예제에서, 그 status line은 그 서버가 HTTP/1.1을 사용하고 있다는 것을 가리킨다. 그리고 모든 것이 괜찮다고 한다 (즉, 서버가 요청된 오브젝트를 찾았고 보내고 있다는 것이다).
  • 그 서버는 Connection: close 헤더라인을 사용하여 클라이언트에게 그 메세지를 보낸 후에 TCP 연결을 닫을 거라고 말한다. Date: header line은 HTTP 반응이 언제 만들어졌고, 서버에 의해 언제 보내졌는지를 가리킨다. 이것이 그 오브젝트가 생성되거나 마지막으로 수정된 시간이 아니라는 것에 주목해라; 그것은 서버가 그것의 파일 시스템으로 부터 그 오브젝트를 가져와서 그 오브젝트를 response message에 넣고, response message를 넣은 시간이다. Server: 헤더 라인은 그 메세지가 Apache Web Server에 의해 생성되었다는 것을 가리킨다; 그것은 HTTP request message에서 User-agent: 헤더라인과 비슷하다. Last-Modified: 헤더라인은 object caching에 중요하다, local client와 network cache server 둘 다 에서 (또한 proxy servers라고 알려진). Content-Length: 헤더라인은 보내진 오브젝트의 바이트 길이를 가리킨다. Content-Type: 헤더라인은 entity body에 있는 오브젝트가 HTML text라는 것을 가리킨다.
  • 어떤 흔한 status codes와 관련된 문구는 다음을 포함한다:
    • 200 OK : 요청이 성공했고, 그 정보가 반응하여 반환되었다.
    • 301 Moved Permanently : 요청된 오브젝트가 영구적으로 이동되었다; 그 새로운 URL이 response message의 Location: header에 명시되어있다. 그 client software는 자동으로 그 새로운 URL을 가져올 것이다.
    • 400 Bad Request : 이것은 generic error code인데, 그 request가 서버에 의해 이해될 수 없다.
    • 404 Not Found : 그 요청된 문서가 이 서버에 존재하지 않는다.
    • 505 HTTP Version Not Supported: 그 요청된 HTTP protocol 버전이 서버에 의해 지원되지 않는다.
- User-Server Interaction: Cookies
  • HTTP server는 stateless이다. 이것은 서버 디자인을 간단하게하고, 엔지니어들이 수 천개의 동시 TCP 연결을 처리하는 고성능 웹 서버를 개발하게 해준다. 그러나, 한 웹 사이트가 사용자를 인식하는 것은 바람직하다, 왜냐하면 그 서버가 사용자 접근을 제한하길 원하거나 사용자 신원의 기능에 따라 내용을 제공하길 원하기 때문이다. 이러한 목적을 위해서, HTTP는 cookies를 사용한다. RFC 6265에 정의된 Cookies는 sites들이 상요자들을추적하게 허용한다. 대부분의 주요 상업 웹 사이트들은 오늘날 쿠키를 사용한다.
  • cookie technology는 4개의 컴포넌트들을 갖는다 : (1) HTTP response message에서 cookie header line; (2) HTTP request message에서 cookie header line; (3) 사용자 end system에 보관되어 있고 user의 browser에 의해 관리되는 cookie file; (4) Web site에서의 back-end database. 이 방식으로, 특정 사이트에서 어떤 사람의 활동을 서버가 추적할 수 있다. cookies는 한 사용자를 확인하기 위해 사용되어질 수 있다. 한 사용자가 한 site를 처음 방문할 때, 그 사용자는 사용자 신원을제공할 수 있다. 그 나중의 세션 동안에, 그 브라우저는 그 서버에 쿠키 헤더를 넘겨주고, 그것으로 인해 그 서버에 대해 그 사용자를 확인시킨다. Cookies는 따라서 stateless HTTP의 위에 user session layer를 생성하는데 사용될 수 있다.
- Web Caching
  • proxy server라고 불려지는 Web cache는 origin Web server를 대신해서 HTTP 요청을 만족시키는 network entity이다. 그 Web cache는 그것 자신의 disk storage를 가지고 있고, 이 storage에서 최근에 요청된 오브젝트들의 복사본을 유지한다. 한 cache는 동시에 server이자 client이다. 일반적으로 Web cache는 ISP에 의해 구매되고 설치된다.
  • Web caching은 두 가지 이유로 인터넷에 배치되어 왔다. 첫 째로, Web cache는 client request에 대한 response time을 상당히 줄일 수 있다. 특히 만약 그 client와 origin server사이의 bottleneck bandwidth가 client와 cache 사이의 bottleneck bandwidth보다 더 작다면.  둘 째로, Web caches는 상당히 기관의 Internet에 대한 access link의 트래픽을 제거할 수 있다. 트래픽을 줄여서, 그 기관(예를들어, 회사나 대학)은 bandwidth를 빠르게 업그레이드 할 필요없다. 그것으로 인해 비용을 줄인다. 게다가, Web caches는 Internet에 있는 Web traffic을 전체적으로 줄인다. 그것으로 인해 모든 어플리케이션에 대한 성능을 개선시킨다.
  • Content Distribution Networks (CDNs)의 사용을 통해, Web caches는 점점 더 Internet에서 주요한 역학을 하고 있다. CDN 회사는 Internet 도처에 지리적으로 분산된 많은 caches들을 설치한다. 그것으로 인해 많은 트래픽들을 localizing한다. 공유 CDNs과 전용 CDNs이 있다.
- The Conditional GET

  • caching이 user-perceived response times을 줄일 수 있을지라도, 그것은 새로운 문제를 도입한다 - cache에 있는 한 오브젝트의 복사본이 오래된 것일지도 모른다. 다시 말해서, Web server에 있는 그 오브젝트는 copy가 client에 cached 되고나서 수정되었을지도 모른다. 운좋게도 HTTP는 그것의 오브젝트들이 최신인지를 cache가 확인하는 메커니즘을 가지고 있다. 이 메커니즘은 conditional GET이라고 불려진다.
  • HTTP requeest message는 소위 coditional GET message 인데, 만약 (1) request message가 GET method를 사용하고, request message가 If-Modified-Since: header line을 사용한다면.
* File Transfer: FTP
  • HTTP와 FTP는 둘 다 file transfer protocols이고 많은 공통된 특징을 갖는다; 예를들어, 둘 다 TCP 위에서 작동한다. 그러나 두 application-layer protocols은 어떤 중요한 차이를 가지고 있다. 가장 큰 차이는 FTP는 한 파일을 전송하기 위해 두 개의 parallel TCP connections을 사용한다 : control connectiondata connection. 그 control connection은 두 개의 hosts 사이의 control information을 보내기 위해 사용된다 - 사용자 id, 패스워드, 원격 directory를 바꾸는 명령어, "put"과 "get" files를 하는 명령어들 같은 정보. data connection은 실제로 한 파일을 보내는데 사용된다. FTP가 별개의 control connection을 사용하기 때문에, FTP는 out-of-band로 그것의 control information을 보낸다고 말해진다. HTTP는 request/response header lines을 전송된 파일 자체를 나르는 같은 TCP connections에 보낸다. 이 이유 때문에 HTTP는 그것의 control information을 in-band하게 보낸다고 말해진다.
  • 한 사용자가 remote host와 FTP session을 시작할 때, FTP의 client side는 처음에 server side와 server port number 21에서 control TCP connection을 시작한다. FTP의 client side는 그 사용자 신원과 패스워드를 이 control connection을 통해 보낸다. FTP의 client side는 또한 그 control connection을 통해 remote directory를 바꾸는 명령어를 보낸다. 그 서버단은 control connection을 통한 file transfer에 대한 명령어를 받았을 때, 서버단은 그 client side에 TCP data connection을 시작한다. FTP는 정확히 그 data connection을 통해 한 개의 파일을 보내고, 그 data connection을 닫는다. 만약 그 같은 session 동안 사용자가 또 다른 file을 전송하길 원한다면, FTP는 또 다른 data connection을 연다. 따라서, FTP로, control connection은 user session 지속시간 동안 열려있게 된다. data connections는 non-persistent 이다.
  • session 동안, FTP 서버는 그 사용자에 대한 state를 유지해야 한다. 특히, 그 서버는 control connection과 특정 사용자 계정을 연관시켜야 하고, 그 서버는 사용자가 remote directory tree를 돌아다닐 때 사용자의 현재 디렉토리를 추적해야만 한다. 각 진행중인 사용자 세션에 대해 이 상태 정보를 추적하는 것은 FTP가 동시에 유지할 수 있는 총 세션의 수를 제한한다. 반면에 HTTP는 stateless이다. 그것은 어떠한 사용자 상태를 추적할 필요가 없다.
  • client <-> server로 주고받는 commands와 replies는 7-bit ASCII format으로 control connection을 거쳐 보내진다. 따라서 HTTP 명령어 처럼, FTP 명령어는 사람이 읽을 수 있다. 각 명령어는 4개의 대문자 ASCII 문자들로 몇 가지 옵션 인자와 함께 구성된다. 좀 더 흔한 명령어들은아래에 주어진다:
    • USER username: 서버에 사용자 id를 보내기 위해 사용됌
    • PASS password: 서버에 사용자 패스워드를 보내기 위해 사용됌
    • LIST: 서버에 현재 remote directory에 있는 모든 파일의 리스트를 보내라고 요청하기 위해 사용됌. 파일드르이 리스트는 control TCP connection 보다는 (new and non-persistent) data connection을 통해 보내진다.
    • RETR filename: remote host의 현재 directory로부터 한 파일을 retrieve(즉, get)하기 위해 사용됌. 이 명령어는 remote host가 data connection을 시작하게 하고, 그 data connection을 통해 요청된 file을 전송하게 한다.
    • STOR filename: remote host의 현재 디렉토리에 한 파일을 store(즉, put)하기 위해 사용됌
  • 일반적으로 사용자가 만드는 명령어와 control connection을 통해 보내진 FTP command 사이에 일대일 대응이 있다. 각 명령어 다음에 답장(reply)가 온다, 서버에서 클라이언트로 보내지는. 그 답장들은 3개의 숫자이고, 그 숫자 다음에 부가적인 메세지가 있다. 이것은 HTTP response message의 status line에 있는 status code와 phrase와 비슷하다. 그것들의 가능한 메세지와 함께 어떤 일반적 답장들은 다음과 같다:
    • 331 Username OK, password required
    • 125 Data connection already open; transfer starting
    • 425 Can't open data connection
    • 452 Error writing file
* Electronic Mail in the Internet
  • e-mail은 비동기 통신 매체이다 - 사람들은 편할 때 다른 사람의 스케쥴을 조정할 필요 없이 메세지들을 읽고 보낸다. 현대 이메일은 첨부 파일, 하이퍼링크, HTML-포맷 텍스트, 삽입 사진을 포함한 많은 강력한 기능들을 가진다. Internet mail system은 세 개의 주요 컴포넌트를 가진다: user agents, mail servers, and the Simple Mail Transfer Protocol (SMTP).
  • Mail servers는 email infrastructure의 핵심을 형성한다. Bob과 같은 각 수령자는 그 메일 서버들 중 하나에 위치한 mailbox를 가진다. Bob의 mailbox는 그에게 보내진 메세지를 관리하고 유지한다. 일반적인 메세지는 그것의 여정을 sender의 user agent에서 시작하여, sender의 mail server로 이동하고, 수령자의 mail server로 이동한다. 거기에서 그것은 수령자의 mailbox에 놓아진다.
  • Bob이 그의 mailbox에 있는 메세지에 접근하길 원할 때, 그의 mailbox를 포함하는 mail server는 Bob을 인증한다 (사용자 이름과 패스워드로). Alice의 메일 서버는 또한 Bob의 메일서버에서의 실패를 처리해야만한다. 만약 Alice의 server가 Bob의 서버에 우편을 전달하지 못한다면, Alice 서버는 그 메세지를 message queue에 보유해야 하고, 그 메세지를 나중에 전달하려고 한다. 재시도는 매 30분마다 된다. 만약 며칠 뒤에 성공이 없다면, 그 서버는 그 메세지를 제거하고, 보내는 사람에게 이메일 메세지로 알린다.
  • SMTP는 Internet electronic mail를 위한 주요 application-layer protocol이다. 그것은 보내는 사람의 mail server에서 받는 사람의 mail server로 메일을 전하기 위해 TCP의 reliable data transfer service를 사용한다. 대부분의 application-layer protocols 처럼, SMTP는 두 개의 단을 갖는다: sender의 mail server에서 실행되는 client side, 와 recipient의 mail server에서 실행되는 server side. 한 mail server가 다른 메일 서버에 메일을 보낼 때, 그것은 SMTP client로 작동한다. 받을 때는 SMTP server로 작동한다.
- SMTP

  • RFC 5321에 정의된 SMTP는 Internet electronic mail의 중심에 있다. 위에서 언급했듯이, SMTP는 sender의 메일 서버에서 recipient의 메일 서버로 메세지들을 옮긴다. SMTP는 HTTP보다 더 오래되었다. SMTP가 수 많은 멋진 특징들을 가질지라도, 인터넷에서 그것의 ubiquity로 인해, 그것은 그럼에도 불구하고, 어떤 옛날 특징을 가진 legacy 기술이다. 예를들어, 그것은 모든 mail messages의 body (headers가 아닌)를 간단한 7-bit ASCII로 제한한다. 이 제한은 전송 능력이 부족하고 어떤 사람이 큰 첨부파일이나 큰 이미지, 오디오, 비디오 파일을 이메일 보내려 하지 않았을 1980년대 초기에 말이 되었었다. 그러나 오늘날, multimedia 시대에, 7-bit ASCII 제한은 고통이다 - 그것은 binary multimedia data가 SMTP를 거쳐 보내지기 전에 ASCII로 인코딩 되는 것을 요구한다. 그리고 그것은 대응되는 ASCII 메세지가 SMTP 전송 후에 다시 binary로 디코딩 되기를 요구한다. 
  • SMTP가 보통 intermediate mail servers를 메일을 보내기 위해서 사용하지 않는다는 것을 관찰하는 것은 중요하다. 심지어 두 메일 서버가 세계 반대 편에 위치할 때에도. 만약 Bob의 mail server가 다운되었다면, 그 메세지는 Alice의 mail server에 남아있고 새로운 시도를 기다린다.
  • client SMTP (sending mail server host에서 작동하는)는 TCP가 server SMTP (receiving mail server host에 작동하는)에 있는 port 25에 connection을 만들게 한다. 만약 그 서버가 다운되어있다면, 그 클라이언트는 나중에 다시 시도한다. 이 연결이 만들어지기만 한다면, 그 서버와 클라이언트는 어떤 application-layer handshaking을 수행한다. SMTP clients와 servers는 정보를 전송하기 전에 그들 자신을 소개한다. 이 SMTP handshaking 단계 동안,  그 SMTP client는 보내는 사람의 e-mail 주소와 수령자의 e-mail 주소를 가리킨다. SMTP client와 server가 그들 자신을 서로에게 소개하고 나면, 그 클라이언트는 메세지를 보낸다. SMTP는 에러 없이 메세지를 서버에 보내기 위해 TCP의 reliable data transfer service에 의존할 수 있다. 그 클라이언트는 그러고나서 그것이 그 서버에 보낼 다른 메세지들을 가지고 있다면, 같은 TCP 연결을 통해 이 프로세스를 반복한다; 만약 그렇지 않다면, 그것은 TCP가 그 연결을 끊도록 한다.
  • HELO (HELLO의 축약어), MAIL FROM, RCPT TO, DATA, QUIT.
- Comparison with HTTP

  • 두 프로토콜들은 한 호스트에서 다른 것으로 파일을 보내기 위해 사용된다: HTTP는 파일을 (또는 오브젝트라고 불려지는) Web server에서 Web client로 전송한다 (일반적으로 한 브라우저); SMTP는 파일을 (즉, e-mail messages) 한 mail server에서 다른 mail server로 전송한다. 그 파일을 전송할 때, persistent HTTP and SMTP 둘 다 persistent connection을 사용한다. 따라서, 그 두 개의 프로토콜들은 공통된 특성으 ㄹ갖는다.
  • 그러나 중요한 차이점들이 있다. 첫 번째, HTTP는 주로 pull protocol이다. - 누군가가 한 Web server에서 정보를 불러오고 사용자는 그들의 편리성에서 서버로 부터 그 정보를 당겨오기 위해 HTTP를 사용한다. 반면에, SMTP는 주로 push protocol이다 - sending mail server는 receiving mail server에 파일을 보낸다. 특히, TCP connection은 파일을 보내길 원하는 기계에 의해 시작된다. 
  • 두 번째 차이는 SMTP는 각 메세지의 body를 포함하여 각 메세지가 7-bit ASCII format이 되기를 요구한다. 만약 그 메세지가 7-bit ASCII가 아니라면 또는 binary data를 포함한다면 (이미지 파일), 그러고나서 그 메세지는 7-bit ASCII로 인코딩 되어야 한다. HTTP data는 이 제약을 부과하지 않는다.
  • 세 번째 차이는 text와 images들 (가급적 다른 매체의 종류와 함께)로 구성된 문서가 처리되는 방식과 관련되어 있다. HTTP는 각 오브젝트를 그것 자신의 HTTP response message에 캡슐화한다. Internet mail은 그 메세지의 오브젝트들 모두를 한 메세지에 배치한다.
- Mail Message Formats
  • 한 이메일 메세지가 한 사람으로부터 다른 사람에게 보내질 때, 주변 정보를 포함하는 한 헤더가 그 메세지의 바디에 선행한다. 이 주변 정보는 일련의 헤더 라인에 포함되고, RFC 5322에 정의되어 있다. 그 헤더라인들과 메세지의 body는 blank line(즉, CRLF)로 분리되어 있다. RFC 5322는 mail header lines 뿐만 아니라 그것들의 semantic interpretations에 대해 정확한 형식을 명시한다. 각 header는 읽을 수 있는 텍스트를 포함하는데, 키워드 다음에 colon 다음에 value로 구성되어 있다. 어떤 키워드들이 요구되고 다른 것들은 optional이다. 모든 header는 From: header line과 To: header line을 가져야 한다; 한 header는 Subject: 뿐만 아니라 다른 선택할 수 있는 헤더 라인을 포함할지도 모른다.
From: alice@crepes.fr
To: bob@hamburger.edu
Subject: Searching for the meaning of life.
  • 메세지 헤더 후에, blank line이 따라온다; 그러고나서 그 message body (ASCII의)가 따라온다. 너는 어떤 header lines을 포함하는 메세지를 메일 서버에 보내기위해 Telnet을 사용해야 하는데, Subject: header line을 포함해야 한다.
- Mail Access Protocols
  • 1990년대 까지는, 일반 사용자가 server host에 접속하고 그 host에서 작동하는 mail reader를 실행하여 그의 메일을 읽었다. 그러나 오늘날, mail access는 client-server architecture를 사용한다 - 일반적인 사용자는 사용자의 end system에서 실행되는 클라이언트로 이메일을 읽는다. 예를들어, office PC, laptop, smartphone. local PC에서 mail client를 실행하여, 사용자는 풍분한 기능을 즐긴다, 멀티미디어 메세지와 첨부파일을 보는 능력을 포함해서.
  • Alice는 e-mail messasge를 그녀의 mail server에 넣기 위해 SMTP를 사용하고, Alice의 mail server는 그 이메일 메세지를 Bob의 mail server에 다시 놓기 위해 SMTP를 사용한다. 왜 두 단계 절차인가? 우선 Alice의 mail server를 통해 다시 두는 것 없이 Alice의 user agent는 도달할 수 없는 목적지 mail server에 대한 어떤 resource가 없기 때문이다. Alice가 처음에 그녀 자신의 메일 서버에 email을 두도록 하여, Alice의 mail server는 반복적으로 그 메세지르르 Bob의 mail server에 보내려고 할 수 있다. 가령 매 30분마다. Bob의 mail server가 작동할 수 있게 될 때 까지. 그 SMTP RFC는 그 SMTP 명령어가 여러 SMTP servers를 가로질러서 한 메세지를 다시 놓기 위해 어떻게 사용될 수 있는지를 정의한다.
  • Bob의 user agent는 메세지를 얻기 위해 SMTP를 사용할 수 없는데, 그 메세지를 얻는 것은 pull operation이기 때문이다. 반면에 SMTP는 push protocol이다. 그 퍼즐은 Bob의 mail server에서 그의 local PC로 메세지를 전송하는 특별한 mail access protocol를 도입하여 완료된다. 현재 Post Office Protocol-Version 3 (POP3), Internet Mail Access Protocol (IMAP), HTTP를 포함하는 많은 인기있는 mail access protocols이 있다.
  • SMTP는 sender의 메일 서버에서 recipient의 mail server로 메일을 전송하기 위해 사용된다. SMTP는 또한 sender의 user agent에서 그 sender의 mail server로 메일을 전송하는데 사용된다. POP3 같은 mail access protocol은 recipient의 mail server에서 그 recipient의 user agent로 메일을 전송하는데 사용된다.
  • POP3는 매우 간단한 mail access protocol이다. 그것은 RFC 1939에 정의되어있고, 짧고 꽤 읽기 좋다. 그 protocol은 간단하기 때문에, 그것의 기능은 오히려 제한된다. POP3는 user agent (client)가 mail server (the server)와 port 110에서 TCP connection을 열 때 시작한다. TCP connection이 설정되고, POP3는 세 단계를 통해 진행한다: authorization, transaction, and update. 첫 번째 단계인 authrization 동안, user agent는 사용자를 인증하기 위해 username과 password를 보낸다. second phase인 transaction 동안, 그 user agent는 메세지를 가져온다; 또한 이 단계 동안, 그 user agent는 삭제를 위해 메세지를 마킹하고, deletion marks를 제거하고, 메일 통계를 얻을 수 있다. 세 번째 단계인 update는 client가 quit command를 한 후에 발생하는데, 이것은 POP3 session을 끝낸다. 이 시간에, 그 mail server는 deletion으로 마킹된 메세지들을 제거한다. download-delete mode와 download-keep mode
  • POP3는 어떤 컴퓨터에서든지 접근될 수 있는 remote server에 folder hierarchy를 유지하는 것을 선호하는 nomadic user에 대해 문제를 발생시킨다. 이것과 다른 문제들을 해결하기 위해 RFC 3501에 정의된 IMAP protocol이 개발되었다. POP3처럼, IMAP은 mail access protocol이다. 그것은 POP3 보다 더 많은 기능을 가졌찌만 또한 상당히 더 복잡하다 (따라서 클라이언트와 서버 단 구현은 상당히 더 복잡하다.)
  • IMAP server는 각 메세지를 한 폴더와 연관시킨다; 한 메세지가 처음에 서버에 도착할 때, 그것은 수령자의 INBOX folder와 연관된다. 그 recipient는 그러고나서 그 메세지를 새로운, user-created folder로 옮길 수 있고, 그 메세지를 읽을 수 있고, 그 메세지를 삭제할 수 있고 등등. IMAP protocol은 사용자가 폴더를 생성하고 한 폴더에서 다른 곳으로 메세지들을 옮기도록 허용하는 명령어들을 제공한다. IMAP는 또한 특정한 기준에 부합하는 메세지에 대해 remote folders를 사용자들이 탐색하도록 하는 명령어를 제공한다. POP3와 다르게, IMAP server는 IMAP sessions을 넘어서 user state information을 유지한다 - 예를들어, 폴더들의 이름과 어떤 메세지가 어떤 폴더들과 연관되어 있는지.
  • IMAP의 또 다른 중요한 기능은 그것이 한 사용자 agent가 메세지들의 컴포넌트들을 획들하는 것을 허용하는 명령어를 가졌다는 것이다. 예를들어, 한 사용자는 한 메세지의 message header를 얻을 수 있고 또는 multipart MIME message의 한 부분을 얻을 수 있다. 이 기능은 user agent와 그것의 mail server사이에 low-bandwidth connection이 있을 때 (예를들어, slow-speed modem link) 유용하다. low-bandwidth connection으로, 그 사용자는 그것의 mailbox에 모든 메세지를 다운로드 하길 원하지 않을지도 모른다. 특히 예를들어, audio or video clip을 포함할지도 모르는 긴 메세지를 피하면서.
  • 이 서비스로, user agent는 ordinary Web browser이고, user는 HTTP로 그것의 원격 mailbox로 통신한다. Bob같은 한 수령자가 그의 메일 박스에 있는 메세지를 접근하길 원할 때, 그 이메일 메세지는 bob의 메일 서버에서 Bob의 brower로 POP3 또는 IMAP protocol 보다는 HTTP protocol을 사용하여 보내진다. Alice같은 sender는 한 e-mail message를 보내길 원할 때, 그 이메일 메세지는 그녀의 브라우저에서 그녀의 메일 서버로 SMTP보다는 HTTP를 통해 보내진다. 그러나, Alice의 mail server는 여전히 SMTP를 사용하여 다른 메일 서버와 메일을 주고 받는다.
* DNS - The Internet's Directory Service

  • 한 host에 대한 한 identifier는 그것의 hostname이다. - cnn.com, www.yahoo.com 같은. hostname은 연상기호이고 인간에 의해서 인정받는다. 그러나, hostnames은 host의 Internet에서 위치에 대한 어떠한 정보를 제공하지 않는다. 게다가, hostnames은 가변 길이의 문자와 숫자로 된 문자로 구성될 수 있기 때문에, 라우터에 의해 처리하는 기에 어려울 것이다. 이러한 이유 때문에, hosts들은 소위 IP addresses에 의해 확인된다.
  • IP address는 4바이트로 구성되고, rigid hierarchical structure를 갖는다. IP address는 121.7.106.83 같이 보이고, 거기에 각 period는 10진수 표기로 0에서 255까지 나타내어 질 수 있는 바이트들 중의 하나이다. IP 주소는 hierarchical인데, 우리가 그 주소를 왼쪽에서 오른쪽으로 스캔할 때, 우리는 그 호스트가 Internet에 어디에 위치해 있는지에 대한 점점 더 많은 정보를 얻는다 (즉, 네트워크 내에서, 네트워크의 네트워크 안에).
- Services Provided by DNS
  • host를 확인하는 두 가지 방법이 있다는 것을 보았다 - hostname과 IP address로. 사람들은 좀 더 연상되는 hostname identifier를 선호하지만, routers는 고정 길이이고, hierarchically structured IP addresses를 선호한다. 이러한 선호를 중재하기 위해, 우리는 hostnames을 IP addresses로 바꾸는 directory service가 필요하다. 이것이 그 Internet의 domain name system (DNS)의 주된 일이다. 그 DNS는 (1) DNS servers의 hierarchy에서 구현된 distributed database이고, (2) hosts가 distributed database를 query하는 것을 허용하는 application-layer protocol 이다. 그 DNS servers는 종종 Berkeley Internet Name Domain (BIND) software를 실행하는 UNIX machines이다. 그 DNS protocols은 UDP 위에서 작동하고, port 53을 사용한다.
  • DNS는 다른 application-layer protocols에 의해서도 흔히 이용된다. - HTTP, SMTP, FTP 를 퐇마하여 - 사용자가 입력한 hostnames을 IP addresses로 바꾸기 위해서. 우리는 DNS가 부가적인 delay를 (가끔씩 상당히 많다) 그것을 사용하는 Internet applications에 더한다는 것을 알 수 있다. 운 좋게도, 그 요구되는 IP address는 종종 "근처" DNS server에서 cached 된다. 그리고 이것은 DNS network traffic 뿐만 아니라 평균 DNS delay를 제거하는데 도움이 된다.
  • DNS는 hostnames을 IP 주소로 바꾸는 것 외에도 다른 중요한 서비스들을 제공한다:
    • Host aliasing : 복잡한 hostname을 가진 호스트는 한 개 이상의 alias names을 가질 수 있다. relay1.westcoast.enterprise.com 같은 hostname은 가령 enterprise.com과 www.enterprise.com 같은 두 개의 aliases를 가질 수 있다. 이 경우에 relay1.westcoast.enterprise.com hostname은 canonical hostname이라고 말해진다. DNS는 입력된 alias hostname에 대해 canonical hostname 뿐만 아니라 그 host의 IP address를 얻기 위해서 한 프로그램에 의해 불러와질 수 있다.
    • Mail server aliasing :  명백히, e-mail 주소가 연상기호여야 매우 바람직하다. Bob의 이메일 주소는 bob@hotmail.com과 같이 간단할지도 모른다. 그러나 Hotmail mail server의 hostname은 간단히 hotmail.com 보다 좀 더 복잡하고 덜 연상기호를 쓴다. DNS는 입력된 alias hostname에 대한 canonical hostname뿐만 아니라 그 host의 IP address를 얻기위해 mail application에 의해 불러와질 수 있다. 사실, MX record는 한 회사의 mail server와  Web server가 동일한 (aliased) hostnames을 갖도록 허가한다; 예를들어, 한 회사의 Web server와 mail server가 둘 다 enterprise.com으로 불려질 수 있다.
    • Load distribution : DNS는 또한 복제된 Web servers같은 replicated servers 사이에서 load distribution을 수행하는데 사용된다. cnn.com같은 바쁜 사이트들은 여러 서버에 걸쳐 복제되는데, 각 서버는 다른 end system에서 작동하고, 각각은 다른 IP 주소를 가진다. 복제된 웹 서버에 대해, IP 주소들의 한 집합은 따라서 한 canonical hostname과 연관이 된다. 그 DNS database는 IP 주소의 이 집합을 포함한다. 클라이언트가 한 주소들의 집합에 사상된 이름에 DNS query를 할 때, 그 서버는 IP 주소들의 전체 집합을 가지고 반응하지만, 각 답장 내에서 그 주소의 순서를 회전시킨다. 한 클라이언트가 일반적으로 그것의 HTTP reqeust message를 그 집합에 처음 기재된 IP 주소로 보내기 때문에, DNS rotation은 복제된 서버 사이에서 그 트래픽을 분산시킨다. DNS rotation은 또한 여러 메일 서버들이 같은 alias name을 가질 수 있게하여 e-mail에 대해 사용된다. 또한, Akamai같은 content distribution 회사들은 Web content distribution을 제공하기 위해 좀 더 정교한 방식으로 DNS를 사용해온다.
- Overview of How DNS Works
  • 우리는 이제 DNS가 어떻게 작동하는지에 대한 high-level overview를 다룬다. 우리의 이야기는 hostnam에서 IP 주소로 바꾸는 서비스에 집중할 것이다.
  • 한 어플리케이션은 DNS의 클라이언트 단을 불러올 것이고, 바뀔 필요가 있는 hostname을 명시한다. (많은 UNIX기반 기계에서, gethostbyname()은 한 어플리케이션이 그 translation을 수행하기 위해 호출하는 함수 호출이다.) user의 host에 있는 DNS는 인계받고, query message를 network에 보낸다. 모든 DNS query와 reply messages는 port 53으로 UDP datagrams 내에서 보내진다. 지연 후에, 밀리세컨드에서 세컨드의 범위로, user의 host에서 DNS는 요구되는 mapping을 제공하는 DNS reply message를 받는다. 이 mapping은 그러고나서 불러온 application에 넘겨진다. 따라서, 사용자의 host에서 불러온 어플리케이션의 관점으로부터, DNS는 간단하고 편한 변환 서비스를 제공하는 black box이다. 그러나 사실, 그 서비스를 구현하는 black box는 복잡하고, 전세계에 분산된 수 많은 DNS 서버 뿐만 아니라 그 DNS 서버들과 query하는 호스트들이 어떻게 통신하는지를 명시한 application-layer protocol로 구성되어 있다.
  • DNS에 대한 간단한 설계는 모든 mapping을 포함하는 하나의 DNS server를 갖는 것이다. 이 중앙화된 디자인에서, 클라이언트들은 간단히 모든 쿼리들을 단일의 DNS server에 향하게 하고, DNS server는 그 질문하는 클라이언트에 직접 반응한다. 비록 이 디자인의 간단함이 매력적일지라도, 광대하고 커지고있는 호스트들의 수를 가진 오늘날의 인터넷에 적절하지 않다. 중앙화된 디자인의 문제는 다음을 포함한다:
    • A single point of failure : 만약 DNS server가 crash한다면, 전체 인터넷도 그렇게 된다.
    • Traffic volume : single DNS server가 모든 DNS 쿼리들을 다뤄야만 한다.
    • Distant centralized database : single DNS server는 모든 query하는 clients에 가까울 수 없다.
    • Maintenance : 그 single DNS server는 모든 Internet hosts에 관해 기록을 유지해야 한다. 이 cenralized database는 거대해야할 뿐만 아니라, 모든 새로운 host를 보유하기 위해 자주 업데이트되어야 만 한다.
  • 요약해서 single DNS server에 있는 centralized database는 간단히 커지지 않는다. 결과적으로 DNS는 설계 상 분산되어진다. 사실, 그 DNS는 distributed database가 Internet에서 어떻게 구현되어있는 지에 대한 훌륭한 예이다.
  • 크기의 문제를 다루기 위해, DNS는 많은 수의 서버를 사용하는데, hierarchical 방식으로 구성되어 있고, 세계 주위에 분산되어 있다. 어떠한 단일 DNS server도 Internet에서 모든 호스트에 대한 모든 mapping을 갖고 있지 않다. 대신에 그 mappings은 DNS 서버들에 걸쳐서 분산되어 있다. DNS 서버들의 세 개의 class가 있다- root DNS server, top-level domain (TLD) DNS, authoritative DNS servers. 사용자는 root -> TLD -> authoritative DNS server 에 순차적으로 접근하여 IP 주소를 받는다. 먼저 이러한 세 개의 클래스들에 대해서 봐보자:
    • Root DNS servers : Internet에 13개의 root DNS servers가 있다. 그것들의 대부분은 북미에 위치한다. 13개의 root DNS servers가 마치 단일의 서버인 것 같지만, 각 "server"는 실제로 복제된 서버들의 한 네트워크이다.
    • Top-level domain DNS servers : 이러한 서버들은 com, org, net, edu, gov같은 top-level domains들과 uk, fr, ca, jp 같은 모든 country top-level domains에 책임이 있다.
    • Authoritative DNS servers : Internet에 공공으로 접근가능한 호스트들을 가진 모든 조직은 그들의 hosts의 이름을 IP 주소로 매핑하는 접근 가능한 DNS records를 제공해야만 한다. 한 조직의 authoritative DNS server는 이러한 DNS records를 포함한다. 한 조직은 이러한 records를 보유할 그것 자신의 authoritative DNS server를 구현하는 것을 선택할 수 있다.
  • root, TLD, and authoritative DNS servers는 모두 DNS servers의 hierarchy에 속한다. local DNS server라고 불려지는 또 다른 중요한 종류의 DNS server가 있다. local DNS server는 엄격히 servers들의 hierarchy에 속하지 않지만, 그럼에도 불구하고, DNS 아키텍쳐에 중심적이다. 각 ISP - 대학, academic department, employee의 회사, 또는 residential ISP - 는 local DSP server를 갖는다 (또한 default name server라고 불려진다). 한 호스트가 ISP에 연결할 때, 그 isp는 그 호스트에게 그것의 local DNS servers의 한 개 이상의 IP 주소를 제공한다 (일반적으로 Chapter 4에서 이야기 될 DHCP를 통해서). 너는 윈도우즈 또는 UNIX를 에서 network status windows에 접근하여 너의 local DNS server의 IP 주소를 결정할 수 있다. 한 host의 local DNS server는 일반적으로 그 host와 "가깝다". institutional ISP에 대해, 그 local DNS server는 그 host와 같은 LAN에 있을지도 모른다; residential ISP에 대해, 그것은 일반적으로 몇 개 안되는 라우터들에 의해 호스트와 분리되어 있다. 한 host가 DNS query를 할 때, 그 query는 local DNS server에 보내지고, 그 서버는 proxy를 행한다. 즉 그 쿼리를 DNS server hierarchy에 쿼리를 보낸다는 것이다. 일반적으로 TLD server는 authoritative DNS server를 항상 아는 것은 아니다. 대신에 그 TLD server는 intermediate DNS server만을 알지도 모른다. 그리고 차례로 그것은 그 hostname에 대한 authoritative DNS server를 안다. 보여준 예시는 recursive queriesiterative queries 둘 다를 사용한다. recursive queries는 대신해서 mapping을 얻도록 요청하기 때문에 그렇다. 한 dns server에 직접 다 받아지면 iterative이다.
  • 사실, DNS는 광범위하게 Internet에 튀어나오는 DNS 메세지들의 수를 줄이고 delay 성능을 향상시키기위해서 DNS caching을 이용한다. DNS chaining 뒤에 있는 아이디어는 매우 간단하다. query chain에서, 한 DNS server가 DNS reply를 받을 때 (예를들어, hostname에서 IP address에 대한 mapping을 포함하는), 그것은 그것의 local memory에서 mapping을 cache할 수 있다. hosts와 hostnames과 IP address사이의 mappings이 결코 영구적이기 않기 때문에, DNS servers는 한 주기 후에 cached information을 버린다 (종종 2일 까지).
- DNS Records and Messages
  • DNS distributed database를 함께 구현하는 DNS servers들은 resource records (RRs)를 저장한다. 그리고 hostname-to-IP address mapping을 제공하는 RRs을 포함한다. 각 DNS reply message는 한 개 이상의 resource records를 나른다. 
  • 한 resource record는 다음의 필드들을 포함하는 four-tuple이다:
    • (Name, Value, Type, TTL)
  • TTL은 resource record의 time to live이다; 즉, 그것은 한 resource가 cache로 부터 언제 제거되어야 하는지를 결정한다. Name과 Value의 의미는 Type에 의존한다:
    • Type = A : 그러면 Name은 hostname이고, Value는 그 hostname에 대한 IP 주소이다. 따라서, Type A record는 표준의 hostname-to-IP address mapping을 제공한다.
    • Type = NS : Name은 한 domain이고 (foo.com 같은), Value는 그 domain에서 hosts들에 대한 IP 주소를 어떻게 얻는지를 아는 authoritative DNS server의 host name이다. 이 record는 query chain에서 DNS queries 더 멀리 보내기 위해 사용된다.
    • Type = CNAME : Value는 alias hostname Name에 대한 canonical hostname이다. 이 record는 querying host에게 hostname에 대한 canonical name을 제공한다.
    • Type = MX : Value는 alias hostname Name을 가진 한 mail server의 canonical name이다. MX records는 mail servers의 hostnames이 간단한 aliases를 갖도록 한다. MX record를 사용하여, 한 회사가 그것의 메일 서버에 대해 그리고 그것의 다른 서버들 중 하나에 대해 (웹서버 같은) 같은 aliased name을 가질 수 있다는 것에 주목해라. mail server에 대해 canonical name을 얻기  위해서, DNS client는 MX record에 대해 query할 것이다; 다른 서버에 대해 canonical name을 얻기 위해서, 그 DNS client는 CNAME record에 대해서 query할 것이다.
  • 만약 한 DNS server가 특정한 hostname에 대해 authoritative라면, 그러면 그 DNS server는 그 호스트 네임에 대해 Type A record를 포함할 것이다. (비록 그 DNS server가 authoritative하지 않을지라도, 그것은 그것의 cache에 Type A record를 포함할지도 모른다.) 만약 한 서버가 한 hostname에 대해 authoritative하지 않다면, 그러면 그 서버는 그 hostname을 포함하는 domain에 대한 Type NS record를 포함할 것이다; 그것은 또한 NS record의 Value field에서 DNS server의 IP 주소를 제공하는 Type A record를 포함할 것이다.
  • 우리는 DNS query와 reply messages에 대해서 언급했다. 이러한 것들은 DNS messages의 유일한 두 가지 종류의 것이다. 게다가, 두 query와 reply messages 다 같은 format을 가진다. DNS message에서 다양한 fields에 대한 의미들은 다음과 같다:
    • 처음 12 bytes는 header section인데, 많은 fields를 가지고 있다. 그 첫 번째 field는 그 query를 확인하는 16-bit 숫자이다. 이 identifier는 한 query에 대한 reply message에 복사되는데, 그 client가 보내진 queries와 받아진 replies를 대조 시킬 수 있게 한다. flag field에는 많은 flags들이 있다. 1-bit query/reply flag는 그 메세지가 query(0) 또는 reply(1)인지를 가리킨다. 1-bit authoritative flag는 한 DNS server가 queried name에 대해 authoritative server일 때, reply message에서 설정된다. 한 1-bit recursion-desired flag는 한 client (host or DNS server)가 DNS server가 그것이 record를 가지지 않을 때 recursion을 수행하는 것을 요구할 때 설정된다. 1-bit recursion-available field는 만약 그 DNS server가 recursion을 지원한다면 reply에서 설정된다. 또한 헤더에 네 개의 숫자로된 fields가 있다. 이러한 필드들은 그 헤더 다음의 data sections의 네 가지 종류의 발생 횟수를 가리킨다.
    • question section은 만들어지고 있는 query에 대한 정보를 포함한다. 이 섹션은 (1) queried되고 있는 name을 포함하는 name field와, (2) 그 name에 대해 질문되는 question의 type을 가리키는 type field를 포함한다 - 예를들어,한 name과 연관된 host address (Type A) or 한 네임에 대한 mail server (Type MX).
    • DNS server로부터의 reply에서, answer section은 원래 queried되었떤 name에 대한 resource records를 포함한다. 한 reply는 answer에서 여러 개의 RRs를 반환할 수 있다. 왜냐하면 hostname은 여러 IP 주소를 가질 수 있기 때문이다.
    • authority section은 다른 authoritative servers에 대한 records를 포함한다.
    • additional section은 다른 도움이 되는 records를 포함한다. 예를들어, MX query에 대한 reply에서 answer field는 mail server의 canonical hostname을 제공하는 resource record를 포함한다. 그 additional section은 그 mail server의 canonical hostname에 대해 IP 주소를 제공하는 Type A record를 포함한다.
  • 작업하고 있는 host에서 DNS server로 DNS query message를 보내는 것은 nslookup program으로 쉽게 처리될 수 있다. 이것은 대부분의 Windows와 UNIX platforms에서 이용가능하다.
  • 너는 records가 database에 처음에 어떻게 들어가는지를 궁금할 것이다. 예시로 이것을 볼 것이다. 너가 Network Utopia라고 불리는 새로운 스타트업 회사를 만들었다고 가정하자. 너가 확실히 처음애 하길 원하는 것은 domain name networkutopia.com을 registrar에 등록하는 것이다. registrar은 domain name의 유일성을 확인하고, DNS database에 domain name을 등록시키고 그것의 서비스에 대해 작은 수수료를 받는 commercial entity이다. 1999년 이전에 Network Solutions이라는 단일 registrar가 독점했지만, 지금은 경쟁하는 많은 registrars이 있다. Internet Corporation for Assigned Names and Numbers (ICANN)이 다양한 registrars을 인가한다. registarr를 통해 domain name networkutopia.com을 등록할 때, 너는 또한 너의 primary and secondary authoritative DNS servers를 제공할 필요가 있다. 그 이름들과 IP 주소가 dns1.netwrokutopia.com, dns2.networkutopia.com 212.212.212.1., 212.212.212.2 라고 하자. 이러한 두 개의 authoritative DNS servers의 각각에 대해, 그 registrar은 Type NS와 Type A record가 TLD com servers에 들어가지도록 한다. 구체적으로 primary authoritative server에 대해, 그 registrar은 다음의 두 개의 resource records를 DNS system에 넣을 것이다:
(networkutopia.com, dns1.networkutopia.com, NS)
(dns1.networkutopia.com, 212.212.212.1, A)
  • 이러한 단계들 모두가 완료된다면, 사람들은 너의 웹사이트에 방문할 수 있을 것이고, 너의 회사에서 그 직원들에게 이메일을 보낼 수 있을 것이다.
* Peer-to-Peer Applications
  • peers라고 불려지는 간헐적으로 연결되는 hosts들의 쌍이 서로와 직접 통신한다. 그 peers들은 service provider에 의해 소유되지 않지만, 대신에 사용자들에 의해 통제되는 데스크탑과 랩탑이다.
  • P2P에 적합한 두 가지 다른 어플리케이션이 있다. 첫 번째는 file distribution인데, 그 어플리케이션은 single source에서 더 많은 peers로 한 파일을 배포한다. File distribution은 P2P에 대한 우리의 조사를 시작할 좋은 장소이다. 왜냐하면 그것은 명확히 P2P 아키텍쳐의 self-scalability를 보여주기 때문이다. 두 번째 P2P 어플리케이션은 peers의 큰 커뮤니티에 걸쳐 분산된 database이다. 이 어플리케이션에 대해 우리는 Distributed Hash Table (DHT)의 개념을 알아볼 것이다.
- P2P File Distribution
  • P2P file distribution에서 각 peer는 그것이 받은 file의 어떤 부분을 다른 peers에게 재배포할 수 있다. 그것으로 인해, 그것은 distribution process에서 그 서버를 도와준다. 2012년 일자로, 가장 인기있는 P2P file distribution protocol은 BitTorrent이다. Bram Cohen에 의해 원래 개발되었고, 그 BitTorrent protocol을 따르는 많은 다른 독립적인 BitTorrent clients들이 있다. HTTP protocol에 따르는 많은 web browser client가 있듯이.  처음에 file distribution의 맥락에서 P2P 아키텍쳐의 self-scalability를 알아보고, 그러고나서 BitTorrent를 상세히 알아볼 것인데, 그것의 중요한 특징과 기능을 강조할 것이다.
  • client-server 아키텍쳐와 P2P 아키텍쳐를 비교하고, P2P의 내재된 self-scalability를 보여주기 위해, 우리는 두 아키텍쳐 유형ㅇ에 대해 고정된 peers의 집합에 한 파일을 배포하는 것을 위한 간단한 quantitative model를 고려한다.
  • 그림 2.24에 보여지듯이, 서버와 peers는 access links로 Internet에 연결된다. 서버의 access link의 upload rate가 u_s이고, i번째 peer의 access link의 upload rate가 u_i이고, i번째 peer의 access link는 d_i이다. 또한 배포될 파일의 크기를 (비트로) F라고 하고, 그 파일의 한 복사본을 얻길 원하는 peers의 수를 N이라고 표기ㅣ하자. distribution time은 모든 N명의 peers에게 그 파일의 한 복사본이 도착하는데 걸린 시간이다. 아래의 distribution time에 대한 우리의 분석에서, client-server와 P2P 아키텍쳐 둘 다에 대해, 우리는 간단하게 된 일반적으로 정확한 가정을 했는데, Internet core가 풍부한 bandwidth를 가지고, 그것은 모든 병목이 access networks에 있다는 것이다. 우리는 또한 서버와 클라이언트가 어떤 다른 네트워크 어플리케이션에 참여하고 있지 않다고 가정하는데, 그것들의 모든 upload and download access bandwidth가 완전히 이 파일을 배포하는데에 완전히 전념할 수 있게 하기 위해서이다. 
  • client-server 아키텍쳐에 대해 distribution time을 처음에 결정하자. 그리고 우리는 그것을 D_cs라고 표기한다. 클라이언트-서버 아키텍쳐에서, 어떠한 peers들은 그 파일을 배포하는데 도움을 주지 않는다. 우리는 다음의 관찰을 한다:
    • 그 서버는 그 파일의 한 복사본을 N명의 peers 각각에게 전송해야만 한다. 따라서, 그 서버는 NF bits를 전송해야만 한다. 그 서버의 upload rate가 u_s이기 때문에, 그 파일을 배포하는데 걸리는 시간은 적어도 NF/u_s이다.
    • d_min이 peer가 가장 느린 download rate로 한 download rate라고 하자. 즉, d_min = min{d_1, d_p, ..., d_N}. 가장 느린 download rate를 가진 peer는 file의 모든 F bits를 F/d_min 초보다 적게 얻을 수 없다. 따라서 그 최소한의 distribution time은 적어도 F/d_min이다. 
  • 이러한 두 개의 관찰을 합쳐서, 우리는 다음을 얻는다 D_cs >= max{NF/u_s, F/d_min}. 이것은 client-server 아키텍쳐에 대해 최소한의 distribution time에 대한 하한을 제공한다. 저 식의 하한값을 실제 distribution time이라고 가정하자.                          즉, D_cs = max{NF/u_s, F/d_min}이다. 우리는 이 식으로 부터, 충분히 큰 N에 대해, client-server distribution time이 NF/u_s에 의해 주어진다는 것을 본다. 따라서, distribution time은 peers N의 숫자로 선형으로 증가한다. 그래서 예를들어, 만약 peers의 수가 한 주에서 다음주까지 1000배 증가하여 천에서 백만이 된다면, 모든 peers에게 파일을 배포하는데 요구되는 시간은 1000이 증가한다.
  • P2P 아키텍쳐에 대해 비슷한 분석을 해보자. 거기에서 각 peer는 파일을 배포할 때 그 서버를 도와줄 수 있다. 특히, 한 peer가 어떤 파일 데이터를 받았을 때, 그것은 그 데이터를 다른 peers에게 재배포하기 위해 그것 자신의 upload capacity를 사용할 수 있다. P2P 아키텍쳐에 대해 distribution time을 계산하는 것은 client-server 아키텍쳐보다 어느정도 더 복잡하다. 그 distribution time은 각 peer가 그 파일의 부분을 다른 peers에게 어떻게 배포하는지에 의존하기 떄문이다. 그럼에도 불구하고, 최소 distribution time에 대한 간단한 수식이 얻어질 수 있다. 우리는 다음의 관찰을 한다:
    • 배포를 시작할 때, 오직 서버만이 그 파일을 갖는다. 이 파일을 peers의 커뮤니티에 보내주기 위해, 그 서버는 그 파일의 각 bit를 적어도 한 번 그것의 access link에 보내야만 한다. 따라서, 그 최소한의 distribution time은 적어도 F/u_s이다.
    • client-server 아키텍쳐와 같이, 가장 낮은 download rate를 가진 peer는 F/d_min seconds보다 더 낮게 파일의 모든 F bits를 얻을 수 없다. 따라서, 그 minimum distribution time은 적어도 F/d_min이다.
    • 마지막으로, 전체적으로 그 시스템의 total upload capacity는 서버의 upload rate + 개별 peers의 각각의 upload rates인데, 즉, u_total = u_s + u_1 + ... u_N. 그 시스템은 그 N명의 peers 각각에게 F bits를 보내야만 (upload) 한다. ㄸ라서, 총 NF bits를 보낸다. 이것은 u_total보다 더 빠른 비율로 처리될 수 없다. 따라서, 그 minimum distribution time은 또한 적어도 NF/(u_s + u_1 + ... + u_N).
  • 이러한 세 개의 관찰을 합쳐서, 우리는 P2P에 대해 minimum distribution time을 얻는데, 그것은 D_p2p로 표현되고,                                                                  D_p2p >= max{F/u_s, F/d_min, NF/u_s + sum{1->N}(u_i). 이 식은 P2P 아키텍쳐에 대해 minimum distribution time에 대한 하한을 제공한다. 만약 우리가 각 peer가 비트를 받자마자 그 비트를 재배포 할 수 있다고 상상한다면, 실제로 이 하한을 성취하는 재배포 전략이 있다는 것이 밝혀졌다. 개별 bits보다는 file의 chunks로 재배포 되는 현실에서, 방정식 2.2는 실제 minimum distribution time의 좋은 근사의 역할을 한다. 따라서, 방정식 2.2에서 제공되는 lower bound를 실제 minimum distribution time이라고 하자. 즉, D_p2p = max{F/u_s, F/d_min, NF/u_s + sum{1->N}(u_i). ~~ P2P 아키텍쳐에 대해, 그러나, minimal distribution time은 항상 클라이언트-서버 아키텍쳐의 배포시간보다 작은것은 아니다; 그것은 또한 N peers의 어떤 수에 대해 1시간 보다 작다. 따라서, P2P 아키텍쳐의 어플리케잇녀들은 self-scaling할 수 있다. 이 scalability는 재배포자가 될 수 있을 뿐만 아니라 bits의 소비자가 될 수 있는 직접적인 결과이다.
  • BitTorrent는 file distribution을 위한 인기있는 P2P protocol이다. BitTorrent 언어에서, 특정한 파일의 배포에 참여하는 모든 peers의 무리는 torrent라고 불려진다. 한 torrent에 있는 Peers는 서로로 부터 그 파일의 동일한 사이즈의 chunks를 다운로드 한다. 일반적으로 256 KBytes의 chunk 크기이다. 한 peer가 처음에 한 torrent에 들어갈 때, 그것은 어떠한 chunks를 가지고 있지 않다. 시간이 흘러, 그것은 좀 더 많은 chunks를 축적한다. 그것이 chunks를 다운로드 하는 동안, 그것은 또한 다른 peers에게 chunks를 업로드한다. 한 peer가 전체 파일을 얻었다면, 그것은 (이기적으로) 그 torrent를 떠날지도 모르고, 또는 (이타적으로) 그 torrent에 남아서 다른 peers에게 chunks를 계속 업로드할지도 모른다. 또한, 어떤 peer는 언제 든지 chunks의 subset만 가지고 그 torrent를 떠날지도 모르고, 나중에 그 torrent에 다시 참여할지도 모른다.
  • 이제 BitTorrent가 어떻게 작동하는지를 자세히 봐보자. BitTorrent는 오히려 복잡한 protocol이자 시스템이기 때문에, 우리는 그것의 가장 중요한 메커니즘만을 설명할 것이다. 그리고 밑에 있는 세부사항들은 치울 것이다. 즉 이것은 우리가 나무를 통해 숲을 보게 해줄 것이다. 각 토렌트는 tracker라고 불려지는 infrastructure node를 가진다. 한 peer가 한 torrent에 들어갈 때, 그것은 그것 자체로 tracker로 등록하고, 주기적으로 tracker에게 그것이 여전히 torrent에 있다고 알린다. 이 방식으로, 그 tracker는 그 torrent에 참여하고 있는 peers를 추적한다. 한 주어진 torrent는 어떤 순간에 참여하고 있는 10명 미만이거나 1000명 이상일 수 있다.
  • 한 새로운 peer인 Alice가 그 torrent에 들어갈 때, 그 tracker는 참여하고 있는 peers의 집합으로부터 peers의 subset을 선택하고 (구체적으로 가령 50명), 그리고 이러한 50명의 peers의 IP주소를 Alice에게 보낸다. 이 peers의 list를 소유하고, Alice는 이 목록에 있는 모든 peers와 함께 concurrent TCP connections를 만들려고 한다. Alice가 TCP connection을 만드는데 성공한 모든 peers를 "neighboring peers"라고 부르자. 시간이 지남에 따라, 이러한 peers들의 어떤 이는 떠나거나, 다른 peers들이 Alice와 TCP 연결을 만들려고 할지도 모른다. 그래서 한 peer의 neighboring peers를 시간에 따라 요동친다. 어떤 주어진 시간에, 각 peer는 그 파일의 chunks의 subset를 가질지도 모르고, 다른 peers들은 다른 subsets을 가질지도 모른다. 주기적으로, Alice는 그녀의 neighboring peers의 각각에게 그들이 가진 chunks의 list를 요청한다 (TCP 연결 위에서). 만약 Alice L명의 다른 이웃을 가지고 있다면, 그녀는 chunks의 L개의 lists를 얻을 것이다.
  • 그래서 어떤 주어진 순간에, Alice는 chunks의 한 subset을 가지고 있을 것이고, 그녀의 이웃들이 어떤 chunks를 가지고 있는지를 알고 있을 것이다.  이 정보로, Alice는 결정한 두 개의 중요한 결정을 가질 것이다. 첫 번째로, 그녀는 그녀의 이웃으로부터 처음에 어떤 chunks를 요구해야 되는가? 그리고 둘 째로, 그녀는 요청된 chunks를 그녀의 어떤 이웃에게 보내야 하는가? 어떤 chunks를 요구할지를 결정할 때, Alice는 rarest first라고 불리는 기법을 사용한다. 그 아이디어는 그녀가 가지고 있지 않는 chunks 중에서, 그녀의 이웃 중에서 가장 희귀한 chunks를 결정하는 것이다. (즉, 그녀의 이웃 중에서 가장 적게 반복된 copies를 가진 chunks) 그리고 그러고나서 그러한 rarest chunks 를 처음에 요청한다. 이 방식으로, 그 가장 희귀한 chunks는 좀 더 빠르게 재배포되고, (대강) torrent에서 각 chunk의 복사본의 수가 동일하게 되는 것을 목표로 한다. 그녀가 어떤 요청에 반응할지에 대해 결정하기 위해, BitTorrent는 똑똑한 trading 알고리즘을 사용한다. 그 기본 아이디어는 Alice가 현재 그녀의 데이터를 가장 높은 rate로 공급하는 이웃에게 우선순위를 주는 것이다. 구체적으로, 그녀의 이웃의 각각에 대해, Alice는 지속적으로 그녀가 비트를 받는 비율을 측정하고, 가장 높은 비율로 그녀의 bits를 주는 네 명의 peers를 결정한다. 그녀느 그러고나서 chunks를 이러한 같은 4명의 peers에게 보내서 회답한다. 매 10초마다, 그녀는 그 비율을 재계산하고, 가급적 4명의 peers의 집합을 수정한다. BitTorrent 언어에서, 이러한 네 명의 peers는 unchoked되었다고 말해진다. 중요하게, 매 30초마다, 그녀는 또한 무작위로 하나의 부가적인 이웃을 고르고, 그것에게 chunks를 보낸다. 그 무작위로 선택된 peer를 Bob이라고 부르자. BitTorrent 언어에서, Bob은 optimistically unchoked 되었다고 말해진다. Alice는 Bob에게 data를 보내기 때문에, 그녀는 Bob의 top four uploaders중의 하나가 될지도 모른다. 그 경우에, Bob은 Alice에게 data를 보내기 시작할 것이다. 만약 Bob이 Alice에게 보내는 data 비율이 충분히 높을 때, Bob은 그러고나서 차례로 Alice의 top four uploaders 중의 하나가 될 수 있다. 다시 말해서, 매 30초 마다, Alice는 무작위로 새로운 거래 파트너를 선택하고, 그 파트너와 거래를 시작한다. 만약 두 peers가 그 거래에 만족한다면, 그들은 서로를 그들의 top four lists에 올리고, 그 peers중의 하나가 더 좋은 파트러를 찾을 때 까지 서로 거래를 계속한다. 그 효과는 호환 가능한 비율로 업로드 할 수 있는 peers가 서로를 찾는 경향이 있다는 것이다. 그 random neighbor selection은 또한 새로운 peers들이 chunks를 받게하는데, 그들이 거래할 어떤 것을 가질 수 있게 하기 위해서이다. 이러한 5명의 peers들 (four "top" peers and one probing peer)외의 모든 다른 neighboring peers는 "choked" 되었다. 즉, 그들이 Alice로부터 어떠한 chunks를 받지 않는다. 
* Distributed Hash Tables (DHTs)
  • 우리는 P2P network에서 간단한 데이터베이스를 어떻게 구현할지를 고려할 것이다. 우리는 이 간단한 데이터베이스의 중앙화 버전을 설명하여 시작할 것인데, 이것은 간단히 (key, value) 쌍을 포함한다. 우리는 key로 database를 쿼리한다. 우리는 수백만 이상의 peers에 대해 (key, value)를 저장할 이 데이터베이스의 distributed P2P version을 어떻게 만들지를 고려할 것이다. P2P 시스템에서, 각 peer는 오직 (key, value) 쌍의 전체의 작은 부분집합만을 가질 것이다. 우리는 어떤 peer가 특정한 키를 가지고 distributed database를 query할 수 잇도록 할 것이다. 그 distributed database는 그러고나서 대응되는 (key, value) 쌍을 가진 peerㄴ를 찾고, 그 querying peer에게 key-value pairs를 반환할 것이다. 어떤 peer는 또한 그 데이터베이스에 새로운 key-value pairs를 넣는 것이 허용될 것이다. 그러한 distributed database는 distributed hash table(DHT)라고 언급된다.
  • DHT를 어떻게 만들 수 있는지를 설명하기 전에, 처음에 P2P file sharing의 맥락에서 구체적인 DHT service 예제를 설명하자. 이 경우에, key는 content name이고, 그 value는 content의 copy를 가진 peer의 IP 주소이다. 그래서, 만약 Bob과 Charlie 각각이 최신 Linux distribution의 한 복사본을 가지고 있다면, 그러면 그 DHT database는 다음의 두 개의 key-value pairs를 포함할 것이다: (Linux, IP_Bob) and (Linux, IP_Charlie). 좀 더 구체적으로, DHT database는 그 peers들에게 분산되어 있기 때문에, 어떤 peer, 가령 Dave는 "Linux" key에 대해 책임이 있을 것이고, 대응되는 key-value paris를 가질 것이다. 이제 Alice가 Linux의 복사본을 얻길 원한다고 가정하자. 명백히, 그녀는 그것을 다운로드 시작하기 전에 처음에 어떤 peers가 그 복사본을 가지고 있는지를 알 필요가 있다. 그녀는 DHT에 key로서 "Linux"로 쿼리한다. 그 DHT는 그러고나서 그 peer Dave가 "Linux"에 대한 key에 책임이 있다는 것을 결정한다. 그 DHT는 그러고나서 peer Dave에게 연락하고, Dave로부터 key-value pairs (Linux, IP_Bob), (Linux, IP_Charlie)를 얻고, 그것들을 Alice에게 보내준다. Alice는 그러고나서 IP_Bob 또는 IP_Charlie 둘 중 하나로부터 최신 Linux 배포판을 다운로드 할 수 있다.
  • 일반적인 key-value pairs에 대해 DHT를 설계하는 일반 문제로 돌아가자. DHT를 만드는 한 가지 단순한 접근법은 무작위로 (key, value) pairs를 모든 peers에 대해 무작위로 흩뿌리는 것이고, 각 peer가 모든 참여하는 peers의 IP 주소의 한 리스트를 유지하게 하는 것이다. 이 설계에서, 그 querying peer는 그것의 query를 모든 다른 peers에게 보내고, 그 key와 맞는 (key, value) pairs를 포함하는 peers는 그들의 matching pairs로 반응할 수 있다. 이러한 접근법은 완전히 unscalable하다. 물론, 왜냐하면 그것이 각 peer가 모든 다른 peers를 알아야 할 뿐만 아니라 (몇 백만의 peers들), 설상가상으로 각 query가 모든 peers에게 보내져야 하기 때문이다.
  • 우리는 이제 DHT를 설계한는데 우아한 접근법을 설명한다. 이것을 위해, 우리는 처음에 각 peer에 대해 identifier(식별자)를 할당하는데, 거기에서 각 식별자는 어떤 고정된 n에 대해 [0, 2^n -1]의 범위의 정수이다. 각 그러한 식별자는 n-bit 표기로 표현될 수 있다는 것에 주목해라. 또한 각 key가 그 같은 범위에 있는 정수라는 것을 요구하자. 머리 좋은 독자는 이전에 설명된 예시 키들이 정수가 아니라는 것을 봤을지도 모른다. 그러한 키들에서 정수를 만들기 위해서, 우리는 각 key를 [0, 2^n -1]의 범위의 정수로 매핑하는 해쉬 함수를 사용할 것이다. 한 해쉬 함수는 many-to-one function인데, 거기에서 두 개의 다른 입력들은 같은 output (same integer)를 가질 수 있찌만, 그 같은 output을 가질 가능성은 매우 작다. 그 hash 함수는 그 시스템에서 모든 peers에게 이용가능하다고 가정된다. 이후로, 우리가 "key"를 언급할 때, 우리는 그 원래 키의 hash를 언급한다.
  • DHT에 (key, value) pairs를 저장하는 문제를 고려하자. 그 중심 문제는 여기에서 keys를 peers에게 할당하는 규칙을 정의하는 것이다. 각 peer가 정수 식별자를 가지고, 각 key가 같은 범위의 정수라는 것이 주어진다면, 자명한 접근법은 (key, value) pair를 식별자가 그 key에 가장 가까운 identifier인 peer에게 할당하는 것이다. 그러한 전략을 구현하기 위해서, 우리는 "closest"가 무엇을 의미하느지를 정의할 필요가 있을 것이다. 거기에서, 많은 convetions이 가능하다. 편리성을 위해서, 우리는 closest peer를 key의 closest successor라고 정의하자. 예를 들어보자. n = 4라고 가정하고, 모든 peer와 키 식별자는 [0, 15]의 범위에 있다. 게다가, 시스템에 식별자가 1,3,4,5,8,10,12,15인 8명의 peers가 있다고 가정하자. 마지막으로, 우리가 (key, value) pair (11, Johnny Wu)를 8명의 peers중의 하나에 저장한다고 갖ㅇ하자. 그러나 어떤 peer에? 우리의 가장 가까운 convention을 사용하여, peer12가 key 11에 대해 가장 가까운 successor이기 때문에, 우리는 그러므로 그 pair (11, Johnny Wu)를 peer 12에 저장한다.
  • 이제 한 peer Alice가 (key, value) pair를 DHT에 넣기를 원한다고 가정하자. 개념적으로 이것은 간단하다: 그녀는 처음에 그 key에 가장 가까운 identifier를 가진 peer를 결정한다; 그러고나서 그녀는 그 peer에게 한 메세지를 보낸다. 그리고 그것에게 그 (key, value) pair를 저장하라고 알린다. 그러나 Alice는 어떻게 그 key에 가장 가까운 peer를 결정하는가? 만약 Alice가 그 시스템에 있는 모든 peers를 추적하려 한다면 (peer IDs and 대응되는 IP 주소), 그녀는 locally하게 가장 가까운 peer를 결정할 수 있다. 그러나, 그러한 접근법은 각 peer가 DHT에 있는 모든 다른 peers를 추적하는 것을 요구한다 - 그리고 이것은 수백만의 peers를 가진 큰 규모의 시스템에 대해서 완전히 비실용적이다.
  • 이 규모의 문제를 다루기 위해, 우리는 그 peers를 한 원으로 조직하는 것을 고려한다. 이 circular arrangement에서, 각 peer는 그것의 immediate successor와 immediate predecessor (modulo 2^n)만을 추적한다. 그러한 원의 한 예제는 그림 2.27(a)에 보인다. 이 예제에서, n은 또 다시 4이고, 이전의 예로부터 8명의 peers가 있다. 각 peer는 그것의 immediate successor와 predecessor만을 인지한다; 예를들어, peer 5가 peers 8과 4에 대해 IP 주소와 식별자를 알지만, 반드시 DHT에 있으지도 모르는 어떤 다른 peers에 대해 어떤 것도 알지 못한다. peers의 이 circular arragnement는 overlay network의 특별한  경우이다. overlay network에서, peers는 한 abstract logical network를 형성하는데, 그 네트워크는 physical links, routers, and hosts로 구성된 "underlay" computer network위에 있다. overlay network에 있는 links는 physical links는 아니지만, 간단히 peers의 쌍 사이의 간단히 가상의 liaisons(연락)이다. 그림 2.27(a)에서, 8명의 peers가 있고, 8개의 overlay links가 있다; 그림 2.27(b)에서 overlay에서, 8개의 peers가 있고, 16개의 overlay links가 있다. 단일의 overlay link는 일반적으로 underlay network에서 많은 physical links와 physical routers를 사용한다.
  • circular DHT는 각 peer가 관리해야 하는 overlay 정보의 양을 줄이는 매우 우아한 솔루션을 제공한다. 특히, 각 peer는 두 peers만을 알 필요가 있다, 즉 그것의 immediate successor과 immediate predecessor. 그러나 이 솔루션은 새로운 문제를 도입한다. 비록 각 peer가 두 이웃한 peers를 인지할지라도, 한 key에 책임이 있는 노드를 찾기 위해서 (최악의 경우에), DHT 에 있는 모든 N개의 노드들은 그 circle 주변의 한 메세지를 보내야만 할 것이다; N/2 messages가 평균적으로 보내진다.
  • 따라서, DHT를 설계할 때, 각 peer가 추적해야만 하는 이웃의 수와, DHT가 single query를 해결하기 위해 필요한 메세지의 개수 사이의 trade off가 있다. 한 편, 만약 각 peer가 모든 다른 peers를 추적한다면 (mesh overlay), 그러몬 오직 한 메세지가 query당 보내지지만, 각 peer는 N명의 peers를 추적해야만 한다. 다른 한편으로, circular DHT로, 각 peer는 오직 두 명의 peers만을 추적하지만, N/2 messages가 각 쿼리에 대해 평균적으로 보내진다. 운 좋게도, 우리는 DHT의 설계를 정제 할 수 있는데, peer당 이웃의 수 뿐만 아니라 query당 메세지의 수가 수용할만한 크기로 유지된다. 그러한 정제는 circular overlay를 기초로서 사용하지만, 각 peer가 그것의 immediate successor과 predecessor뿐만 아니라 그 원에 대해 흩뿌려진 상대적으로 작은 수의 shortcut peers를 추적하기 위해서 "shortcuts"을 추가하는 것이다.
  • P2P 시스템에서, 한 peer는 경고없이 왔다가 갈 수 있다. 따라서, 한 DHT를 설계할 때, 우리는 또한 그러한 peer churn의 존재할 때 DHT overlay를 유지하는 것에 걱정해야만 한다. 이것이 어떻게 이뤄지는지에 대해 크게 이해하기 위해서, 그림 2.27(a)의 circular DHT를 다시 고려하자. peer churn을 다루기 위해, 우리는 이제 각 peer가 그것의 첫 번째 그리고 두 번째 successors를 추적하는 것을 요구한다 (즉, IP 주소를 아는 것). 이제 한 peer가 급작스럽게 떠날 때 그 DHT가 어떻게 유지되는지를 고려하자.예를들어, 그림 2.27(a)에서 peer 5가 갑자기 떠났다고 가정하자. 이 경우에, 그 떠난 peer를 선행하는 두 개의 peers들 (4와 3)은 5가 떠났다는 것을 알게된다, 왜냐하면 그것이 더 이상 ping messages에 반응하지 않기 때문이다. Peers 4와 3은 따라서 그들의 successor state information을 업데이트 할 필요가 있다. peer4가 그것의 상태를 어떻게 업데이트 하는지 고려하자:
    • Peer 4는 그것의 첫 번째 successor (peer 5)를 그것의 두 번째 successor(peer 8)로 교체한다.
    • Peer 4는 그러고나서 그것의 첫 번째 successor (peer 8)에게 그것의 immediate successor (peer 10)의 IP주소와 식별자를 요청한다. Peer 4는 그러고나서 peer 10이 그것의 second successor가 되게한다.
  • 한 peer가 DHT에 들어가길 원할 때 무슨일이 발생하는지 고려하자. 식별자 13을 가진 한 peer가 DHT에 들어오고 싶다고 가정하자, 들어올 떄, 그것은 오직 DHT에 peer 1의 존재만을 안다. Peer 13은 처음에 peer 1에게 한 메세지를 보낼 것이고, 13의 "predecessor와 successor가 무엇이냐?"라고 말한다. 이 메세지는 DHT를 통해서 그것이 peer 12에 도달할 때 까지 보내진다. peer 12는 그것이 13의 predecessor이고, 그것의 현재 successor peer 15는 13의 successor가 될 것이라고 알게 된다. 다음으로, peer 12는 이 predecessor와 successor information을 peer 13에게 보낸다. peer 13은 이제 peer 15를 그것의 successor로 만들고, peer 12에게 그것의 immediate successor를 13로 바꾸라고 해서 DHT에 참여할 수 있다.
* Socket Programming: Creating Network Applications
  • 네트워크 어플리케이션에 두 가지 유형이 있다. 한 유형은 RFC 또는 어떤 다른 표준 문서와 같이 protocol standard에 연산이 명시된 한 구현이다; 그러한 어플리케이션은 가끔씩 "open"으로서 언급되는데, 그것의 연산을 명시하는 규칙들이 모두에게 알려져 있기 때문이다. 그러한 구현에 대해서, 클라이언트와 서버 프로그램은 FTP protocol의 클라이언트 단의 구현이 될 수 있다. 이것은 Section 2.3에서 설명되었고, RFC 959에서 explicitly하게 정의도어있따; 유사하게, 서버 프로그램은 FTP server protocl의 구현이 될 수 있다. 이것은 RFC 959에 explicitly하게 정의되어 있다. 만약 한 개발자가 클라이언트 프로그램을 위해 코드를 작성하고, 또 다른 개발자가 서버 프로그램을 위해 코드를 작성하고, 그리고 두 개발자가 세심히 RFC의 규칙들을 따른다면, 그러면 그 두 프로그램들은 상호 작동할 수 있을 것이다. 실제로, 오늘날의 많은 네트워크 어플리케이션들은 독립 개발자들에 의해 만들어진 클라이언트와 서버 프로그램 사이의 통신을 포함한다 - 예르들어, Apache Web server와 통신하는 Firefox browser, BitTorrent tracker와 통신하는 BitTorrent client.
  • 네트워크 어플리케이션의 다른 유형은 proprietary network application이다. 이 경우에 그 클라이언트와 서버 프로그램은 RFC 또는 다른 곳에서 openly하게 알려지지 않은 application-layer protocol을 이용한다.한 단일 개발자가 (또는 팀) client와 server program 둘 다를 만들고, 그 개발자는 그 코드에서 무슨일이 일어나느지에 대해 완전한 제어를 갖는다. 그러나 그 코드는 open protocol을 구현하지 않기 때문에, 다른 독립 개발자들은 그 어플리케이션과 상호 작동하는 코드를 개발할 수 ㅇ벗을 것이다.
- Socket Programming with UDP
  • sending process가 socket door 밖으로 데이터의 한 패킷을 보낼 수 있기 전에, UDP를 사용할 때, 그것은 처음에 그 패킷에 먹적지 주소를 붙여야만 한다. 그 패킷이 그 보내느 사람의 socket을 통과한 후에, 그 Internet은 Internet을 통해 그 받는 프로세스의 소켓에 패킷을 보내기 위해 이 목적지 주소를 사용할 것이다. 그 패킷이 받는 프로세스에 도착할 때, 그 받는 프로세스는 그 소켓을 통해 패킷을 가져올 것이고, 그러고나서 그 패킷의 내용을 조사하고, 적절한 행동을 취할 것이다.
  • 목적지 호스트의 IP 주소가 목적지 주소의 일부분이다. 패킷에 목적지 IP 주소를 포함하여, 그 Internet에 있는 routers가 Internet을 통해 목적지 호스트까지 패킷을 보낼 수 있을 것이다. 그러나 한 호스트가 많은 네트워크 어플리케이션 프로세스들을 작동시킬지도 모르기 때문에, 한 개 이상의 소켓을 가진 각각, 또한 목적지 호스트에서 특정한 소켓을 식별하는 것이 필수적이다. 한 소켓이 만들어질 때, port number라고 불리는 식별자가 그것에게 할당된다. 그래서, 그 패킷의 목적지 주소는 또한 소켓의 port number를 포함한다. 요악해서, 그 보내는 프로세스는 그 패킷에 목적지 호스트의 IP 주소와 목적지 소켓의 포트 번호로 구성된 목적지 주소를 붙인다. 게다가, 곧 우리가 보게 되듯이, 그 보내느 사람의 source address - source host의 IP주소와 source socket의 포트번호로 구성된 -는 또한 패킷에 붙여진다. 그러나, 그 패킷에 source address를 붙이는 것은 일반적으로 UDP application code에 의해서 되지 않는다; 대신에 그것은 자동적으로 밑의 운영체제에 의해서 처리된다.
  • 우리는 다음을 하는 간단한 데모를 만들 것인데:
    • 1. 그 클라이언트는 그것의 키보드로부터 문자들(data)의 한 줄을 읽고 그 데이터를 서버에 보낸다.
    • 그 서버는 그 데이터를 받고 그 문자들을 대문자로 바꾼다.
    • 그 서버는 그 수정된 데이터를 클라이언트에게 보낸다.
    • 그 클라이언트는 수정된 데이터를 받아서 그 line을 그것의 스크린에 보인다.

Python 3.6.4 버전 기준.
  • 첫 번째 줄은 string serverName을 hostname으로 설정한다. 여기에서 우리는 그 서버의 IP주소 (예를들어, "128.138.32.126") 또는 그 서버의 hostname (예를들어, "cis.poly.edu") 둘 중 하나로를 포함하는 string을 제공한다. 만약 우리가 그 hostname을 사용한다면, 그러면 한 DNS lookup이 자동적으로 그 IP 주소를 얻기 위해 수행될 것이다.  그 두번째 LINE은 정수 변수 serverPort를 12000으로 설정한다.
  • clientSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 이 라인은 clientSocket이라고 불려지는 클라이언트 소켓을 만든다. 그 첫 번째 파라미터는 그 주소 family를 가리킨다; 특히 AF_INET은 그 밑에 있는 네트워크가 IPv4를 사용한다고 가리킨다. (IPv4는 챕터 4에서 이야기 될 것이다.) 그 두 번째 파라미터는 그 소켓이 SOCK_DGRAM 타입이라는 것을 가리킨다. 이것은 그것이 UDP socket이라는 것을 의미한다. 우리가 소켓을 만들 때 클라이언트 소켓의 포트번호를 명시하고 있지 않다는 것을 주목해라; 대신에 우리는 그 운영체제가 우리를 위해 이것을 하게 할 것이다. 클라이언트 프로세스의 문이 만들어 졌으니, 우리는 그 문을 통해 보낼 메세지를 만들길 원한다.
  • message = input('Input lowercase sentence:') 책에서는 raw_input인데 python3부터는 input이다. 그리고 이것은 byte stream으로 받아져서, 나중에 메세지를 보낼때는 string형태로 보내야하기 때문에, encode() 명령어를 사용해서 문자를 보낸다.
  • clientSocket.sendto(message.encode(), (serverName, serverPort)) 이 라인에서, sendto()는 메세지에 목적지 주소 (serverName, serverPort)를 붙이고, 최종 패킷을 프로세스의 소켓인 clientSocket에 보낸다. (이전에 언급되었듯이, source address는 또한 패킷에 덧붙여 지는데, 비록 이것이 코드에 의해서 explicitly하게가 아니라 자동으로 처리된다.) UDP socket을 통해서 client-to-server message를 보내는 것은 이렇게 간단하다! 그 패킷을 보낸 후에 그 클라이언트는 서버로부터 데이터를 받기를 기다린다.
  • modifiedMessage, serverAddress = clientSocket.recvfrom(2048) 이 라인으로, 한 패킷이 클라이언트의 소켓에 Internet으로부터 도착할 때, 그 퍀ㅅ의 데이터가 변수 modifiedMessage에 넣어지고, 그 패킷의 source address는 serverAddress에 넣어진다. 그 변수 serverAddress는 그 서버의 IP주소와 서버의 port number 둘 다를 포함한다. program UDPClient는 실제로 이 서버 주소 정보가 필요하지 않다, 왜냐하면 그것은 이미 처음에 서버 주소를 알고있기 때문이다; 그러나 이 파이썬의 라인은 서버 주소를 그럼에도 불구하고 제공한다. recvfrom 메소드는 또한 입력으로 버퍼사이즈를 2048로 한다. (이 버퍼 사이즈는 대부분의 목적에 대해 작동한다.)

작동 결과.
  • UDPServer의 시작은 UDPClient와 비슷하다는 것에 주목해라. UDPClient와 매우 다른 코드의 첫 번째 줄은 serverSocket.bind(('', serverPort)) 이다. 위의 라인은 포트번호 12000을 그 서버의 소켓에 bind(즉, 할당(assign))한다. 따라서, UDPServer에서, 그 코드 (어플리케이션 개발자에 의해 쓰여진)는 explicitly하게 그 소켓에 한 포트번호를 할당하고 있다. 이 방식으로, 어떤 사람이 그 서버의 IP 주소에 포트 12000에 한 패킷을 보낼 때, 그 패킷은 이 소켓에 향할 것이다. UDPServer는 그러고나서 while loop에 들어간다. while loop는 UDPServer가 클라이언트로부터 무한정으로 패킷을 받고 처리하도록 할 것이다.
  • while loop에서, UDPServer는 한 패킷이 도착하기를 기다린다. message, clientAddress = serverSocket.recvfrom(2048) 이 코드 라인은 우리가 UDPClient에서 본 것과 유사하다.  한 패킷이 서버의 소켓에 도착했을 때, 그 패킷의 데이터는 변수 message에 들어가고, 패킷의 source address가 그 변수 clientAddress에 넣어진다. 그 변수 clientAddress는 클라이언트의 IP 주소와 클라이언트의 포트 번호 둘 다를 포함한다. 여기에서 UDPServer는 이 주소 정보를 이용한다, 왜냐하면 그것은 return address를 제공하기 때문이다. 이것은 평범한 우편 메일의 return address와 동일하다. 이 소스 어드레스 정보로, 그 서버는 이제 그것이 그것의 답장을 어디로 향해야 할지를 안다.
  • serverSocket.sendto(modifiedMessage, clientAddress) 이 마지막 라인은 그 클라이언트의 주소를 대문자화 된 메세지에 붙인다. 그리고 그 최종 패킷을 서버의 소켓에 보낸다. (이전에 언급되었듯이, 그 서버 주소는 또한 패킷에 부착된다. 비록 이것이 코드에 의해 explicitly하게가 아니라 자동으로 될지라도.) 그 인터넷은 그러고나서 그 패킷을 이 클라이언트 주소에 보낼 것이다. 그 서버가 패킷을 보낸 후에, 그것은 while loop에 남아 있고, 또 다른 UDP packet이 도착하기를 기다린다 (어떤 호스트에서 작동하는 어떤 클라이언트로든).
- Socket Programming with TCP
  • 클라이언트는 server에 연락을 시작하는 일을 가진다. 그 서버가 클라이언트의 초기 연락에 반응할 수 있게 하기 위해서, 그 서버가 준비되어야 만 한다. 이것은 두 가지 것을 암시한다. 첫 째로, UDP의 경우처럼, TCP server는 한 프로세스로서 클라이언트가 contact를 시작하기 전에 작동하고 있어야만 한다. 둘 째로, 그 서버가 특별한 문을 가져야만 한다 - 좀 더 정확히, 특별한 소켓- 그리고 그것은 임의의 호스트에서 작동하는 클라이언트 프로세스로 부터 어떤 초기의 연락을 받아들인다. process/socket에 대해 house/door 비유를 사용하여, 우리는 가끔씩 그 클라이언트의 initial contact를 "welcoming door에 노크하기"로 언급할 것이다.
  • 서버 프로세스가 작동하고, 그 클라이언트 프로세스는 서버에 대해 TCP 연결을 시작할 수 있다. 이것은 클라이언트 프로그램에서 TCP socket을 만들어서 된다. 그 클라이언트가 TCP socket을 만들 때, 그것은 그 서버의 welcoming socket의 주소를 명시한다, 이름그대로, 서버 host의 IP 주소와 그 소켓의 port number. 그것의 소켓을 만든 후에, 그 클라이언트는 three-way handshake를 시작하고, 그 서버와 TCP 연결을 만든다. 그 transport layer에서 발생하는 three-way handshake는 와넞ㄴ히 클라이언트와 서버 프로그램에서 보이지 않는다.
  • 그 three-way handshake 동안, 그 클라이언트 프로세스는 서버 프로세스의 welcoming door를 노크한다. 그 서버가 그 노크를 "hear"했을 때, 그것은 새로운 문을 만들고 좀 더 정확히는, 그 특별한 클라이언트에게만 쓰이는 새로운 socket이다. 우리의 예제에서, welcoming door는 우리가 serverSocket이라고 부르는 TCP socket object이다; 연결을 만든 클라이언트 전용으로 새로이 만들어진 소켓은 connectionSocket이라고 불려진다. 가끔 처음 TCP sockets을 마난 학생들은 welcoming socket (서버와 통신하길 원하는 모든 클라이언트들에 대해 연락을 위한 초기 진입점)과, 각 클라이언트와 통신을 위해 나중에 만들어진, 각각의 새롭게 만들어진 server-side connection socket을 혼동한다.
  • 어플리케이션의 관점으로 부터, 그 클라이언트의 소켓과 그 서버의 connection socket은 직접적으로 한 pipe에 의해서 연결된다. 그림 2.29에 보이듯이, 그 클라이언트 프로세스는 임의의 바이트들을 그것의 소켓에 보낼 수 있고, TCP는 그 서버 프로세스가 보내진 순서로 각 바이트를 (connection socket을 통해) 받을 수 있다는 것을 보장한다. 따라서 TCP는 클라이언트와 서버 프로세스 사이의 신뢰할만한 서비스를 제공한다. 게다가, 사람들이 같은 문으로 오고갈 수 있듯이, 그 클라이언트 프로세스는 그것의 소켓으로부터 바이트들을 보내거나 받을 수 있다; 유사하게, 그 서버 프로세스 또한 그것의 connection socket에 bytes를 보내거나 받을 수 있다.
  • clientSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 이 라인은 clientSocket이라고 불려지는 client의 소켓을 만든다. 첫 번째 파라미터는 또 다시 밑의 네트워크가 IPv4를 사용한다고 가리킨다. 그 두 번쨰 파라미터는 그 소켓이 SOCK_STREAM 타입이라고 가리키는데, 이것은 TCP 소켓이라는 것을 의미한다. 우리가 또 다시 소켓을 만들 때 그 클라이언트 소켓의 포트 번호를 명시하지 않는다는 것을 주목해라; 대신에 우리는 그 운영체제가 우리를 위해 이것을 하도록 한다. 이제 그 코드의 다음라인은 우리가 UDPClient에서 본것고 다르다:
  • clientSocket.connect((serverName, serverPort)) 클라이언트가 TCP를 사용하여 서버에게 데이터를 보낼 수 있기 전에, TCP 연결은 처음에 클라이언트와 서버 사이에 만들어져야 한다. 그 위의 라인은 그 클라이언트와 서버 사이의 TCP 연결을 시작한다. 그 connect() method의 파라미터는 그 연결의 서버단의 주소이다. 이 코드 라인이 실행되고나서, 그 three-way handshake가 수행되고, TCP connection은 그 클라이언트와 서버사이에 만들어진다.
  • clientSocket.send(sentence) 위의 라인은 문자열 sentence를 클라이언트 소켓을 통해 보내고 TCP connection으로 보낸다. 그 프로그램이 explicitly하게 패킷을 생성하고, 그 목적지 주소를 패킷에 부착하지 않았다는 것에 주목해라, UDP socekts으로 그랬던 것 처럼. 대신에 그 클라이언트 프로그램은 단순히 string sentence의 bytes를 TCP connection에 drops한다. 그 클라이언트는 그러고나서 서버로부터 바이트를 받기위해 기다린다.
  • modifiedSentence = clientSocket.recv(2048) 문자들이 서버로부터 도착했을 때, 그들은 modifiedSentence로 바껴지고, 문자들은 그 carriage return character로 끝날 때 까지 modifiedSentence에 계속해서 축적된다. 그 대문자화된 문장을 출력한 후에 그 클라이언트의 소켓을 닫는다.
  • clientSocket.close() 이 마지막 라인은 그 소켓을 닫고, 그러므로 클라이언트와 서버 사이의 TCP 연결을 닫는다. 그것은 클라이언트에 있는 TCP가 서버에 있는 TCP에 한 TCP message를 보내도록 한다.
  • serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) UDPServer와 유사하게, 우리는 서버 포트 번호 serverPort를 이 소켓과 연관시킨다:
  • serverSocket.bind(('', serverPort)) 그러나 TCP로, serverSocket은 우리의 welcoming socket이 될 것이다. 이 welcoming door를 만든 후에, 우리는 어떤 클라이언트가 그 door를 노크하기를 기다리고 듣고 있을 것이다:
  • serverSocket.listen(1) 이 라인은 서버가 클라이언트로 부터 TCP connectino requests를 듣고 있도록 한다. 그 파라미터는 queued connections의 최대 숫자를 명시하다 (적어도 1)
  • connectionSocket, addr = serverSocket.accept() 한 클라이언트가 이 문을 노크했을 때, 그 프로그램은 serverSocket에 대해 accept() method를 불러오는데, 이것은 서버에서 connectionSocket이라고 불리는 이 특별한 클라이언트 전용의 새로운 소켓을 만든다. 그 클라이언트와 서버는 그러고나서 handshaking을 마무리하고, 클라이언트으 clientSocket과 서버의 connectionSocket 사이에 TCP 연결을 만든다. TCP connection이 만들어지고, 그 클라이언트와 서버는 이제 바이트들을 서로에게 그 연결을 통해 보낼 수 있다. TCP로, 한 side에서 보내진 바이트들은 다른 side로 보내지는 것이 보장될 뿐만 아니라 순서대로 도착하는 것이 보장된다.
  • connectionSocket.close() 이 프로그램에서, 그 변형된 문장이 클라이언트로 보내진 후에, 우리는 connection socket을 닫는다. 그러나 serverSocket이 열려있기 때문에, 또 다른 클라이언트는 이제 그 door를 노크할 수 있고, 그 서버에 변형할 문장을 보낼 수 있다.

댓글 없음:

댓글 쓰기