Transport 계층

Network 계층 위에 있는 Transport 계층에 대해 알아보자

Transport Layer

DataLink 계층은 프레임을 전달하기 위해 수신 호스트의 MAC 주소를 요구하고 Network 계층은 패킷을 라우팅하기 위해 IP 주소를 요구한다. 하지만 Transport 계층은 호스트 위에서 실행되는 프로세스 간의 통신을 담당하므로 포트번호를 요구한다. 포트번호는 1개의 호스트에서 실행되는 여러개의 프로세스를 구분하는 데 사용한다.

포트 번호

포트 번호는 3가지로 분류 할 수 있다.

  • 잘 알려진(well-known) 포트 번호

  • 등록된(registered) 포트 번호

  • 동적(dynamic) 포트 번호

잘 알려진 포트번호는 주로 서버 애플리케이션을 식별하기 위해 사용되며, IANA(Internet Assigned Numbers Authority)라는 단체가 지정한다. 예) HTTP의 잘 알려진 포트번호 = 80, SSH의 잘 알려진 포트번호 = 22

등록된 포트번호는 IANA에 의해서 '자주 이용하는 애플리케이션의 포트번호'로 등록된 번호의 범위다. 예) Postgresql의 등록된 포트번호 = 5432

동적 포트번호는 주로 클라이언트 애플리케이션을 식별하기 위해 사용한다. 클라이언트가 서버와 통신할 때에는 OS가 클라이언트에게 임의의 동적 포트번호를 랜덤으로 할당한다. 이 포트번호는 서버에서 클라이언트에게 응답을 보낼 때 사용한다.

TCP

  • 데이터를 송/수신 하는 단위는 세그먼트(segment)다.

  • 세그먼트를 멀티플렉싱(multiplexing), 디멀티플렉싱(demultiplexing)한다.

  • 소켓의 연결 성립, 종료 과정이 있다.

  • 윈도우 제어, 재전송 제어, 혼잡 제어가 가능하다.

Multiplexing, Demultiplexing

전송 계층에서는 클라이언트-서버가 데이터를 송/수신 하기 위해 파이프같은 통로를 서로 연결한다. 세그먼트를 송/수신 하는 과정은 크게 4가지로 분류할 수 있다.

  1. 소켓을 만든다. (소켓 작성 단계)

  2. 서버 측의 소켓에 파이프를 연결한다. (접속 단계)

  3. 세그먼트를 송/수신 한다. (송/수신 단계)

  4. 파이프를 분리하고 소켓을 말소시킨다. (연결 끊기 단계)

이 파이프의 양끝에 있는 데이터의 출입구를 소켓이라고 한다. 소켓 1개는 포트번호 1개를 소유하며 여러 소켓으로부터 들어온 데이터들에게 TCP 헤더를 붙여서 세그먼트를 만들고 네트워크 계층으로 넘기는 것을 멀티플렉싱(multiplexing)이라고 한다. 멀티플렉싱은 데이터를 송신하는 호스트에서 한다.

반대로 디멀티플렉싱(demultiplexing)은 데이터를 수신하는 호스트의 전송계층에서 세그먼트를 분리하여 적절한 소켓으로 데이터를 보내는 것을 뜻한다.

하나의 호스트에서 N개의 포트 번호로 N개의 프로세스를 실행할 수 있기 때문에 두 호스트가 N개의 소켓을 연결할 수 있다. 이는 PC 1대에서 여러 개의 브라우저를 띄워놓고 각기 다른 서버와 통신이 가능한 이유이기도 하다.

TCP header

TCP는 전송할 데이터 크기가 MSS(Maximum Segment Size)보다 크면 데이터를 분할한다. 이 분할 단위를 세그먼트(segment)라고 한다.

이름

Source port

데이터를 송신하는 프로세스의 포트번호.

Destination port

데이터를 수신하는 프로세스의 포트번호.

Sequence Number

송신하는 데이터의 순서를 나타내는 번호. TCP세그먼트의 순서를 제어하는 데 쓰인다.

Ack Number

데이터가 몇 바이트만큼 도착했는지 수신 측에서 송신 측에게 전달하는 데 쓰인다.

Data offset

TCP 데이터의 시작 위치.

Reserved

예약되어 있어서 사용하지 않는 영역.

Control flags

TCP세그먼트의 종류를 나타내기 위한 비트 SYN, ACK, FIN 등을 포함한다.

Window size

수신 측에서 송신 측에게 한번에 수신가능한 데이터의 크기를 통지할 때 쓰인다.

Checksum

TCP헤더와 데이터 부분의 에러체크를 수행할 때 이용한다. 값이 잘못되었을 때 오류가 있음을 인지할 수 있다.

Urgent pointer

Control flags가 URG일 때만 유효하며, 긴급 데이터의 위치를 나타낸다.

Control flags의 종류는 아래와 같다.

이름

ACK

확인 응답을 수행할 때 1이 된다. TCP 연결을 최초로 요청한 호스트의 세그먼트를 제외하고 항상 1이어야 한다.

SYN

연결의 성립을 요구할 때 1이 된다.

PSH

수신한 데이터를 애플리케이션에게 곧바로 전달하길 수신 측에게 요청할 때 1이 된다.

FIN

연결의 정상 종료를 요구할 때 1이 된다.

RST

연결의 강제 종료를 요구할 때 1이 된다.

URG

세그먼트가 긴급한 데이터를 포함했을 때 1이 된다.

TCP의 연결 성립

TCP는 애플리케이션 간의 신뢰성있는 데이터전송을 수행하기 위해 3-way handshake 라는 기법을 사용하여 두 애플리케이션의 연결을 성립시킨다. 3-way handshake는 말그대로 데이터 송/수신을 수행하는 애플리케이션끼리 인사를 3번 한 후에 연결을 완전히 성립시킨다는 뜻이다. 순서는 아래와 같다.

  1. A 앱에서 B에게 TCP 연결을 요청한다. (ACK = 0, SYN = 1, Seq number = x)

  2. B 앱에서 이슈가 없으면 A 앱에게 응답한다. (ACK = 1, SYN = 1, Seq number = y, Ack number = x + 1)

  3. A 앱이 응답을 받고 B앱에게 다시 응답한다. (ACK = 1, Ack Number = y + 1)

위 3가지 과정을 거치면 A 앱이 B앱에게 실제 데이터를 전송한다. 한 가지 유의할 점은 3-way handshake 과정에서는 상대방이 보낸 Seq번호 + 1 로 자신의 Ack 번호를 만들어내고, 실제 데이터를 주고받을 때는 상대방이 최근까지 보낸 바이트의 수를 Ack번호로 정한다는 것이다.

Wireshark로 tcp 세그먼트를 아무거나 1개 캡쳐해보았다. 송신 측 포트번는 51943이고 수신 측 포트번호는 443이다. ACK 플래그가 1인걸 보니 최초로 연결 성립을 요청하는 세그먼트는 아님을 알 수 있다.

ACK 번호가 1024인 것을 통해 상대방이 지금까지 1024바이트만큼의 데이터를 보내온 것을 예측할 수 있다.

Last updated