트랜스포트 계층의 다중화와 역다중화에 대해서 알아보자
다중화와 역다중화
애플리케이션의 한 부분으로서 프로세스는 소켓을 가지고 있다.
소켓을 통해서 프로세스와 프로세스가 네트워크를 통해 데이터를 주고받을 수 있다.
위 그림을 보면 트랜스포트와 애플리케이션 계층 사이에 소켓(초록 네모 박스)이 있고 소켓과 프로세스가 연결되어 있음을 볼 수 있다. 따라서 트랜스포트 계층은 메시지를 직접 프로세스로 전달하지 않고 중간 매개자인 소켓에게 전달한다. 이때 애플리케이션이 메시지를 받을 다양한 소켓을 가지고 있을 수 있으므로 각 소켓은 TCP 소켓인지 UDP 소켓인지를 구분하는 식별자를 가지게 된다.
역다중화
트랜트포트 계층에 상대 프로세스로부터 수신된 세그먼트 필드 집합이 있다. 이들은 사전에 설정된 트랜스포트 프로토콜에 따라서 알맞게 검사가 된다. 그리고 검사가 완료된 세그먼트 집합은 올바른 소켓으로 전달된다. 이를 역다중화 라고 한다. 여러개로 분할되어서 오는 세그먼트들을 한데 모아서 소켓으로 전송시키는 과정이다.
다중화
애플리케이션 계층에서 메시지를 만들고 이들은 소켓을 통해 트랜스포트 계층으로 넘어간다. 데이터는 세그먼트로 캡슐화 되고 각 세그먼트를 네트워크 계층으로 전달하는 작업을 다중화 라고 한다.
역다중화와 다중화를 애플리케이션 계층과 트랜스포트 계층 사이에서만 설명했지만, 이 작업은 한 계층의 프로토콜이 상위 계층의 프로토콜에 의해 사용될 때마다 필요한 작업이다.
트랜스포트 계층 다중화에는 두 가지 요구사항이 있다.
- 소켓은 유일한 식별자를 가진다.
- 각 세그먼트는 세그먼트가 전달 될 적절한 소켓을 가리키는 특별한 필드를 가진다.
특별한 필드라는 것은 출발지 포트번호 필드와 목적지 포트번호 필드이다. 각각의 포트 번호는 0~65535의 16비트 정수이다. 이 중에서 0~1023 까지의 포트번호를 잘 알려진 포트번호라고 하여 사용을 엄격하게 제한하고 있다. 예를 들어 HTTP(포트번호 80), FTP(포트번호 21), SSL, HTTPS(443), SMTP(25, 587), SSH(22) 등과 같은 유명한 포트들이 있다.
트랜트포트 계층이 역다중화 서비스를 구현하는 방법
- 호스트의 각 소켓은 포트 번호를 할당받는다.
- 세그먼트가 호스트에 도착하면 트랜스포트 계층은 세그먼트 안의 목적지 포트 번호를 검사하고 상응하는 소켓으로 세그먼트를 보낸다.
- 세그먼트의 데이터는 소켓을 통해 해당되는 프로세스로 전달된다.
UDP를 사용한 비연결형 다중화와 역다중화
UDP 소켓 19000을 가진 호스트 A의 프로세스가 호스트 B의 UDP 소켓 46000을 가진 프로세스에게 데이터 전송을 원한다고 가정하자. 호스트 A의 트랜스포트 계층은 애플리케이션 데이터, 출발지 포트번호(19000), 목적지 포트번호(46000), 그리고 다른 2개의 중요하지 않은 값을 포함하는 세그먼트를 생성한다. 만들어진 세그먼트는 네트워크 계층으로 전달된다. 네트워크 계층은 세그먼트를 IP 데이터그램으로 캡슐화 하고 목적지 호스트로 전송한다. 세그먼트가 목적지에 도착하면 목적지 호스트는 세그먼트 안의 목적지 포트번호(46000)을 검사하고 그 세그먼트들을 46000포트로 역다중화하여 전달한다.
과정에서 UDP 소켓은 목적지 IP 주소와 목적지 포트번호에 의해서만 식별된다. 따라서 만약 2개의 UDP세그먼트들이 출발지 IP주소 또는 출발지 포트번호가 다른 경우 동일한 목적지 IP, 포트번호를 가진 프로세스에 도착할 것이다. 이는 프로세스가 데이터를 받았지만 누구의 데이터인지 확인할 방법이 없기 때문에 UDP가 왜 단방향 통신의 특성을 가지는지에 대한 이유가 된다.
TCP를 사용한 연결형 다중화와 역다중화
TCP 역다중화를 수행하기 위해서는 TCP 소켓과 TCP 연결 설정을 봐야한다. TCP 소켓과 UDP 소켓의 차이점은 TCP 소켓은 출발지 IP주소, 포트번호, 목적지 IP주소, 포트번호 총 4가지 정보가 필요하다는 점이다. 호스트에 TCP 세그먼트가 도착하면, 호스트는 알맞은 소켓으로 역다중화 하기 위해서 4개의 값을 모두 사용한다.
- TCP 애플리케이션은 8000번 포트를 가지고 있다.
- TCP 클라이언트는 소켓을 생성하고 연결 설정을 요구하는 세그먼트를 애플리케이션으로 전송한다.
- 연결 설정 요청은 목적지 포트번호, IP와 출발지 포트번호, IP를 포함하는 세그먼트에 지나지 않는다.
- 프로세스로 동작하는 컴퓨터의 호스트가 목적지 포트 8000을 포함하는 연결 요청 세그먼트를 수신하면, 포트 번호 8000 상에서 연결을 기다리는 애플리케이션을 찾는다. 그때 서버는 새로운 소켓을 생성한다.
- 앞으로 연결 요청이 들어오면 세그먼트의 출발지 포트번호, IP, 목적지 포트번호 , IP를 확인해서 생성된 소켓과 일치하는지 확인한다. 만약 일치한다면 데이터의 역다중화를 통해 프로세스는 데이터를 받을 수 있을 것이다.
위 그림에서 호스트 C는 웹 서버 B로 HTTP 요청 2개를 보내고 있다. 호스트 A는 웹 서버 B로 HTTP요청 하나를 보내고 있다. 그런데 호스트 C의 요청 중 하나와 호스트 A의 요청의 출발지 포트가 26145로 같은 상황이다. 출발지 포트 번호는 애플리케이션측에서 랜덤으로 설정되는 값이다. 하지만 호스트의 위치가 다르기 때문에 서로 다른 IP를 가지게 되고 호스트 A와 C의 요청은 올바르게 구분되어 역다중화 될 수 있다.
웹 서버와 TCP
웹 서버중 하나인 nginx를 예시로 웹 서버가 어떻게 포트번호를 사용하는지 알아보자. nginx는 멀티 프로세스, 싱글 스레드 방식이다. 주로 리버스 프록시로 사용되고 http/https 요청을 받는다. nginx는 프로세스나 스레드에 대한 지속적인 생성/파괴 패턴이 없기 때문에 CPU 자원 소모를 절약한다는 특징이 있다.
nginx를 통해 웹사이트가 정적 파일을 서비스하고 있다고 가정하자.
클라이언트는 특정 버튼을 눌러 nginx에게 HTTP 요청(80번 포트)을 보낼 수 있다. 이때 80번 포트가 TCP로 열려있다면 위에서 설명한 4개의 정보를 이용해 임의의 소켓을 열어둘 수 있다. 만약 AWS 클라우드를 사용해서 서버를 가동중이라면 보안 그룹 구성 탭에서 특정 포트에 대해 어떤 트랜스포트 프로토콜을 사용할 지 설정할 수 있다.
데이터는 소켓을 통해 들어오게되고 nginx는 데이터를 WAS(웹 애플리케이션 서버)에 넘겨주게 된다. WAS는 항상 nginx가 주는 데이터만 받을 수 있으며(설정 가능) 따라서 소켓도 계속 생성하고 삭제할 필요가 없어진다.
만약 클라이언트와 웹서버가 지속적인 HTTP를 사용한다면 지속적인 연결기간 동안에 클라이언트와 서버는 동일한 서버 소켓을 통해서 HTTP 메시지를 교환한다. 이는 서버의 특정 시간 내의 TCP 연결의 수를 그만큼 적게 함으로써 CPU나 메모리 자원을 절약할 수 있고, 네트워크 혼잡을 줄일 수 있다. 하지만 비지속적인 HTTP를 사용한다면 모든 요청/응답마다 새로운 TCP연결을 생성/삭제하고 이에 맞는 소켓도 생성/삭제 될것이다. 따라서 많은 CPU 및 메모리 자원이 소모될 것이다.
현재 대부분 사용하고 있는 HTTP 1.1 은 지속적 연결을 기본적으로 지원한다.
만약 HTTP 1.0 에서 지속적 연결을 사용하기 위해서는 서버에게 HTTP 요청 시, 요청 메시지 내부에 다음 헤더를 추가한다.
> connection: keep-alive
'CS > Network' 카테고리의 다른 글
[Network] 트랜스포트 계층 : 흐름제어, TCP 연결 (0) | 2021.09.28 |
---|---|
[Network] 트랜트포트 계층 : TCP 연결 (연결 지향형) (0) | 2021.09.24 |
[Network] 트랜스포트 계층 : 개요(Intro) (0) | 2021.09.16 |
[Network] 인터넷 프로토콜 계층과 캡슐화 (0) | 2021.09.09 |
[Network] 네트워크 코어 (0) | 2021.09.06 |