▶ 대부분의 컴퓨터 네트웍 프로그램은 클라이언트-서버 모델로 구현되는데 서비스를 제공하는 장비를 서버라 하고 서비스를 받는 장비를 클라이언트라 한다.
▶ 컴퓨터 네트웍의 역할은 네트웍에 접속된 임의의 클라이언트가 임의의 서버와 연결될 수 있도록 하는 것이다.

1-14 컴퓨터 네트웍과 클라이언트-서버 통신 모델
▶ 일반적으로 네트웍 서비스를 받기 위하여 클라이언트가 통신을 시작한다.
▶ 클라이언트는 서버에 접속을 시도하고 그 연결 결과를 기다린다든가(연결형 서비스의 경우), 어떤 서비스를 요구하고 응답을 기다린다.
▶ 클라이언트의 이와같은 요구(request)에 대하여 서버는 응답(response)을 보내는 방식으로 동작이 이루어진다.
▶ 서버는 파일 시스템, 통신 포트 등의 자원을 관리하기 위하여 root 권한을 갖는 경우가 많으므로 클라이언트가 서버 프로그램을 통하여 서버의 자원을 임의로 액세스하지 못하도록 주의하여 서버 프로그램을 구현하여야 한다.
▶ 예를들면 접속된 클라이언트가 서비스를 제공할 대상인지 확인하기 위하여 클라이언트의 id를 검사하거나(authentication), 서버의 정보의 유출, 변경 등을 확인하거나(security), 여러 클라이언트에게 서비스를 동시에 제공하는 기능(concurrency) 등이 필요할 수 있으며 따라서 클라이언트보다 구현이 복잡하다.
▶ 클라이언트-서버 통신 프로그램을 작성하려면 서버를 어떠한 방식으로 구현할지를 먼저 정해야 한다.
▶ 클라이언트는 서버의 구현 형태에 따라서 단순히 서비스를 요청하는 것이므로 우선 서버의 구현 방식을 정하는 것이 중요하다.
▶ 서버의 구현기술 종류로 연결형과 비연결형 서버, state- less와 stateful 서버, iterative와 concurrent 서버에 대하여 각각의 구현 방법과 특징을 설명하겠다.
(1) 연결형과 비연결형 서버
▶ 클라이언트와 서버의 통신에서 사용할 트랜스포트 계층 프로토콜의 종류(즉, TCP 또는 UDP)에 따라 연결형 서버와 비연결형 서버로 나눌 수 있다.
▶ 연결형 서버는 스트림형 트랜스포트 프로토콜(TCP)을 사용하며 데이터의 안정적인 전달(전송 순서 유지, 재전송 제공 등)을 보장하는 서버이다.
▶ 연결형 서버의 단점은 모든 클라이언트와의 접속마다 소켓을 각각 개설하고 있어야 한다는 것이다(소켓에 관하여는 2.1절에서 설명함).
▶ 한 컴퓨터에서 동시에 열 수 있는 파일 수가 제한되듯이 소켓을 많이 개설하면 시스템 자원을 많이 사용하게 된다.
▶ 서버에서 소켓을 개설하는 것이 계속 누적되면 서버가 메모리 사용의 증가로 동작을 정지할 수도 있으므로 이를 주의하여야 한다.
▶ 비연결형 서버는 비연결형 트랜스포트 프로토콜(UDP)을 사용하는 서버로 네트웍이 안정적인 데이터의 전달을 책임지지 못하기 때문에 응용 프로그램이 필요하면 이를 보상해 주어야 한다.
▶ 비연결형 서버의 장점은 하나의 소켓을 통하여 다수의 클라이언트에게 서비스를 제공할 수 있으므로 자원(소켓, 메모리)을 절약할 수 있다는 것이다.
▶ TCP는 일대일 접속만 지원하므로 방송형 또는 멀티캐스팅을 필요로 하는 응용 프로그램에서는 비연결형(UDP) 서버를 이용하는 것이 편리하다.
▶ 연결형과 비연결형 서버의 특징을 표 1-6에 비교하였다.
(2) Stateful과 Stateless 서버
▶ 서버가 클라이언트와의 통신 상태(state)를 계속 추적하며 이 상태 정보를 서비스 제공에 이용하는 서버를 stateful 서버라고 한다.
▶ 상태란 과거의 동작(데이터 송수신 및 처리) 결과라고 할 수 있는데 서버의 현재 상태에 따라서 클라이언트로부터의 요구(request)마다 취하는 응답(response)이 달라질 수 있다.
▶ 상태 정보를 사용하면 현재의 상태에 따라 약속된 명령에 대하여 신속히 응답할 수 있게 되며, 클라이언트와 주고 받을 메시지의 크기를 줄일 수 있다.
▶ 예를들어 서버가 현재 파일을 열고(open) 일정 크기로 데이터를 읽거나 지울 수 있는 상태에 있다고 하자.
클라이언트가 '0'이라는 명령(request)을 보내면 100바이트를 서버가 읽어 클라이언트로 보내고 '1'이라는 request를 보내면 100바이트를 파일에서 지우도록 약속되어 있다면, 클라이언트는 request로 사용하는 메시지의 크기를 한 비트로 작게 할 수 있으며 서버도 약속된 명령을 신속히 처리할 수 있다.
▶ stateful 서버를 사용하는 경우 현재의 상태 정보가 잘못되어 있거나 request에서 비트 오류가 발생하면 오동작을 할 가능성이 높다는 단점이 있다.
▶ 통신의 동작 상태를 정의하지 않고 항상 클라이언트로부터의 독립적인 request에 의해 서비스를 제공하는 서버를 stateless 서버라고 한다.
▶ 즉 stateless 서버는 클라이언트로부터 새로 도착한 명령문(request)에만 의존하여 서비스를 제공한다.
▶ stateless 서버를 사용하는 장점은 틀린 상태 정보를 사용할 가능성을 없앰으로써 서버가 안정적으로 동작한다는 것이다.
▶ 상태 정보는 과거의 정보이므로 클라이언트가 이전에 보낸 메시지에서 오류가 발생했으면 틀린 상태로 가 있을 수 있기 때문이다.
▶클라이언트가 stateless 서버로 보내는 request는 서버가 동작하기에 필요한 모든 정보를 가지고 있어야 하므로 메시지의 길이가 stateful 서버의 경우보다 길어질 수 있다.
▶ 네트웍이 안정적인(즉, 오류 및 순서 바뀜이 적은) 경우에는 stateful 서버를 사용하는 것이 유리하다.
▶ 인터넷의 환경은 패킷의 복사, 분실, 오류, 지연, 순서 바뀜 등이 발생할 가능성이 크므로 안정적이라고 할 수 없다.
▶ stateful 서버를 사용하는 경우는 네트웍 또는 서버가 reset되었을 때 모든 상태 정보도 reset되어야 하고 모든 동작이 reset된다는 단점이 있다.
▶ 오동작을 최소화하는 범위에서 상태 정보를 적절히 이용하는 프로그래밍 기술이 필요하다.
(3) Iterative와 Concurrent 서버
▶ Iterative 서버는 클라이언트의 서비스 요구를 순서대로 처리해 주는 서버이다.
▶ 클라이언트로부터의 각 request를 충분히 짧은 시간 동안에 처리할 수 있어 다른 클라이언트들이 기다리는 시간이 거의 없거나 별로 문제가 되지 않는 경우에 사용할 수 있다.
▶ Iterative 서버는 프로그램 구현이 다음에 설명할 con- current 서버보다 비교적 간단하다.
▶ Concurrent 서버는 여러 클라이언트가 요구하는 서비스를 동시에(concurrently) 제공할 수 있는 서버를 말한다.
▶ Concurrent 서버는 동시에 여러 클라이언트들에게 서비스를 제공하기 위하여 새로운 클라이언트가 접속될 때마다 이 클라이언트가 요구하는 서비스를 처리할 프로세스를 계속 만들어야 한다.
▶ 이 방법은 클라이언트 수가 늘어남에 따라 프로세스 수도 계속 늘어나게 되므로 다수의(예를들면 수백개) 클라이언트가 접속될 수 있는 서비스에서는 사용할 수 없다.
▶새로운 클라이언트들이 새로 접속되어도 이를 처리할 프로세스를 계속 생성하지 않고, 마치 운영체제가 여러 작업을 스케줄링하듯이 하나의 프로세스가 모든 서비스를 동시에(concurrently) 처리하는 방법이 널리 사용된다.
▶ 이러한 방식으로 구현되는 서버를 apparent concurrent 서버라고 하며 이에 대하여는 4.2절에서 설명하겠다.