Network

성공과 실패를 결정하는 1%의 네트워크 원리 6장: 여행의 끝

Debin 2023. 2. 2.
반응형

Chapter 6. 웹 서버에 도착해 응답 데이터가 웹 브라우저로 돌아간다.

방화벽, 캐시 서버, 부하 분산 장치를 통과하면 패킷은 웹 서버로 들어간다.

01. 서버의 개요

1. 클라이언트와 서버의 차이점

  • 서버를 기동한 후 여러 가지 준비 동작을 하기 시작하여 클라이언트에서의 액세스에 응하는 상태가 된다.
  • 클라이언트에서 도착한 패킷을 수신하여 처리하는 것은 이러한 준비 작업이 끝난 후의 일이다.
  • 클라이언트와 서버에서 하드웨어, OS, 네트워크 부분은 동일하다. 대신 사용법이 조금 다르다.
  • 클라이언트에서 는 접속 동작을 수행하고, 서버는 그것을 기다리는 형태가 되므로 Socket 라이브러리의 사용법이 조금 다르다.
  • 또한 서버의 애플리케이션은 다수의 클라이언트 PC와 대화한다는 차이점도 있다. 그러므로 서버 애플리케이션은 클라이언트 애플리케이션과 구조가 다르다.

2. 서버 애플리케이션의 구조

  • 클라이언트가 접속할 때마다 새로 서버 프로그램을 작동하여 서버 애플리케이션이 클라이언트와 1대 1로 대화하는 방법을 선택하는 것이 일반적이다.
  • 서버 OS는 멀티태스크 또는 멀티스레드라는 기능에 의해 다수의 프로그램을 동시에 함께 작동할 수 있다.
  • 미리 클라이언트와 대화하는 몇 개의 부분을 작동시켜 두고 클라이언트가 접속했을 때 클라이언트의 상대를 처리하지 않는 비어있는 것을 찾아 여기에 접속한 소켓을 건네주어 클라이언트와의 대화를 계속하는 방법도 있다.

3. 서버측의 소켓과 포트 번호

  • 데이터 송, 수신 동작의 시점에서 보았을 때 클라이언트와 서버의 차이점은 접속하는 측이 클라이언트이고, 접속을 기다리는 측이 서버다.
  • 클라이언트측에서는 접속 동작을 실행할 때 서버측의 소켓에 할당한 포트 번호를 지정하는데, 이것이 포트 번호다.
  • 구체적인 번호는 규칙에 의해 애플리케이션마다 결정되어 있고, 웹 서버의 경우는 80번이다.
  • 서버에서는 포트 번호를 기록하면  Socket 라이브러리에서 listen을 호출해 소켓에 접속하기를 기다리는 상태라는 제어 정보를 기록한다.  그러면 소켓은 클라이언트에서 접속 동작의 패킷이 도착하는 것을 기다리는 상태가 된다.
  • 그리고 accept를 호출해 접속을 접수한다. 이 시점에서는 아직 클라이언트의 접속 패킷이 도착하지 않은 상태다.
    접속 패킷이 도착하지 않았으면 도착을 기다리는 상태가 되어 패킷이 도착할 때 접속 접수 동작을 실행한다.
  • 그러므로 accept를 실행한 시점에서 보통 서버측은 패킷의 도착을 기다리는 상태가 되고, 애플리케이션은 쉬는 상태가 된다.
  • 이 상태에서 애플리케이션에서 접속 패킷이 도착하면 응답 패킷을 반송하여 접속 접수 동작을 실행한다.
  • 그리고 접속 대기의 소켓을 복사해 새로운 소켓을 만들고, 접속 상대의 정보를 비롯한 제어 정보를 새 소켓에 기록한다.
  • 여기까지가 accept를 호출했을 때의 동작으로, 이렇게 해서 새 소켓이 클라이언트측의 소켓과 연결된다.
  • 기억할 부분은 접속 대기의 소켓을 복사하여 새 소켓을 만들고, 새 소켓을 클라이언트측의 소켓과 접속한 후 원래 소켓은 그대로 접속 대기 상태로 두는 것이다.
  • 새 소켓을 만들 때는 포트 번호도 요점이다. 포트 번호는 소켓을 식별하기 위한 것이므로 소켓마다 다른 번호를 할당해야 한다.
  • 이 개념을 지키려면 복사한 새로운 소켓은 원래의 접속 대기 소켓과 다른 포트 번호를 할당해야 한다.
  • 여기서 문제가 있다. 예를 들어 클라이언트에서 80번이라는 포트 번호의 소켓에 접속 패킷을 보냈을 때 이것과는 다른 포트 번호의 소켓에서 회답이 돌아오는 것이다.
  • 이렇게 되면 접속 패킷을 보낸 상대로부터 회답이 돌아왔는지 아니면 다른 상대로부터 잘못도니 회답의 패킷이 돌아왔는지 판별할 수 없다.
  • 그러므로 새로 만든 소켓에도 접속 대기 소켓과 같은 포트 번호를 할당해야 하는데 여기서도 문제가 있다.
  • 같은 번호를 할당한 여러 개의 소켓이 존재해서 포트 번호로 소켓을 지정할 수 없게 된다는 것이 문제다.
  • 이를 해결하기 위한 방법이 존재하는데 소켓을 지정할 때 서버측의 소켓에 할당한 포트 번호 뿐만 아니라 클라이언트측의 포트 번호도 사용하고 IP 주소도 추가하여 다음의 네 가지 정보를 사용하는 것이다. (클라이언트와 서버의 IP, 클라이언트와 서버의 포트 번호)

