CSAPP(11) - Network Programming

업데이트:

모든 네트워크 애플리케이션은 동일한 기본 프로그래밍 모델, 유사한 논리 구조, 동일한 프로그래밍 인터페이스를 기반으로 한다.

1. The Client-Server Programming Model

서버

  • 자원을 관리한다
  • 자원을 조작하여 클라이언트에 서비스를 제공한다

클라이언트-서버 모델의 근본 연산은 트랜잭션이다.(db transaction 개념 아님)

  1. 클라이언트는 서버에 request를 전송해 트랜잭션을 초기화한다.
  2. 서버는 요청을 받아 해석하고 자원을 적합하게 조작한다.
  3. 서버는 클라이언트에 response를 보내고 클라이언트의 다음 요청을 기다린다.
  4. 클라이언트는 응답을 받는다.

클라이언트와 서버는 프로세스다. 머신이나 호스트가 아니다.

  • 단일 호스트에서도 많은 클라이언트와 서버를 동시에 실행 가능하다.
  • 클라이언트-서버 모델은 클라이언트와 서버가 어느 호스트에 있는지는 관계없다.

2. Networks

호스트에게 네트워크는 데이터의 소스와 싱크를 제공하는 입출력 장치일 뿐이다.

  • 네트워크 어댑터는 I/O버스의 확장 슬롯에 꽂혀서 네트워크의 물리적 인터페이스를 제공한다.
  • 네트워크로부터 받은 데이터는 어댑터에서 I/O, 메모리 버스를 거쳐 메모리로 복사된다
    • 보통 DMA로 전송된다.(CPU 개입 없음)

물리적으로, 네트워크는 지리적 근접성에 따라 조직된 계층형 시스템이다.

가장 로우 레벨은 LAN이다. 빌딩이나 캠퍼스 범위

  • 대표적인게 Ethernet. 이더넷은 3Mb/s 에서 10Gb/s로 진화했다.
  • ethernet segment는 와이어와 허브로 구성되어 있으며, 방이나 층 범위에 있다.
    • 각 와이어는 동일한 대역폭을 갖는다.(100Mb/s or 1Gb/s)
    • 와이어의 끝은 호스트의 어댑터에 붙어 있다. 다른쪽 끝은 허브 포트에 붙어 있다.
    • 허브는 각 포트에서 받은 모든 비트를 다른 포트로 복사한다. 따라서 모든 호스트는 모든 비트를 받을 수 있다.
  • 각 이더넷 어댑터는 전역적으로 고유한 48비트 주소를 갖는다.(MAC 주소)
  • 호스트는 frame이라 하는 비트 뭉치를 보낼 수 있다.
    • 프레임 헤더는 시작과 도착점의 식별자와 프레임 길이를 갖는다.
    • 뒤에 payload라는 데이터 비트가 붙는다.
    • 모든 호스트 어댑터는 프레임을 받을 수 있지만 목적 호스트만 읽을 수 있다.
  • 여러 이더넷 세그먼트는 더 큰 LAN에 연결될 수 있다. 이를 bridged ethernets라 한다.
    • bridge라는 와이어와 박스 집합 장치를 이용한다.
    • 전체 빌딩이나 캠퍼스 범위
    • 브릿지와 브릿지가 연결되기도 하고, 브릿지와 허브를 연결하기도 한다.
      • 연결하는 와이어의 대역폭은 다를 수 있다.
    • 브릿지는 와이어 대역폭을 허브보다 잘 사용한다.
      • 자동으로 연결된 호스트들을 학습해서 선택적으로 데이터를 전달한다.

그 다음 레벨에서 여러 LAN들은 router로 연결될 수 있다. 이를 internet이라 한다.

  • 각 라우터는 각 네트워크를 위한 어댑터(포트)를 갖는다.
  • 라우터는 고속 종단간 연결도 된다. 일례로 WAN이 있다.
  • 인터넷의 주요 속성은 호환되지 않고 다른 LAN들과 WAN들을 조직할 수 있다는 것이다. 각 호스트는 물리적으로 모든 다른 호스트에 연결되어 있다.
    • 어떻게 소스 호스트는 다른 목적 호스트에 데이터를 전달할 수 있을까?
  • 각 호스트와 라우터에서 실행되는 프로토콜 소프트웨어는 두 기본 기능을 제공한다.
    • 네이밍 규약 : 호스트 주소에 대한 공통 포맷을 정의한다. 각 호스트는 인터넷 주소라 하는 고유 식별자를 할당받는다.
    • 전송 메커니즘 : 데이터 비트 뭉치를 packet이라 하는 공통된 방식으로 정의한다. 패킷은 패킷 크기, 시작/목적지 주소를 갖는 헤더와 데이터를 갖는 페이로드로 구성되어 있다.

