[네트워크] Day 11
서버
서버 OS는 멀티태스크 혹은 멀티스레드라는 기능으로 다수의 프로그램을 동시에 함께 작동한다.
멀티 태스크는 OS가 갖추고 있는 기능의 하나로, 복수의 태스크(프로그램)을 동시에 함께 실행하는 기능을 말한다.
하나의 프로세서는 어떤 시점에서 하나의 태스크만 실행할 수 있지만, 단시간에 태스크를 전환하면서 실행하므로 동시에 실행하는 것처럼 보인다.
OS의 종류에 따라 멀티프로세스라고도 불린다.
멀티스레드는 멀티태스크와 같이 복수의 스레드를 동시에 실행하는 기능을 말하고, 멀티태스크와의 차이점은 태스크와 스레드의 차이이다.
OS 내부에서 태스크는 각각 별도의 프로그램으로 취급되지만, 스레드는 한 개의 프로그램 속을 몇 부분으로 나눈 것으로 취급한다.
이 방법은 클라이언트가 접속했을 때 새로 프로그램을 기동하는 부분에서 시간이 걸리고, 응답 시간이 추가로 소요된다는 단점이 있다.
미리 클라이언트와 대화하는 부분들을 작동시켜 두고 클라이언트가 접속했을 때 클라이언트의 상대를 처리하지 않는 빈 것을 찾아
그 곳에 접속한 소켓을 건네주어 클라이언트와 대화를 계속하는 방법도 있다.
데이터를 송수신하는 동작의 관점에서 보면 클라이언트와 서버라는 상태로 역할을 고정시키는 것은 좋은 방법이 아니다.
다양한 형태로 데이터를 송수신하는 구조를 지원하려면 데이터 송수신의 구조에서
클라이언트와 서버라는 식으로 역할을 결정하지 않고, 좌우 대칭으로 어디서나 자유롭게 데이터를 송수신할 수 있도록 해두는 편이 낫다.
하지만 접속 동작은 좌우 대칭으로 할 수 없다. 양 쪽이 동시에 접속하면 안 되고, 양 쪽이 동시에 기다려서도 안 된다.
데이터 송수신 동작의 시점에서 보았을 때 접속하는 측이 클라이언트, 접속을 기다리는 측이 서버가 된다.
클라이언트의 데이터 송수신 동작은 다음과 같은 네 단계로 성립된다.
- 소켓을 만든다.(소켓 작성 단계)
- 서버측의 소켓과 파이프로 연결한다.(접속 단계)
- 데이터를 송수신한다.(송수신 단계)
- 파이프를 분리하고 소켓을 말소한다.(연결 끊기 단계)
이에 비해 서버의 데이터 송수신 동작은 약간의 차이가 있다.
- 소켓을 만든다.(소켓 작성 단계)
- 소켓을 접속 대기 상태로 만든다.(접속 대기 상태)
- 접속을 접수한다.(접속 접수 단계)
- 데이터를 송수신한다.(송수신 단계)
- 파이프를 분리하고 소켓을 말소한다.(연결 끊기 단계)
서버의 동작은 우선 socket을 호출하여 소켓을 만들고, bind를 호출하여 소켓에 포트 번호를 기록한다.
클라이언트측에서 접속 동작을 실행할 때 서버측의 소켓에 할당한 포트 번호를 지정하고 구체적인 번호는
서버 애플리케이션마다 정해져있으며 웹 서버의 경우 80번으로 되어 있다.
포트 번호가 기록된 뒤 listen을 호출하여 소켓에 접속하기를 기다리는 상태라는 제어 정보를 기록하고,
소켓은 클라이언트에서 접속 동작의 패킷이 도착하는 것을 기다리는 상태가 된다.
이후 accept를 호출하여 접속을 접수한다.
소켓을 지정할 때 서버측의 소켓에 할당한 포트 번호뿐만 아니라 클라이언트 측의 포트 번호도 사용하고,
IP주소도 추가하여 다음의 네 가지 정보를 사용한다.
- 클라이언트측의 IP 주소
- 클라이언트측의 포트 번호
- 서버측의 IP 주소
- 서버측의 포트 번호
위 네 가지 정보가 있다고 하더라도, 소켓 식별을 위해 디스크립터를 사용하는 이유는 두 가지가 있다.
첫번째로 접속 대기의 소켓에는 클라이언트 측의 IP 주소와 포트 번호가 기록되어 있지 않고,
두번째로 디스크립터라는 한 개의 정보로 식별하는 쪽이 간단하기 때문이다.
LAN 어댑터에서 수신 신호를 디지털 데이터로 변환하는 과정은 클라이언트의 수신 동작과 동일하다.
수신 동작은 패킷의 신호를 LAN 어댑터에서 수신하고 디지털 데이터로 바꾸는 부분에서 시작된다.
먼저 프리앰블 부분에서 클록을 추출한다.
다음으로 패킷의 맨 마지막에 있는 프레임 체크 시퀀스(FCS)라는 오류 검사용 데이터를 이용하여 오류 유무를 검사한다.
FCS가 일치하고 오류가 없는 것을 확인한 다음에는
맨 앞의 MAC 헤더에 있는 수신처 MAC 주소를 조사하여 패킷이 자신을 수신처로 하여 보낸 것인지 판단한다.
수신처가 자신으로 되어 있는 패킷만 남기고 다른 패킷은 버린다.
신호를 수신하여 디지털 데이터로 되돌리는 동작은 끝났으므로 디지털 데이터로 되돌린 것을
LAN 어댑터 내부의 버퍼 메모리에 저장한다.
CPU에게 패킷 도착을 알리기 위해 인터럽트를 사용하여 LAN 어댑터에서 CPU로 패킷의 도착을 알린다.
프로토콜 스택에 패킷이 전달되면 IP 담당 부분이 동작하여 IP 헤더를 점검한다.
IP 헤더의 내용이 규칙에 따라 올바르게 만들어졌는지부터 점검한 후 수신처 IP 주소가 자신을 대상으로 하는지 조사한다.
패킷이 자신을 대상으로 한 것임이 확인되면 조각 나누기에 의해 패킷이 분할되었는지 조사한다.
분할된 경우 패킷의 조각을 조립하여 원래 패킷으로 복원한다.
IP 헤더의 프로토콜 번호 항목을 조사하여 담당 부분에 패킷을 건네준다.
TCP 담당 부분은 동작한 패킷의 내용에 따라 달라진다.
패킷의 TCP 헤더에 있는 SYN이라는 컨트롤 비트가 1로 되어 있으면 접속 동작의 패킷이다.
이 경우 접속을 접수하는 동작을 실행하고, 그 전에 도착한 패킷의 수신처 포트 번호를 조사하여
이 번호와 같은 번호를 할당한 접속 대기 상태의 소켓이 있는지 확인한다.
해당하는 접속 대기 소켓이 있으면 패킷을 복사하여 새 소켓을 만들고,
여기에 송신처의 IP 주소나 포트 번호, 시퀀스 번호의 초기값, 윈도우의 값 등 필요한 정보를 기록한다.
패킷을 받았음을 나타내는 ACK 번호, 서버에서 클라이언트에 보내는 데이터에 관한 시퀀스 번호의 초기값,
클라이언트에서 서버로 보내온 데이터를 받기 위한 수신 버퍼의 빈 용량을 나타내는 윈도우 값 등의 항목을 기록한
TCP 헤더를 만들고, 이것을 IP 담당 부분에 의뢰하여 클라이언트에 반송한다.
웹 서버 소프트웨어
URI에 쓴 파일의 내용이 HTML 문서나 화상 데이터인 경우에는 파일의 내용을 그대로 응답 메시지로 클라이언트에 반송한다.
하지만 URI에 쓰는 파일의 내용은 HTML 문서뿐만 아니라 프로그램 파일의 이름을 URI에 쓸 수도 있다.
이 경우 파일의 내용을 그대로 반송하지 않고 해당 프로그램을 작동시켜서 프로그램이 출력하는 데이터를 클라이언트에 반송한다.
웹 서버에서 작동시키는 프로그램은 몇 가지 유형이 있고, 그 중에는 CGI(Common Gateway Interface)라는 타입도 있다.
웹 서버에서 프로그램을 작동시키는 경우 프로그램에서 처리하는 데이터를
HTTP의 리퀘스트 메시지 안에 넣어 브라우저에서 웹 서버로 보내는 것이 일반적이다.
리퀘스트 메시지를 보낸 웹 서버는 다음과 같이 작동한다.
웹서버는 먼저 URI의 부분에 쓰여있는 파일명을 조사하여 프로그램인지 확인한다.
프로그램인 경우 OS에 작동을 의뢰하고, 리퀘스트 메시지에서 데이터를 추출하여 작동시킨 프로그램에 건넨다.
이 후 작동시킨 프로그램이 받은 데이터를 처리하여 무언가의 출력 데이터를 웹 서버에 돌려준다.
출력 데이터는 보통 HTML 태그를 내장한 HTML 문서로 되어있고 이것을 그대로 클라이언트에 반송한다.
리퀘스트 메시지의 내용에서 데이터 출처를 판단하고, 그곳에서 데이터를 얻어 클라이언트에 반송한다는 것이 웹 서버의 기본 동작이다.
하지만 그 동작을 실행할 때 사전에 설정해 둔 조건에 해당하는지 조사하고, 조건에 해당하는 경우 금지하거나
해당하는 동작만 실행하는 기능이 있고, 이를 액세스 제어라 한다.
웹 서버에서 설정하는 조건은 주로 다음 세 가지이다.
- 클라이언트의 주소
- 클라이언트의 도메인명
- 사용자명과 패스워드
우선 첫번째로 클라이언트의 주소가 조건으로 설정된 경우 accept로 접속을 접수했을 때 클라이언트의 IP 주소를 점검한다.
클라이언트의 도메인명이 조건으로 설정되어 있는 경우에는 클라이언트의 IP 주소에서 DNS 서버를 이용하여 도메인 명을 조사한다.
클라이언트에서 리퀘스트 메시지를 받은 웹 서버는 프로토콜 스택에 의뢰하여 패킷의 송신처 IP 주소를 조사하고,
IP 주소에 대응하는 이름을 조회하는 메시지를 만들어 가까운 DNS 서버로 보낸다.
DNS서버로부터 IP 주소가 등록된 DNS 서버를 찾아 도메인명 조회 요청을 보내고,
회답이 돌아오면 웹 서버측의 DNS는 웹 서버로 전송한다.
사용자명과 패스워드가 설정된 경우에는 웹 서버는 사용자명과 패스워드를 기록하거나
리퀘스트 메시지를 보내도록 응답 메시지에서 클라이언트에 통지한다.
브라우저는 이 응답 메시지를 받으면 사용자명과 패스워드를 입력하는 화면을 표시하고,
입력받은 값을 리퀘스트 메시지에 기록하고 다시 서버에 액세스한다.
웹 서버가 보낸 응답 메시지는 다수의 패킷으로 나뉘어 클라이언트에 도착한다.
브라우저 화면 표시 동작은 응답 메시지에 저장된 데이터가 어떤 종류인지 조사하는 것부터 시작한다.
데이터의 종류를 판단하는 근거에는 몇 가지가 있는데, 응답 메시지의 맨 앞부분에 있는
Content-type이라는 헤더 파일의 값으로 판단한다.
Content-type 필드를 사용하여 데이터의 종류를 나타내는 방법은 MIME라는 사양에 규정되어 있는데,
웹뿐만 아니라 메일 등에서도 사용하는 일반적인 원칙이지만 어디까지나 원칙에 불과하다.
Today 확인 질문
1. 클라이언트의 데이터 송수신 단계와 서버의 데이터 송수신 단계의 차이점에 대해 말해주세요.
: 클라이언트와 달리 서버의 데이터 송수신 동작에는 서버측의 소켓과 파이프로 연결하는 접속 단계가 없고,
소켓을 접속 대기 상태로 만드는 접속 대기 상태와 접속을 접수하는 접속 접수 단계가 있습니다.
References
성공과 실패를 결정하는 1%의 네트워크 원리