02. 서버의 수신 동작

1. LAN 어댑터에서 수신 신호를 디지털 데이터로 변환한다.

  • 수신 동작은 패킷의 신호를 LAN 어댑터에서 수신하고 디지털 데이터로 바꾸는 부분에서 시작된다.
  • LAN을 흐르는 패킷의 신호는 1과 0으로 이루어진 디지털 데이터의 신호와 타이밍을 나타내는 클록 신호를 합성한 것이고, 여기에서 클록 신호를 추출해 클록 신호에서 타이밍을 계산하면서 신호를 읽어오면, 1과 0의 디지털 데이터로 바꿀 수 있다.
  • 다음은 패킷의 맨 마지막에 있는 프레임 체크 시퀀스라는 오류 검사용 데이터를 이용해 오류 유무를 검사한다.
  • FCS가 일치하고 오류가 없는 것을 확인한 다음에는 맨 앞의 MAC 헤더에 있는 수신처 MAC 주소를 조사하여 패킷이 자신을 수신처로 하여 보낸 것이 맞는지 판단한다. 수신처가 자신으로 되어있는 패킷만 남기고 다른 패킷은 버린다.
  • 이로써 신호를 수신해 디지털 데이터로 되돌리는 동작은 끝났으므로 디지털 데이터로 되돌린 것을 LAN 어댑터 내부의 버퍼 메모리에 저장한다. 여기까지는 LAN 어댑터의 MAC 부분이 실행한다.
  • 그 사이에 서버의 CPU는 패킷의 도착을 감시하고 있는 것이 아니라 다른 일을 실행하고 있으므로 CPU가 알아차리지 못하는데, 수신처리가 진행되지 않으므로 인터럽트 방법을 사용해 LAN 어댑터에서 CPU로 패킷의 도착을 알린다.
  • 그럼 CPU는 실행하고 있떤 작업을 중단하고 LAN 드라이버로 실행을 전환한다.
  • 이렇게 LAN 드라이버가 동작하기 시작하여 LAN 어댑터의 버퍼 메모리에서 수신한 패킷을 추출하고 MAC 헤더 타입 필드의 값에 따라 프로토콜을 판별하고, 프로토콜을 처리하는 소프트웨어를 호출한다.
  • 타입 필드의 값은 IP 프로토콜을 나타내는 값으로 되어있으므로 TCP/IP의 프로토콜 스택을 호출하고 여기에 패킷을 건네준다.