호스트와 라우터가 인터넷 프로토콜로 데이터를 전송하는 과정

  1. 호스트A는 시스템 콜을 호출해서 클라이언트의 가상 주소 공간내 데이터를 커널 버퍼로 복사한다.
  2. 호스트A의 프로토콜 소프트웨어는 데이터에 인터넷 헤더와, LAN1프레임 헤더를 덧붙인 LAN1프레임을 생성한다. 이후 프레임을 어댑터에 보낸다. LAN1프레임의 페이로드는 인터넷 패킷이며, 인터넷 패킷의 페이로드는 실제 유저 데이터이다. 이 캡슐화는 네트워크의 핵심이다.
  3. LAN1 어댑터는 프레임을 네트워크로 복제한다.
  4. 프레임이 라우터에 도달하면 라우터의 LAN1어댑터는 읽어서 프로토콜 소프트웨어에 전달한다.
  5. 라우터는 인터넷 패킷 헤더에서 목적지 주소를 가져온다. 라우팅 테이블에서 목적지 주소를 조회하여 패킷이 갈 곳을 정한다. LAN2 프레임 헤더를 덧붙인 뒤에 어댑터로 보낸다.
  6. 라우터의 LAN2어댑터는 프레임을 네트워크로 복사한다.
  7. 프레임이 호스트B에 도착하면 호스트의 어댑터는 읽어서 프로토콜 소프트웨어에 전달한다.
  8. 호스트B의 프로토콜 소프트웨어는 패킷 헤더와 프레임 헤더를 제거하고 결과 데이터를 서버의 가상 주소 공간에 복사한다. 서버는 시스템 콜을 호출해 데이터를 읽는다.

3. The Global IP Internet

각 인터넷 호스트는 TCP/IP 프로토콜 구현 소프트웨어를 실행한다.

  • 인터넷 클라이언트와 서버는 소켓 인터페이스 함수와 유닉스 입출력 함수를 섞어 통신한다.
    • 소켓 함수는 시스템 콜과 TCP/IP의 커널 모드 함수로 구현된다.

TCP/IP는 프로토콜의 집합으로 각 프로토콜은 다른 역할을 한다.

  • IP는 네이밍 규약과 전송 매커니즘을 제공한다. 전송되는 데이터 뭉치를 datagrams라 하며, 한 인터넷 호스트에서 다른 호스트로 전송된다.
    • IP는 데이터 전송의 중복이나 유실에 대해 관여하지 않는다.
  • UDP는 IP의 확장으로 데이터그램이 프로세스 to 프로세스로 전달되게 한다.
    • 마찬가지로 중복이나 유실에 관여하지 않는다.
  • TCP는 IP의 확장으로 신뢰할 수 있는 프로세스 간 전이중 연결을 제공한다.

인터넷은 다음 특성을 가진 호스트의 집합이다.

  • 호스트의 집합은 32비트 ip 주소의 집합으로 매핑된다.
  • ip주소의 집합은 internet domain names라 불리는 식별자의 집합으로 매핑된다.
  • 한 인터넷 호스트의 프소세스는 다른 인터넷 호스트의 프로세스와 connection으로 통신할 수 있다.

3.1. IP Addresses

ip주소는 부호없는 32비트 정수다.

  • 인터넷 호스트는 다른 호스트 바이트 순서를 가지기에 TCP/IP는 공통 네트워크 바이트 순서를 정의한다.(빅-엔디안)
  • IP주소는 보통 dotted-decimal notation으로 표현된다.
    • inet_pton 함수는 dotted-decimal 문자열을 빅-엔디안 표현의 이진 IP주소로 변환한다.

3.2. Internet Domain names

