1일 1커밋🌱

5 분 소요

1. 트랜스포트 계층

트랜스포트 계층은 같은 호스트 내에서 프로세스(실행 중인 애플리케이션)을 구분하기 위해서 포트를 사용하는 계층이다. 여기서 포트는 라우터에 있는 포트(인터페이스)와는 다른 논리적인 개념이다. 포트는 2의 16승으로 0~65536까지 될 수 있다. 보통 IP 주소와 같이 표현하는데 IP 주소 뒤에 콜론으로 포트 번호를 붙인다.

포트번호는 0번부터 1023번까지는 잘 알려진 포트이며 1024번부터 49151번까지는 잘 알려지지 않은 포트가 있다.

트랜스포트 계층은 포트뿐만 아니라 TCP와 UDP를 사용해 신뢰성을 보장하는 데이터 전송(TCP)을 하거나 빠른 속도로 데이터를 전송(UDP)을 할 수 있다.

참고 : http://wiki.hash.kr/index.php/포트#.ED.8F.AC.ED.8A.B8_.EB.B2.88.ED.98.B8

2. TCP(Transmisson Control Protocol) 개요

TCP(Transmission Control Protocol)은 데이터의 신뢰성을 보장해주는 프로토콜이다. TCP는 통신을 시작하기 전에 3 way handshake로 커넥션을 만든다. 3 way handshake로 커넥션을 만들고 난 뒤 데이터 전송을 할 수 있다.

또한 TCP는 애플리케이션에서 전송하는 데이터를 세그멘테이션, 즉 분할해서 전송한다. 분할하는 첫번째 이유는 너무 큰 데이터가 분실되는 경우에 잃어버리는 데이터도 많기 때문이다. 데이터를 분할하면 일부 데이터가 분실되었더라도 그 부분만 다시 보내면 되기 때문에 효율적이다. 두번째 이유는 데이터링크 계층에서 보낼 수 있는 최대 크기가 정해져 있기 때문이다. 만약 이더넷 프레임의 기본 값을 사용한다면 최대 크기는 1500Byte이다. 이더넷 프레임의 최대 크기가 1500Byte이므로 TCP 헤더 20Byte와 IP 헤더 20Byte를 제외하면 1460Byte가 최대 크기이다.

데이터를 전송할 때는 해당 데이터의 번호를 나타내는 seq 번호와 다음 데이터의 번호(seq 번호 + 데이터 크기 + 1)를 나타내는 ack 번호를 이용해 데이터를 주고받는다.

커넥션을 끊을 때는 4 way handshake로 진행한다. TCP는 이렇게 커넥션 확립, 데이터 전송, 커넥션 끊기로 신뢰성 있는 데이터 전송을 하게된다.

3. TCP(헤더, 흐름 제어, 혼잡 제어)

애플리케이션 계층에서 전송한 데이터는 트랜스포트 계층으로 전달된다. 트랜스포트 계층에서는 이 데이터에 사용할 프로토콜의 헤더를 붙이는데 여기서는 TCP를 사용하므로 TCP 헤더가 붙는다. 그러면 이 데이터의 이름은 세그먼트가 된다.

network-transport-1

