본문 바로가기

컴퓨터 시스템 이야기

네트워크 프로그래밍 (수정중)

네트워크 애플리케이션들은 동일한 기본적인 프로그래밍 모델에 기초하고 있다. 이들은 비슷한 전체 논리 구조를 가지며, 동일한 프로그래밍 인터페이스를 사용한다. 

11.1 클라이 언트-서버 프로그래밍 모델

모든 네트워크 애플리케이션 프로그램은 클라이언트-서버 모델에 기초하고 있다. 클라이언트-서버 모델에서 근본적인 연산은 트랜잭션이다. 클라이언트-서버 트랜잭션은 4단계로 구성된다. (여기서 말하는 트랜잭션은 DB에서 말하는 트랜잭션과는 다르다. 단순한 수행한 일련의 단계를  의미함)

  1. 클라이언트가 서비스를 필요할 때, 한 개의 요청을 서버로 보내는 것으로 트랜잭션을 게시.
  2. 서버는 요청을 받고 해석후 자신의 자원들을 적절한 방법으로 조작. 예를 들어 웹 서버가 브라우저로부터 요청받으면 디스크 파일을 읽음
  3. 서버는 응답을 클라이언트로 보내고, 그 후 다음 요청을 기다림.
  4. 클라이언트는 응답을 받고 처리. 예를 들면 웹 브라우저가 응답을 받고 스크린에 디스플레이한다.

11.2 네트워크

클라이언트와 서버는 별도의 호스트에서 돌아간다. 호스트에게 네트워크는 단지 또 다른 I/O 디바이스이며 어댑터는 네트워크에 물리적인 인터페이스를 제공함. 네트워크에서 수신한 데이터는 I/O와 메모리 버스를 거쳐서 어댑터에서 메모리로, 대개 DMA 전송으로 복사된다. (여기서 호스트는 컴퓨터 네트워크에 연결된 컴퓨터나 장치를 말하고, DMA는 direct memory access를 말한다).

물리적으로 네트워크는 계층구조 시스템이다. 하위 수준은 LAN으로 가장 대중적인 기술로 이더넷(데이터 링크 계층에서 MAC패킷과 프로토콜을 정의)이 있다. 이더넷 세그먼트는 몇 개의 전선들과 허브로 구성된다. 한쪽 끝은 호스트의 어댑터에 연결되고, 다른 끝은 허브의 포트에 연결된다. 허브는 각 포트에서 수신한 모든 비트를 종속적으로 다른 모든 포트로 복사한다. 그래서 모든 호스트는 모든 비트로 볼 수 있다. 호스트는 프레임이라고 부르는 비트들을 세그먼트의 다른 호스트 보낼 수 있다. 프레임은 소스와 목적지, 프레임의 길이를 식별할 수 있는 고정된 헤더 비트를 가지고 있으며, 그 뒤에 데이터 비트가 이어짐. 모든 호스트 어댑터는 이 프레임을 볼 수 있지만 목적지 호스트만이 실제로 이것을 읽음. (허브는 물리계층  장비임). 다른 세그먼트들을 전선들과 브리지라고 하는 장비를 사용해서 연결되는데 이걸 브리지형 이더넷이라고 하는 더 큰 LAN을 구성할 수 있다. 크기를 비교하면 그냥 이더넷 세그먼트는 방이나 층과 같은 작은 지역, 브릿지 이더넷은 전체 빌딩이나 캠퍼스 규모임.  예시를 들면 같은 세그먼트에 있는 호스트에 프레임을 전송하려면 브릿지는 다른 세그먼트에 도달하지 못하게 버려버린다. 따라서 대역폭을 절약함 만약 다른 세그먼트로 보내려면 다른 브릿지에 연결된 포트로만 복사함.

계층구조 상부에서 다수의 비호환성 여러 LAN들은 라우터라고 부르는 특별한 컴퓨터에 연결될 수 있으며 각 라우터는 각 네트워크에 대해 어댑터(포트)를 가지고 있다. 이런 형태를 WAN이라고 한다. 여기서 의문은 다른 비호 환적인 기술을 갖는 여러 LAN과 WAN들이 어떻게 데이터를 목적 호스트로 전송할 수 있을까?  답은 호스트와 라우터에서 돌고 있는 프로토콜 소프트웨어 계층이다. 이 프로토콜은 2가지 기본 기능을 제공해 호스트들과 라우터들이 데이터를 전송할 수 있게 해 준다. Naming scheme과 delivery mechanism을 말함. 하나의 ip주소를 할당하고, 데이터 비트를 패킷이라고 부르는 비연속적인 단위로 묶는 통일된 방법을 정의함. 패킷은 패킷 크기와 소스 및 목적지 호스트 주소를 포함하는 헤더와 호스트가 보낸 데이터 비트를 포함한다.