정수는 사람이 기억하기 어렵기에 인터넷은 인간 친화적인 도메인 이름을 정의한다. 또한 IP 주소들에 도메인 이름을 매핑하는 메커니즘도 정의한다.

도메인 이름은 계층적이다.

인터넷은 도메인 이름의 집합과 IP주소 집합의 매핑을 정의한다.

  • 1988년까지 host.txt라는 단일 텍스트 파일에 매핑이 유지되었다.
  • 이후에 DNS(Domain Name System)에 유지되어 오고 있다.
    • DNS 데이터베이스는 수백만 host entries로 구성된다. 각각은 매핑을 정의한다.

각 인터넷 호스트는 로컬에 정의된 도메인 이름 localhost를 갖는다. 언제나 루프백 주소인 127.0.0.1로 매핑된다.

  • localhost 는 동일 머신에서 실행중인 서버와 클라이언트를 참조하는데 편리하고 이식성있는 방법을 제공한다.

여러 도메인 이름이 동일 IP 주소 집합으로 매핑될 수 있다. 유효한 도메인이 IP에 매핑되지 않을 수도 있다.

3.3. Internet Connections

커넥션은 프로세스 종단간 통신한다.

  • 전이중 통신으로 각 방향에 동시에 데이터 전송 가능하다.
  • 신뢰할 수 있다.

소켓은 커넥션의 엔드포인트다.

  • 소켓 주소는 인터넷 주소와 16비트 정수 port로 이루어져 있다.

클라이언트 소켓 주소의 포트는 커넥션 요청 시 커널에 의해 자동 할당된다. 이를 임시 포트라 한다.

  • 서버 소켓 주소의 포트는 영구적으로 연관된 well-known 포트다.
    • well-known 포트는 well-known 서비스 이름과 연관되어 있다.(http/80) /etc/services 파일에 정의되어 있다.

커넥션은 소켓 주소의 두 엔드포인트로 전역 식별된다.(소켓 페어)

  • (cliaddr:cliport, servaddr:servport)

4. The Socket Interface

소켓 인터페이스는 유닉스 I/O 함수와 함께 네트웍 애플리케이션을 만든다.

4.1. Socket Address Structures

  • 리눅스 커널 관점에서 소켓은 통신의 엔드포인트다.
  • 리눅스 프로그램의 관점에서 소켓은 서술자에 일지하는 오픈 파일이다.

인터넷 소켓 주소는 16바이트 구조이다.

  • 프로토콜 16비트
  • 포트 16비트
  • ip주소 32비트
  • 패드 64비트

The socket function

  • 클라이언트와 서버는 socket함수로 소켓 서술자를 생성한다.
  • 더 나은 방법은 getaddrinfo 함수를 사용하는 것이다.
  • 반환값은 clientfd 서술자이다.
    • 서술자는 아직 읽거나 쓸 수 없다. 클라이언트인지 서버인지에 따라 소켓을 여는 방법이 다르다.

The connect function

  • 클라이언트는 connect함수로 서버와 커넥션을 만든다.
  • 함수는 커넥션이 설립되거나 에러 발생시까지 블락된다.
  • 성공하면 clientfd 서술자는 읽고 쓸 준비가 되었다.
    • 결과 커넥션은 다음과 같은 소켓 쌍으로 표현된다.
    • (x:y, addr.sin_addr:addr.sin_port)

The bind function

  • bind함수는 커널에게 소켓 서술자 sockfd를 서버의 소켓 주소 addr과 연관시킨다.

The listen function

  • 커널에게 소켓 서술자가 서버에 의해 사용될 것임을 알린다.
    • socket함수로 생성된 서술자는 클라이언트가 사용한다.

The accept function

  • 서버는 accept를 호출해 클라이언트의 커넥션 요청을 기다린다.
  • connected 서술자를 반환한다.
    • 유닉스 I/O 함수를 통해 통신할 수 있다.
    • listening 서술자는 클라이언트 커넥션 요청의 엔드포인트를 제공한다.
      • 한번 생성되고 계속 존재한다.
    • connected 서술자는 클라이언트와 서버 커넥션의 엔드포인트다.