TCP 헤더는 다음과 같이 구성되어 있다.

  • Source Port : 16비트로 구성되어 있고 송신측의 포트를 나타내는 필드이다. 16비트로 구성되어 있기 때문에 최대 65,535 포트까지 사용가능하다.

  • Destination Port : 16비트로 구성되어 있고 수신측의 포트를 나타내는 필드이다. 16비트로 구성되어 있기 때문에 최대 65,535 포트까지 사용가능하다.

  • Sequence Number : 32비트로 구성되어 있고 이 데이터의 일련번호를 나타내는 필드이다. Sequence Number가 있어서 데이터의 순서가 뒤죽박죽으로 도착해도 원상태로 복원할 수 있고 누락된 데이터도 알 수 있다. Sequence Number는 처음 보낼 때 난수로 결정되고 그 다음부터는 현재 Sequence Number와 데이터의 크기에 1을 더한다.
  • Acknowledgement Number : 자신이 다음에 받아야 할 상대의 Sequence Number가 된다. Sequence Number와 Acknowledgement Number를 통해 신뢰성을 보장한다.
  • Data Offset : 현재 TCP 데이터가 TCP 세그먼트의 가장 앞에서 얼마나 떨어져 있는지를 4Byte 단위로 나타내는 필드이다. 즉 TCP 헤더의 크기를 나타낸다. TCP 헤더의 기본값은 20Byte이므로 Data Offset의 기본값은 5이다.
  • Reserved : 3비트로 구성되어 있고 앞으로 필요할 때를 대비해 남겨둔 필드로 현재는 사용되지 않는다. 원래는 더 컸었지만 Control Flag에 여러 필드가 등장해서 지금은 3비트까지 작아진 상황이다.
  • Control Flag : Control Flag의 각 필드는 사용 용도에 따라서 다르게 설정된다.
    • 첫번째 필드(NS, Nonce Sum)는 악의적인 데이터인 것을 은폐하는 걸 방지하기 위한 필드로 아직 실험단계에 있다.
    • 두번째 필드(CWR, Congestion Window Reduced)는 혼잡 제어를 할 때 사용되는 필드이다.
    • 세번째 필드(ECE, ENC-Echo)는 Congestion Window Reduced와 마찬가지로 혼잡 제어를 할 때 사용되는 필드이다.
    • 네번째 필드(URG, Urgent Flag)는 긴급하게 처리해야 하는 데이터를 나타낼 때 사용하는 필드지만 많이 사용되지는 않는다.
    • 다섯번째 필드(ACK, Acknowledgement Flag)는 응답할 때 사용된다. 이 비트가 1인 경우 데이터를 잘 받았다는 뜻이다.
    • 여섯번째 필드(PSH, Pugh Flag)는 이 비트가 1이면 상위 애플리케이션으로 최대한 빨리 전달하라는 의미고 0이면 버퍼링하는 것을 허용한다는 의미이다.
    • 일곱번째 필드(RST, Reset Flag)는 이 비트가 1이면 이미 연결된 커넥션을 강제로 끊는다는 것을 의미한다.
    • 여덟번째 필드(SYN, Synchronization Flag)는 커넥션을 생성할 때 사용된다.
    • 아홉번째 필드(FIN, Fin Flag)는 1로 설정되어 있다면 연결을 끊고 싶다는 의미이다. 보통 더 이상 보낼 데이터가 없어 통신을 종료할 때 사용된다.
  • Window Size : 16비트로 구성되어 있으며 TCP의 흐름 제어인 슬라이딩 윈도우를 사용할 때 사용된다.
  • Checksum : 16비트로 구성되어 있으며 데이터의 변조나 에러를 알아내기 위한 용도로 사용된다.
  • Urgent Pointer : 16비트로 구성되어 있으며 Control Flag의 Urgent Flag가 1인 경우에 사용된다. 이 경우 상위 애플리케이션에서 이 포인터가 가리키고 있는 데이터를 우선 처리할 수도 있고 하지 않을 수도 있다.
  • Options : TCP의 기능을 확장할 때 사용하는데 크기가 정해져있지 않고 가변적이다. 이때 Data Offset 필드를 이용해 헤더의 크기를 계산할 수 있다. Options 필드의 크기는 최대 40바이트이다.

TCP는 이처럼 Sequence Number와 Acknowledgement Number를 이용해 어떤 데이터를 받았고 받지 않았는지를 알 수 있기 때문에 데이터 순서가 바뀌거나 누락되어도 원래 데이터로 복원할 수 있다.

그러나 데이터를 한 번 보내고 그 데이터를 받았다는 응답을 받아야만 다음 데이터를 전송하는 방식은 통신 속도가 떨어진다는 단점이 있다. 이 문제를 해결하기 위해 흐름 제어를 통해 여러 데이터를 한 번에 보내고 한 번에 응답을 보내 데이터의 흐름을 제어한다. 전송할 데이터들이 있을 때 Window 라는 것을 만들어서 한 번에 보낼 영역을 지정한다. 한 번에 전송할 데이터들의 크기를 Window Size라고 한다.

