상위 문서: 컴퓨터 네트워크
개요
Transport layer protocol은 서로 다른 호스트에서 실행되는 애플리케이션 프로세스들 사이의 logical communication을 제공한다. logical communication이란, 애플리케이션 관점에서 마치 프로세스가 실행되는 호스트들이 직접 연결된 것처럼 보이는 것을 의미한다. 실제로는 이 호스트들이 지구 반대편에 위치할 수도 있고, 수많은 라우터와 다양한 링크들을 통해 연결되어 있을 수 있다. 애플리케이션 프로세스는 전송 계층이 제공하는 logical communication을 이용해 메시지를 주고받으며, 이러한 메시지가 전달되는 물리적 인프라의 세부 사항에 대해서는 고려할 필요가 없다.
Transport layer protocol은 host(end system) 내부에 구현되며, 라우터 내에서 구현되지 않는다. 송신 측에서는 applicaiton layer에서의 message를 segment로 변환한다. 이 과정에서는 message를 청크(chunk) 단위로 나누고, 각 청크마다 transport layer 헤더 파일을 붙인다. 또한 이 segment들은 송신측 host의 network layer로 전달되어 datagram으로 캡슐화되어 logical communication으로 연결된 호스트로 전달된다. 해당 호스트는 network layer로 부터 수신한 datagram에서 segment를 추출하여 이를 transport layer에 전달한다. transport layer는 해당 segments들을 message로 재조립하여 application layer에서 이용할 수 있도록 한다.
Transport Layer vs. network layer
Transpot layer는 프로세스간의 logical communication을 제공한다. 반면 network layer는 host간의 logical communication을 제공한다. 이를 아래와 같은 예시를 통해서 이해해보자.
서울에는 승빈이가, 세종시에는 준영이가 살고 있는데 두 사람의 집에는 각각 12명의 아이가 살고 있다. 두 집의 아이들은 서로 편지쓰기를 매우 좋아해 주말만 되면 서로서로 편지를 써주며, 이는 우편 서비스를 통해서 각각 별도의 봉투에 담겨서 전달된다. 즉 주말마다 서로의 집에 총 144통(12X12)의 편지가 부쳐지는 셈이다. 서로의 집에 편지가 도착하면, 준영이와 승빈이는 집에 도착한 편지들을 수거하고, 수신인을 확인해 아이들에게 편지를 하나씩 나눠준다. 반대로 아이들이 편지를 쓰면 준영이와 승빈이는 편지를 모아 우체부에게 전달한다.
위의 예시에서 우편서비스는 두 집간의 logical communication을 제공한다. 즉 우편 서비스는 각 아이들 사이에서가 아니라 준영이와 승빈이의 집 사이에서 우편물을 전달한다. 반면, 준영이와 승빈이는 각각의 집안에 있는 아이들 간의 logical communication을 제공한다. 준영이와 승빈이는 아이들로부터 우편물을 수거하고, 아이들에게 우편물을 나눠주기 때문에 아이들 입장에서는 준영이와 승빈이가 우편 서비스이지만, 준영이와 승빈이는 단지 집에 살고 있는 사람들(end system의 일부)일 뿐이다.
| 네트워킹 용어 | 가정집의 비유 |
|---|---|
| application message | 봉투 속의 편지들 |
| process | 집 안의 아이들 |
| host | 집 |
| transport layer protocol | 준영이와 승빈 |
| network layer protocol | 우편 서비스(우체부 포함) |
위 예시에서 승빈이와 준영이는 자신의 할일을 묵묵히 할 뿐이다. 예를 들어 세종시와 서울 사이의 우편 센터에서 우편을 분류하거나, 한 센터에서 다른 센터로 운반하는 일에 관여하지 않는다. 마찬가지로 transport layer protocol도 end system 내에만 존재하며, 애플리케이션 프로세스에서부터 network layer까지 데이터를 전달하고, 반대로도 전달한다. 하지만 네트워크 내부에서 실제로 데이터가 어떻게 이동하는지에 대해서는 관여하지 않는다.
Multiplexing/demultiplexing
Network Layer은 데이터를 호스트에서 다른 호스트로 전달하지만, 하지만 실제로는 호스트 안의 여러 개의 프로세스들이 네트워크를 통해 통신하고 있다. 따라서, 전송 계층은 호스트 간 데이터를 프로세스 간 데이터 전송으로 확장할 필요가 있다. 즉, 호스트들 사이의 연결에서 프로세스들 사이의 연결로 확장하는 것이 Multiplexing과 Demultiplexing이다.
Socket은 프로세스가 네트워크가 데이터를 주고 받을 때 사용하며, 각 프로세스는 하나 이상의 socket을 가질 수 있다. 이 때문에 각 socket은 자신만의 고유한 식별자로 주로 port 번호를 가진다. port 번호는 16비트 정수(0~65535)로 나타내어지며, 0~1023은 특정한 애플리케이션 프로토콜을 위해 예약되어 있다.
Demultiplexing은 transport layer의 segment들을 segment안의 헤더 파일(목적지 포트 번호)을 이용하여 올바른 socket에 전달하는 과정을 일컫는 말이다. 즉, 하나의 전송 계층 프로토콜을 통해 온 데이터가 다시 여러 개의 개별 프로세스로 나누어 전달되는 것이다.
Multiplexing은 반대로 송신 host에서 서로 다른 socket으로 부터 데이터를 모으고, 각 데이터 조각(chunk)에 헤더 파일을 붙여 segment를 생성하고 이를 network layer에 넘겨주는 작업이다. 즉, 여러 프로세스의 데이터가 하나의 전송 계층 프로토콜을 통해 전송되는 것이다.
How demultiflexing works
host는 IP datagram을 수신하며, datagram에는 출발지와 목적지의 IP 주소가 포함되어 있다. 이 IP 주소는 network layer에서 호스트까지 패킷이 정확히 전달되도록 하는 데 쓰인다. 이때 각각의 diagram은 하나의 segment를 포함하고 있으며, segment에는 출발지와 목적지의 port 번호가 포함되어있다. port 번호는 호스트에 도착한 segment가 정확히 어떤 프로세스의 socket으로 전달되어야 하는지 결정하는 데 사용된다. 호스트는 port 번호를 통해 segment을 올바른 애플리케이션 socket에 전달한다.
이때 datagram에 출발지의 IP 주소, segment에 출발지의 port 번호가 포함되는 이유는 몇가지가 있다. 먼저, 출발지(송신자)의 IP 주소와 포트 번호가 없으면, 수신 측은 받은 패킷에 대해 응답을 보낼 방법이 없기 때문이다. 이러한 상황을 막기 위해 해당 정보를 제공하여 수신자가 패킷을 처리한 뒤 다시 회신할 수 있도록 한다.
또한 같은 IP주소를 가진 컴퓨터가 여러 개의 연결을 동시에 맺을 때, 출발지 포트 번호가 없다면 수신측은 정확히 어떤 연결에서 온 데이터인지 구분할 수 없다. 이 때문에 정확한 demultiplexing을 지원하기 위해 해당 정보를 제공한다.
그리고, 보안을 위해서도 필요하다. 출발지 IP 주소와 port 번호는 방화벽이나 라우터 등이 데이터를 필터링하거나 보안 정책을 적용하는 데 사용된다. 예를 들어 특정 IP 주소나 port에서 오는 데이터를 차단하거나 허용하는 방식으로 네트워크 보안을 유지할 수 있다.
Connectionless Demultiplexing
Connectionless Demultiplexing는 UDP와 같은 conectionless 프로토콜에서 데이터를 수신했을 때, 해당 데이터를 호스트 내의 정확한 socket으로 전달하는 과정이다. 이때 송신자와 수신자 간의 handshaking이 없기 때문에 수신 호스트는 각 패킷을 받을 때마다 독립적인 demultiplexing을 수행한다.
Connectionless demultiplexing은 다음과 같은 과정을 통해서 수행된다.
- UDP socket은 생성될 때 내부적으로 로컬 port 번호를 가진다.
- 송신자는 데이터를 전송할 때, 목적지 IP 주소와 port 번호를 명시한다.
- 수신 호스트가 UDP segment를 받으면 다음 작업을 수행한다.(demultiplexing)
- segment의 목적지 port 번호를 확인하고, 해당 port 번호를 가진 socket에 segment를 전달한다.
- 즉, UDP의 경우 demultiplexing은 목적지의 port 번호만을 기준으로 이루어진다.
따라서 같은 목적지 port 번호를 가진 데이터는, 출발지 IP주소나 port 번호가 달라도 항상 같은 소켓으로 전달된다.
오른쪽에는 호스트 3개가 서로 UDP로 통신하는 상황이 나온다. 이를 표로 정리하면 다음과 같다.
| 호스트 | Socket 이름 | Port 번호 | 프로세스 |
|---|---|---|---|
| Client 1 | mySocket1 | 5775 | P4 |
| Client 2 | mtSocket2 | 9157 | P3 |
| Server | serverSocket | 6428 | P1 |
Client1과 client2는 각각 port 번호를 다르게 가진 UDP socket를 통해 server에게 데이터를 보내고, server는 port 번호 6428을 가진 socket을 통해 데이터를 받는다. 서버는 응답을 보낼 때, 받은 datagram에서 추출한 port 번호를 바탕으로 전송한다.
Connection-oriented demultiplexing
Connection-oriented demultiplexing이란 TCP와 같은 connection-oriented 프로토콜에서 이루어지는 demultiplexing을 의미한다. TCP는 데이터를 보내기 전 handshaking을 반드시 거치며, 해당 과정을 통해 연결을 통해 데이터가 교환됩니다. 이때 수신자는 수신한 datagram이 어떤 연결에서 온 datagram인지를 추적하고, 구분해야 한다. 이때 사용되는 정보가 4-tuple이며, 이는 출발지의 IP 주소와 port 번호, 목적지의 IP 주소와 port 번호로 이루어진다. 즉, UDP가 단순히 목적지의 port 번호만으로 demultiplexing을 하는 것과는 달리, TCP는 4-tuple이라는, 무려 4개의 정보를 이용해 demultiplexing을 수행한다. 이는 TCP가 connect-oriented 프로토콜이기 때문에, 하나의 port가 여러 클라이언트와 동시에 연결을 유지할 수 있기 때문이다. 예를 들어 서버 C의 welcome socket[1]의 port 번호가 80이고 A와 B라는 두 클라이언트가 connection을 요청한다고 하자. 이때 새롭게 생성되는 connection socket은 다음과 같다.
connectionSocket1: (A의 IP 주소, A의 port 번호) → (C의 IP, 80) connectionSocket2: (B의 IP 주소, B의 port 번호) → (C의 IP, 80)
위의 두 socket은 UDP의 경우와는 달리 socket의 port 번호만으로는 구분되지 않는다. 따라서 TCP는 각각의 연결을 구분하는 것이 demultiplexing에 필수적이며, 이 때문에 4-tuple을 필요로한다.
이는 위 이미지를 통해서 더욱 잘 알 수 있다. 아래는 이미지를 정리한 표이다.
| 클라이언트 | 출발지 IP | 출발지 port 번호 | 목적지 IP (서버) | 목적지 port 번호 |
|---|---|---|---|---|
| Host A | IP: A | 26145 | IP: B | 80 |
| Host C | IP: C | 7532 | IP: B | 80 |
| Host C | IP: C | 26145 | IP: B | 80 |
위와 같이 서버 B의 port 80번에 도착하는 세 개의 segment가 있다고 할 때, 서버 B는 아래의 4-tuple 정보로 연결을 정확히 구별한다.
(A, 26145, B, 80) (C, 7532, B, 80) (C, 26145, B, 80)
연결이 설정된 후 서버는 각각의 연결마다 각각의 socket을 생성하며, 각 연결에서 오는 data는 각 socet으로 정확하게 demultiplexing된다. 즉, server의 port 번호는 같아도 클라이언트의 IP 주소와 port 번호가 다르면 각 연결은 명확하게 구분된다.
UDP와 TCP
UDP
자세한 내용은 UDP 문서를 참조하십시오.
TCP
자세한 내용은 TCP 문서를 참조하십시오.
각주
- ↑ TCP 연결이 이루어지기전, 클라이언트의 connection 요청을 기다리고 있는 소켓을 의미한다.
연결을 바탕으로 새로 생성된 socket의 port 번호는 welcome socket의 그것을 따른다.