The getaddrinfo function

  • 호스트네임, 호스트주소, 서비스네임(http 등), 포트번호의 문자열 표현을 소켓 주소 구조로 변환한다.

The getnameinfo function

  • 소켓 주소 구조를 호스트와 서비스 이름 문자열로 변환한다.

The open_clientfd function

  • 함수 호출로 클라이언트는 서버와 커넥션을 설립할 수 있다.
  • 위에서 말한 함수들의 클라이언트측 고수준 헬퍼 함수
  • 유닉스 입출력 가능한 열린 소켓 서술자를 반환한다.

The open_listenfd function

  • 함수 호출로 서버는 커넥션 요청을 받을 준비가 된 listening 서술자를 생성한다.
  • 위에서 말한 함수들의 서버측 고수준 헬퍼 함수

커넥션에서 EOF의 의미?

  • EOF 문자란 것은 없다. EOF는 커널에 의해 감지되는 조건이다.
  • read 함수에서 0 코드를 반환하면 EOF조건이다.
    • 디스크 파일에서는, 파일 위치가 파일 길이를 넘어갔을 때
    • 인터넷 커넥션에서는,
      • 한 쪽 커넥션 프로세스의 커넥션을 닫았을 때.
      • 커넥션의 반대쪽에 있는 프로세스는 스트림의 마지막 바이트를 읽으려 할 때

5. Web Servers

웹 서버는 두 가지 방식의 컨텐트를 제공한다.

  • 정적 콘텐트 : 디스크 파일을 가져와서 클라이언트에게 반환한다.
  • 동적 콘텐트 : 실행 파일을 실행해서 출력을 클라이언트에게 반환한다.
  • 모든 콘텐트는 고유 URL로 식별된다.
  • 서버는 동적 콘텐트를 서빙할 때 CGI프로그램이라 불리는 자식 프로세스를 생성하여 호출한다.
  • CGI 프로그램은 동적 콘텐트를 표준출력으로 보낸다.
    • 자식 프로세스를 로드하고 CGI프로그램을 실행하기 전에 표준출력은 클라이언트에 연관된 서술자로 리다이렉트 된다. 따라서 CGI프로그램이 표준출력에 쓰는 것은 클라이언트에 직접 전달된다.
    • POST의 경우 표준입력으로 리다이렉트하여 바디 내 인자를 직접 읽는다.

7. Summary

  • 모든 네트워크 애플리케이션은 클라이언트-서버 모델에 기반한다.
    • 하나의 서버와 한 개 이상의 클라이언트로 구성된다.
    • 서버는 자원을 관리하고 조작하여 클라이언트에 서비스를 제공한다.
    • 기본 연산은 트랜잭션으로 클라이언트의 요청과 이어진 서버의 응답으로 구성된다.
  • 클라이언트와 서버는 인터넷으로 통신한다.
    • 프로그래머 관점에서 인터넷은 다음 특성을 갖는 호스트의 집합이다.
      • 각 호스트는 ip주소라는 32비트 이름을 갖는다.
      • ip주소의 집합은 도메인 이름의 집합에 매핑된다.
      • 다른 호스트의 프로세스들은 커넥션을 통해 통신한다.
  • 클라이언트와 서버는 소켓 인터페이스로 커넥션을 설립한다.
    • 소켓은 커넥션의 엔드포인트로 애플리케이션에 파일 서술자 형태로 표현된다.
      • 소켓 인터페이스는 소켓 서술자를 열고 닫는 함수를 제공한다.
      • 클라이언트와 서버는 이 서술자들을 읽고 쓰는 방법으로 통신한다.
  • 웹서버와 클라이언트는 HTTP프로토콜로 통신한다.
    • 정적 컨텐트 요청은 서버의 디스크 파일을 가져와서 클라이언트에 반환한다.
    • 동적 컨텐트 요청은 서버의 자식 프로세스 문맥 내 프로그램을 실행해서 그 출력을 클라이언트에 반환한다.
      • CGI 표준은 다음을 정의한다.
        • 클라이언트가 프로그램 인자를 서버에 전달하는 방법
        • 서버가 인자와 다른 정보를 자식 프로세스에 전달하는 방법
        • 자식 프로세스가 출력을 클라이언트에 전달하는 방법

태그:

카테고리:

업데이트:

댓글남기기