2. IP 담당 부분의 수신 동작

  • 프로토콜 스택에 패킷이 전달되면 IP 담당 부분이 동작해 IP 헤더를 점검한다.
  • IP 헤더의 내용이 규칙에 따라 올바르게 만들어졌는지부터 점검한 후 수신처 IP 주소가 자신을 대상으로 하는지 조사한다.
  • 서버에서 라우터와 같이 패킷을 중계하는 기능이 유효하게 된 경우에는 자신을 대상으로 하지 않은 패킷이 도착할 수 있다.
  • 그러면 라우터와 같이 경로표에서 중계 대상을 조사하고 그것에 패킷을 중계한다.
  • 패킷이 자신을 대상으로 한 것임을 확인할 수 있으면, 다음에는 조각 나누기에 의해 패킷이 분할되었는지 조사한다. 이는 IP 헤더를 통해 확인할 수 있다. 분할되어 있는 경우에는 패킷을 메모리에 일시적으로 저장한다.
  • 그리고 분할된 패킷의 조각이 전부 도착한 시점에서 패킷의 조각을 조립해 원래의 패킷으로 복원한다.
  • 패킷이 분할되어 있지 않으면 받은 패킷은 원래의 모습 그대로여서 이 패킷 조립 동작은 필요 없으므로 패킷을 받은 것이 된다.
  • 그러면 IP 헤더의 프로토콜 번호 항목이 06이라면 TCP 담당 부분에 넘겨주고, 11이면 UDP 담당으로 넘겨준다.
    TCP 부분을 더 알아보자.

3. TCP 담당 부분이 접속 패킷을 수신했을 때의 동작

  • 패킷이 접속 동작의 패킷인 경우 TCP 담당 부분은 TCP 헤더의 SYN 컨트롤 비트를 확인하고 수신처  포트 번호를 조사 한 후 해당하는 접속 대기 소켓을 복사하여 새 소켓을 작성하고 송신처의 IP 주소나 포트 번호, 시퀀스 번호의 초기 값, 윈도우의 값 등을 기록한다.
  • 동시에 송신 버퍼나 수신 버퍼로 사용하는 메모리 영역을 확보하고, 패킷을 받았음을 나타내는 ACK 번호, 서버에서 클라이언트에 보내는 데이터에 관한 시퀀스 번호의 초기값, 클라이언트에서 서버로 보내온 데이터를 받기 위한 수신 버퍼의 빈 용량을 나타내는 윈도우 값 등의 항목을 기록한 TCP 헤더를 만들고, 이것을 IP 담당 부분에 의뢰해 클라이언트에 반송한다.
  • 이 패킷이 클라이언트에 도착하면 클라이언트에서 패킷을 받았음을 나타내는 ACK 번호가 돌아올 것이다. 이러면 접속 동작은 완료된다.

4. TCP 담당 부분이 데이터 패킷을 수신했을 때의 동작

  • 다음은 데이터  송, 수신 단계에 들어가서 데이터 패킷이 도착한 경우의 동작이다.
  • TCP 담당 부분은 도착한 패킷이 어느 소켓에 해당하는지 조사한다. IP 헤더의 송신처 IP 주소와 수신처 IP 주소, TCP 헤더의 수신처 포트 번호와 송신처 포트 번호라는  4개의 정보가 모두 합치되는 소켓을 찾는다.
  • 이들 4개 정보가 합치되는 소켓을 발견하면 패킷에 기록되어 있는 데이터 송, 수신의 진행 상황과 도착한 패킷의 TCP 헤더의 정보를 결합하여 데이터 송, 수신  동작이 올바르게 진행되고 있는지 점검한다.
  • 문제가 없다면 서버에 잘 도착한 것이다. 그러면 패킷에서 데이터 조각을 추출해 수신 버퍼에 저장한다. 이때 지난 번 패킷에서 수신한 데이터 조각의 다음에 연결되는 식으로 해서 데이터를 분할하기 전의 상태로 되돌린다.
  • 이 과정을 통해 수신한 데이터를 수신 버퍼에 저장하면 수신 확인 응답용 TCP 헤더를 만든다. 그리고 여기에 수신 패킷의 시퀀스 번호와 데이터 조각의 길이로부터 계산한 ACK 번호를 기록하고, IP 담당 부분에 의뢰하여 클라이언트에 반송한다.
  • 이후 수신한 데이터를 받아온 부분에서 애플리케이션에 건네준다. 즉 TCP 담당 부분의 수신 동작이 끝나는 것과 동시에 애플리케이션에 데이터를 건네주는 동작이 시작된다.
  • 이후 제어가 서버 애플리케이션으로 넘어가서 받은 데이터를 처리하는 장면, 즉 HTTP의 리퀘스트 메시지의 내용을 조사하고, 내용에 따라 브라우저에 데이터를 반송하는 동작으로 넘어간다.