Window 크기가 커질수록 한 번에 더 많은 데이터를 보내기 때문에 통신속도가 빨라지는 효과를 볼 수 있지만 수신측의 네트워크가 혼잡할 때 송신측에서 너무 많은 데이터를 보내면 문제가 생길 수 있다. 네트워크가 혼잡해지는 것을 막기 위해 혼잡 제어를 하게 된다. 송신측에서 처음 데이터를 보낼 때 윈도우의 크기를 최대한 작게 설정해 한 번에 하나의 데이터만 보내는데 이를 Slow Start라고 한다. 수신측에서 데이터를 잘 받았다면 Window 크기를 2배 늘려서 전송하고 다음에는 4배 늘려 점차적으로 많은 데이터를 전송한다. 그러다가 수신측에서 너무 많은 데이터를 받았다고 전달하면 다시 Window 크기를 줄이는 방법으로 적절한 데이터를 전송한다.

TCP를 정리해보면 TCP는 신뢰성 있는 전송을 보장해야 하기 때문에 데이터에 번호를 붙이고 수신측에서 어떤 데이터까지 받았는지 응답한다. 하지만 매번 응답을 기다렸다가 전송하면 속도가 너무 느리므로 흐름 제어를 통해 여러 데이터를 한 번에 보낸다. 만약 수신측에서 감당이 안될 정도로 한번에 많이 보내면 네트워크가 혼잡해지므로 혼잡 제어를 통해 적절한 양으로 전송한다.

참고 : https://networklessons.com/cisco/ccie-routing-switching-written/tcp-header

4. UDP

UDP는 TCP와 비교하면 단순하고 자유로운 프로토콜이다. TCP는 데이터가 분실되거나 손상되면 재전송을 보장하고 순서가 바뀐 데이터를 재조립하지만 UDP는 그렇지 않다. UDP는 TCP처럼 3 way handshake로 커넥션을 확립하지 않으며 일방적으로 데이터를 보낸다. 만약 데이터가 분실되거나 재전송을 원하는 경우는 프로그래머가 직접 애플리케이션 계층에서 요청해야 한다. UDP는 신뢰성을 보장하는 여러 절차를 생략하기 때문에 고속으로 처리하는 용도에 적합하다. 동영상이나 음성, 게임같은 경우에는 데이터가 조금 손실되더라도 끊기지 않고 빠른 응답이 중요하기 때문에 UDP를 많이 사용한다.

network-transport-2

UDP 헤더는 TCP 헤더와 비교하면 굉장히 단순한다.

  • Source Port : 16비트로 구성되어 있으며 송신측의 포트번호가 저장된다. 2^16이므로 0부터 65535까지 숫자가 올 수 있다.
  • Destination Port : 16비트로 구성되어 있으며 수신측의 포트번호가 저장된다. 2^16이므로 0부터 65535까지 숫자가 올 수 있다.
  • UDP Length : 16비트로 구성되어 있으며 UDP 헤더와 데이터의 크기를 합친 값이 저장된다.
  • Checksum : 16비트로 구성되어 있으며 현재 UDP 헤더와 데이터가 변조되었는지 체크하기 위한 용도로 사용된다.

5. TCP vs UDP

TCP는 신뢰성을 보장하므로 신뢰성이 중요한 애플리케이션을 만든다면 TCP를 선택하는 것이 좋은 선택이 될 수 있다. UDP는 신뢰성보다는 속도가 중요한 곳에서 쓰는 것이 좋은 선택이 될 수 있지만 프로그래머의 역량에 따라서 신뢰성까지 보장할 수 있다.

오늘날 쓰이는 HTTP는 버전 2로 TCP를 이용한 기술이지만 앞으로 쓰게 될 버전 3는 UDP 기반으로 만들어진 QUIC를 사용한다.

따라서 신뢰성이 중요한 애플리케이션에서 사용자가 신뢰성까지 구현하기 힘들다면 TCP를 이용하는 것이 좋고, UDP를 이용해 잘 구현한다면 더 빠른 속도로 신뢰성까지 보장하며 통신할 수 있다. 또는 UDP를 이용해 구현해 놓은 라이브러리를 사용하는 것도 방법이 될 수 있다.

참고

카테고리:

업데이트:

댓글남기기