internet protocol을 설명하기 위해 예시를 들어보자.  호스트는 각각 LAN1과 LAN2에 연결되어 있다. 데이터 바이트를 전송하는데 8개의 기본 단계가 있다.

  1. 호스트 1의 클라이언트는 가상 주소 공간에서 커널 버퍼로 데이터를 복사하는 시스템 콜 호출
  2. 호스트 1의 프로토콜 소프트웨어는 internet헤더와 LAN1프레임 헤더를 데이터에 추가해서 LAN1프레임을 생성 internet 헤더는 호스트 2의 주소가 지정됨, LAN1 프레임 헤더는 라우터로 주소가 지정됨. 호스트 1은 이 프레임을 어댑터로 전달함 LAN1 프레임의 데이터가 internet 패킷이고, 그 데이터는 실제 사용자 데이터임
  3. LAN1 어댑터는 프레임을 네트워크로 복사함.
  4. 프레임이 라우터에 도달하면 라우터는 프로토콜 소프트웨어로 전달.
  5. 라우터는 internet 패킷 헤더에서 목적지 internet 주소를 가져와서 패킷을 전달할 곳을 결정하기 위해, LAN2 라우팅 테이블에서의 인덱스로 이것을 사용 라우터는 LAN1 프레임 헤더를 벗겨내고, 호스트 2의 주소를 갖는 새로운 LAN2프레임 헤더를 앞에 붙여서 이것을 어댑터로 전달
  6. 라우터의 LAN2 어댑터는 이 프레임을 네트워크로 복사함.
  7. 이 프레임이 호스트 2에 도착하면 어댑터가 읽어 들이고, 프로토콜 소프트웨어로 전달.
  8. 마지막으로 호스트 2의 프로토콜 소프트웨어는 패킷 헤더와 프레임 헤더를 벗겨내고 프로토콜 소프트웨어는 서버가 이 데이터를 읽는 시스템 콜을 호출할 때 서버의 가상 주소 공간으로 복사함. 

How data travel from one host to another on an internet

11.3 글로벌 IP 인터넷

11.5 웹 기초

웹 클라이언트와 서버는 HTTP라고 하는 텍스트 기반 응용 수준 프로토콜을 사용해서 상호 연동한다. 전통적인  FTP와 웹서비스를 구별하게 해주는 차이점은 HTML언어로 작성될 수 있다는 것이다. HTML프로그램은 명령들을 포함하고 있어서 브라우저에게 여러 가지 텍스트와 그래픽 객체를 페이지에 어떻게 표시할지 알려준다. 또한 HTML의 진정한 파워는 페이지가 인터넷 호스트에 저장된 콘텐츠의 포인터를 포함할 수 있다. 그게 바로 하이퍼링크

웹 서버는 두 가지 서로 다른 방법으로 클라이언트에게 콘텐츠를 제공.

  • 디스크 파일을 가져와서 그 내용을 클라이언트에게 전달, 이런 것을 정적 콘텐츠라 함
  • 실행 파일을 돌리고, 그 출력을 클라이언트에게 보냄. 실행파일이 런타임에 만든 출력을 동적 콘텐츠라 하고 그 결과를 클라이언트에게 전달.

웹 서버가 리턴하는 모든 내용들은 서버가 관리하는 파일에 연관됨. 이 파일 들은 url을 가짐. 실행파일을 위한 URL은 파일 이름 뒤에 프로그램의 인자를 포함함. '?' 문자는 파일 이름과 인자를 구분, 각 인자는 '&'로 구분됨.

클라이언트가 url의 접두어를 사용해서 어디로 가야 할지 결정하고, 서버는 /index.html과 같은 접미어를 사용해서 시스템상의 파일을 검색해서 콘텐츠를 결정함. 어떻게 서버가 URL의 접미어를 해석하는지에 대해서 이해해야 할 몇 가지 사실들 있음

  • URL이 정적 또는 동적 콘텐츠를 참조하는지를 결정하기 위한 표준 규칙은 없다.
  • 접미어 앞부분의 '/'는  어떤 종류의 콘텐츠가 요청되는 간에 홈 디렉터리를 나타낸다.
  • 최소한의 URL은 '/' 문장이며. 모든 서버는 이것을 /index.html 같은 특정 기본 홈페이지로 확장함. 이런 특성이 단순히 브라 우정 도메인 이름만 입력하고도 가져올 수 있는지를 말해줌

HTTP 요청