5. TCP 담당 부분의 연결 끊기 동작

  • 데이터 송, 수신 동작이 끝나면 연결 끊기 동작에 들어간다. 이때의 동작은 클라이언트측과 동일하다.
  • 지난번에 살펴본 것과 비슷하게 보통은 서버에서 연결 끊기 동작을 시작한다.

03. 웹 서버 소프트웨어가 리퀘스트 메세지의 의미를 해석하여 요구에 응한다.

1. 조회의 URI를 실제 파일명으로 변환한다.

  • 단순히 URI에 기록되어 있는 경로명의 파일명을 읽어오면 디스크의 파일에 전부 액세스할 수 있게 되므로 웹 서버의 디스크가 무방비 상태로 노출되어 위험하다. 그래서 한 가지 대첵이 있다.
  • 웹 서버에서 공개하는 디렉토리는 디스크의 실제 디렉토리가 아니라 가상으로 만든 디렉토리이고, 이 가상의 디렉토리 구조에서의 경로명을 URI에 쓰는 것이다. 그러므로 파일을 읽어올 때는 가상의 디렉토리와 실제 디렉토리의 대응 관계를 조사하고, 실제 디렉토리의 경로명으로 변환한 후 파일을 읽어 데이터를 반송한다.
  • 파일명을 바꿔쓰는 규칙을 서버측에 설정하고 규칙에 따라 파일명을 바꿔쓰고 나서 파일에 액세스하는 웹 서버 애플리케이션도 있다.

2. CGI 프로그램을 작동하는 경우

  • URI에 쓴 파일의 내용이 HTML 문서뿐만 아니라 프로그램 파일의 이름을 URI에 쓸 수도 있다.
  • 이런 경우에는 파일의 내용을 그대로 반송하지 않고 해당 프로그램을 작동시켜서 프로그램이 출력하는 데이터를 클라이언트에 반송한다.

3. 웹 서버로 수행하는 액세스 제어

  • 리퀘스트 메시지의 내용에서 데이터 출처를 판단하고, 그곳에서 데이터를 얻어 클라이언트에 반송한다는 것이 웹 서버의 기본 동작이다. 하지만 그 동작을 실행할 때 사전에 설정해 둔 조건에 해당하는지 조사하고, 조건에 해당하는 경우 그 동작을 금지하거나 조건에 해당하는 경우만 동작을 실행한다는 기능도 있다.
  • 이와 같이 조건에 따라 액세스 동작 여부를 설정하는 기능을 액세스 제어라고 하며, 회원제의 정보 제공 서비스 등에서 특정 사용자에게만 액세스를 하거하는 것과 같은 경우 액세스 제어를 사용한다.
  • 웹 서버에서 설정하는 조건은 주로 클라이언트의 주소, 클라이언트의 도메인명, 사용자명과 패스워드다.
  • 클라이언트 IP 주소가 조건으로 설정되어 있는 경우 accept로 접속을 접수했을 때 클라이언트의 IP 주소를 알 수 있으므로 이것을 점검하면 된다.
  • 클라이언트의 도메인명이 조건으로 설정되어 있는 경우에는 클라이언트의 IP 주소에서 도메인 명을 조사하는데, 이때 DNS 서버를 이용한다. IP 주소를 이용해 도메인 명을 조사하는 것이다.
  • 사용자명과 패스워드는 리퀘스트 메시지에 기록되어 있고, 이것을 웹서버는 설정과 비교하고 액세스 가능 여부를 판단해 액세스를 허가하는 경우에 데이터를 반송한다.

4. 응답 메시지를 되돌려 보낸다.

  • 이렇게 해서 리퀘스트 메시지에 대해 적절하게 처리하고 처리가 완료되면 응답 메시지를 반송한다.
  • 이때의 개념은 최초에 클라이언트가 리퀘스트 메시지를 웹 서버에 보내는 동작과 같다.

04. 웹 브라우저가 응답 메시지를 받아 화면에 표시한다.

1. 응답 데이터의 형식을 보고 본질을 판단한다.

  • 웹 서버가 보낸 응답 메시지는 다수의 패킷으로 나뉘어 클라이언트에 도착하는데, 클라이언트가 이를 수신한다.
  • 그럼 서버와 동일하게 LAN 어댑터가 신호로부터 디지털 데이터로 되돌리고, 프로토콜 스택이 분할된 패킷을 모아서 데이터 부분을 추출해 원래의 응답 메시지를 되돌린 후 브라우저에게 건네준다. 나중에 브라우저의 화면 표시 동작으로 진행된다.
  • 화면 표시 동작은 응답 메시지에 저장된 데이터가 어떤 종류인지를 조사하는 것부터 시작한다.
  • 웹에서 취급하는 데이터는 문장, 화상, 음성, 영상 등 다양하고 종류에 따라 표시 방법이 다르므로 최초에 종류를 조사한다. 그렇지 않으면 표시 동작을 올바르게 실행할 수 없다.
  • 데이터의 종류를 판단하는 근거는 몇 가지가 있는데, 응답 메시지의 맨 앞부분에 있는 'Content-Type'이라는 헤더 파일의 값으로 판단하는 것이 원칙이다.
  • 다음으로 조사할 헤더는 'Content-Encoding'이다. 압축 기술이나 부호화 기술에 따라 원래 데이터를 변환하고 나서 메시지에 저장한 경우에는 어떤 변환을 했는지 해당 헤더 필드에 기록해야 한다. 그러므로 이 필드를 조사하여 필요에 따라 원래대로 되돌려야 한다.
  • Content-Type 헤더만으로는 데이터의 종류를 명확하게 판단할 수 없을 때도 있다. 그러면 다른 판단 근거를 사용해 종합적으로 데이터의 종류를 판단하는 경우도 있다. 파일의 확장자나 데이터 내용의 포맷 등에서 종합적으로 판단하는 것이다.

2. 브라우저 화면에 웹 페이지를 표시해 액세스를 완료한다.

  • 데이터의 종류에 따라 화면 표시의 프로그램을 호출해 데이터를 표시하면 된다.
  • HTML, 문서, 일반 텍스트, 화상이라는 기본적인 데이터는 브라우저 자체가 화면 표시 기능을 가지고 있으므로 브라우저가 자체에서 화면 표시 동작을 실행한다.
  • 이렇게 해서 브라우저는 표시 동작을 마치고 사용자가 다음 행동을 하기를 기다린다.
  • 그리고 표시한 페이지 안의 링크를 클릭하거나 URL 입력 상자에 새로운 URL을 입력하면 다시 웹 서버에 대한 액세스 동작이 시작된다.

참고자료

 

컴퓨터 네트워킹 하향식 접근 제 7판

성공과 실패를 결정하는 1%의 네트워크 원리

https://product.kyobobook.co.kr/detail/S000000559964

 

1%의 네트워크 원리 | Tsutomu Tone - 교보문고

1%의 네트워크 원리 | 성공과 실패를 결정하는 1%의 네트워크 원리 (2nd Edition(개정1판 10쇄))이 책만큼 네트워크의 구조와 작동 원리에 대해 체계적으로 설명한 책은 없다! 이 책은 네트워크 기술을

product.kyobobook.co.kr

 

반응형

댓글