http 요청은 다음과 같은 형태를 가짐  method uri version 메서드에는 여러 가지가 있는데 주로 GET에 대해서만 논의. GET메서드는 서버에게 URI에 의해 식별되는 내용을 리턴할 것을 지시한다. URI는 파일 이름과 옵션인 인자들을 포함하는 URL을 포함하는 개념. 요청 라인의 version은 HTTP버전을 나타냄. 요청 헤더는 서버에 브라우저의 이름이나 브라우저가 이해하는 MIMT 타입 같은 추가적인 정보를 제공. host 헤더는 프록시 캐시에 의해 사용되며, 이것은 때로 브라우저와 요청된 파일을 관리하는 본래의 서버 사이의 중간자 역할을 한다. 하나의 클라이언트와 하나의 본래 서버 사이에는 소위 프록시 체인 내에서 다중 프락시가 존재할 수 있다. 헤더 내의 데이터는 프록시 체인의 중간에 있는 프록시가 요청한 컨텐츠의 부분적으로 캐시 된 사본을 가질 수 있는지 결정할 수 있도록 함

HTTP 응답

version status-code status-message 형태로 옴 응답 헤더는 응답에 대한 추가적은 정보를 제공함. MIME 타입을 알려주는 content-type과 크기를 나 나태는 content-length로 구성됨.

11.5.4 동적 콘텐츠 처리

우리가 동적 콘텐츠를 생각하면 여러 질문들이 있는데 이러한 질문들은 CGI로 설명 가능하다.

위키에서 CGI를 찾아보면

정의
공용 게이트웨이 인터페이스(영어: Common Gateway Interface; CGI)는 웹 서버 상에서 사용자 프로그램을 동작시키기 위한 조합이다. 존재하는 많은 웹 서버 프로그램은 CGI의 기능을 이용할 수 있다.
웹 서버 프로그램의 기능의 주체는 미리 준비된 정보를 이용자(클라이언트)의 요구에 응답해 보내는 것이다. 그 때문에 서버 프로그램 그룹에서는 정보를 그 장소에서 동적으로 생성하고 클라이언트에 송신하려 하는 조합을 작성하는 것이 불가능했다. 서버 프로그램에서 다른 프로그램을 불러내고, 그 처리 결과를 클라이언트에 송신하는 방법이 고안되었다. 이를 실현하기 위한 서버 프로그램과 외부 프로그램과의 연계법을 정한 것이 CGI이다. 
(출처: 위키피디아 )
단점
이런 막강한 확장성을 가진 기술임에도 불구하고 CGI는 현재는 널리 쓰이지 않는데, 가장 큰 문제로 요청이 하나 들어올 때마다  프로세스가 하나씩 실행된다는 것이 있다. 이는 특히 스크립트 언어에서 치명적이었는데 스크립트 언어에서는 보통 코드를 실행할 때마다 코드를 매번 해석해야 하기 때문이다. 물론 코드를 해석한 걸 캐싱하면 이 문제는 좀 나아지지만, 설령 C 언어 같은 언어로 미리 CGI 프로그램을 컴파일했다 하더라도 어지간한 환경에서는 프로세스 하나 실행하는데 몇 밀리초는 걸린다! 초당 수십 건의 요청이 들어오면 프로세스 실행하는 데만 시간을 다 소모할 것이다. 필요한 부분만 CGI로 만든다는 절충안을 쓴다 해도 요즘의 웹에는 동적인 것처럼 보이지 않아도 동적인 부분이 많기 때문에 적합하지 않다.
출처:https://namu.wiki/w/Common%20 Gateway%20 Interface

예시를 들어보자, GET /cgi-bin/adder? 1004&233 HTTP/1.1 다음과 같은 요청을 받은 뒤 fork를 호출해서 자식 프로세스를 생성하고, execve를 호출해서 /cgi-bin/adder 프로그램을 자식의 콘텍스트에서 실행함. adder와 같은 프로그램들은 종종 cgi프로그램이라고 불림 그 이유는  이들이 CGI 표준 규칙을 준수하기 때문. CGI프로그램은 자신의 동적 콘텐츠를 표준 출력으로 내보낸다. 가능한 이유는 자식 프로세스가 CGI 프로그램을 로드하고 실행하기 전에 리눅스 dup2함수를 사용해서 표준 출력을 클라이언트와 연계된 연결 식별자로 지정.

'컴퓨터 시스템 이야기' 카테고리의 다른 글

시그널 핸들러 작성하기  (0) 2021.09.24
Exceptional control flow  (0) 2021.09.22
copy on write  (0) 2021.09.16
Memory system  (0) 2021.09.15
Chapter 1 컴퓨터 시스템으로의 여행(1.8 ~ 끝)  (2) 2021.08.22