> For the complete documentation index, see [llms.txt](https://jmxx219.gitbook.io/cs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://jmxx219.gitbook.io/cs/network/tcp-udp.md).

# TCP와 UDP

> TCP와 UDP는 [OSI 7계층](/cs/network/osi-7.md) 중 `전송 계층`에서 사용되는 프로토콜로, 전송 계층은 송싱자와 수신자를 연결하는 통신 서비스를 제공하는 계층임\
> 즉, 데이터의 전달을 담당하며 패킷의 오류를 검사하고 재전송 요구 등의 제어를 담당함

<br>

### 배경(TCP/IP 프로토콜의 패킷 교환 방식)

> 전 세계를 연결하는 복잡한 네트워크인 인터넷에서는 엄청난 양의 데이터를 보다 효율적이고 안정적으로 전송하기 위해 `패킷 교환 방식`으로 데이터를 전송함\
> 이때 TCP와 IP는 패킷 교환 방식에 따라 데이터를 전송할 때 사용하는 프로토콜임

![](https://oopy.lazyrockets.com/api/v2/notion/image?src=https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2Fd9f5066b-a972-47aa-8705-942ddcba85b7%2FUntitled.png\&blockId=b75ed99a-7202-449b-bf0e-ab03cff27aff)

* 네트워크에서 데이터 전송 방식
  * 송신지 호스트에서 수신지 호스트로 데이터가 전송될 때, 데이터가 중간 노드들을 경유하게 되는데 어떤 링크로 이동할지 선택하고 이동함
  * 이때 노드와 노드 사이의 이동 과정에서 어떤 경로를 선택해 데이터를 전송하는 방법은 크게 2가지가 존재함
    * 회선 교환 방식
    * 패킷 교환 방식
* `회선 교환(Circuit Switching) 방식`
  * 통신하고자 하는 두 호스트가 데이터를 전송하기 전에 미리 데이터 이동 경로를 하나 설정해두는 방식
  * 미리 설정해둔 경로는 두 호스트만을 위한 전용 경로가 되며, 이 경로를 통해 통신의 처음부터 끝까지 모든 데이터가 이동함
  * 과거에는 회선 교환 방식을 사용하였는데, 미리 이동 경로를 결정하기 때문에 연결된 선 하나가 잘려나가면 그대로 통신이 끊어졌음
    * 하나의 회선에 전적으로 의존하는 연결이라는 큰 단점을 보완하기 위해 나온 방식이 패킷 교환 방식!
* `패킷 교환(Packet Switching) 방식`
  * 미리 고정된 이동 경로를 설정하지 않는 대신 패킷이라는 작은 단위로 나누어 전송하는 방식
  * 데이터는 네트워크를 통해 전송되기 전에 패킷이라는 작은 조각으로 나누고, 각 패킷에는 고유 번호가 있어서 네트워크를 거쳐 최종 수신지에 전송되었을 때 원래의 데이터로 재결함됨
    * 각각의 패킷은 전송 당시 가장 효율적인 경로를 각자 설정하여 최종 수신지까지 이동함
    * 패킷을 수신한 중간 노드가 패킷의 수신지 호스트를 확인하고 수신지 호스트까지 가는 다양한 경로 중 가장 좋다고 판단되는 경로를 따라 다음 중간 노드로 패킷을 전송하는 기능([라우팅](https://jmxx219.gitbook.io/cs/network/pages/XvEbrb1J4KbB9viKSygE#라우팅))을 수행함
  * 현재는 데이터를 패킷이라는 작은 단위로 분할하여 라우터를 통해 전송하는 것이 기본이 됨
  * 패킷 교환 방식의 유형
    * 가상 회선 패킷 교환(연결 지향 패킷 교환) ➜ `TCP`
    * 데이터그램 패킷 교환(비 연결형 패킷 교환) ➜ `UDP`

<br>

## TCP(Transmission Control Protocol)

* 개념
  * 전송 제어 프로토콜로, 인터넷상에서 데이터를 메세지의 형태로 보내기 위해 IP와 함께 사용하는 프로토콜
  * 일반적으로 TCP와 IP를 함께 사용하여 `TCP/IP 프로토콜`로 불리기도 함
    * IP는 인터넷 망 속에서 IP 주소와 패킷과 같은 규칙을 통해 클라이언트와 서버 간에 통신할 수 있게 하는 것
    * TCP는 IP 규칙으로 통신하기에 부족하거나 불안정한 단점들을 보완하기 위해 패킷 전송을 제어하여 신뢰성을 보장하는 것
  * 네트워크에 연결된 컴퓨터에서 실행되는 프로그램 간에 데이터를 세그먼트(Segment) 단위로 쪼개어 `신뢰성(안정적으로, 순서대로, 에러 없이)`을 기반한 통신을 제공함
* 특징
  * 연결형 서비스로 가상 회선 패킷 교환 방식을 제공함
    * 가상 회선 방식: 발신지와 수신지를 연결하여 패킷을 전송하기 위한 논리적 경로를 배정한다는 의미
    * [3-way handshaking 과정](/cs/network/3-way-handshake.md)을 통해 연결을 설정하고, [4-way handshaking 과정](/cs/network/4-way-handshake.md)을 통해 연결을 해제함
      * 3-way handshaking 과정은 발신지와 수신지 사이에 논리적인 접속(세션)을 성립하는 과정을 의미함
  * 전송 제어
    * `흐름 제어(Flow control)`: 데이터 처리 속도를 조절하여 수신자의 버퍼 오버플로우를 방지
    * `오류 제어(Error Control)`: 데이터가 유실되거나 잘못된 데이터가 수신되었을 경우 대처하는 방법
    * `혼잡 제어(Congestion control)`: 네트워크 내의 패킷 수가 과도하게 증가하지 않도록 방지
  * 높은 신뢰성을 보장함
    * 따라서 UDP 보다 속도가 느림
  * 전이중(Full-Duplex), 점대점(Point to Point) 방식
    * 전이중: 전송이 양방향으로 동시에 일어날 수 있음
    * 점대점: 각 연결이 정확히 2개의 종단점을 가지고 있음
* 연속성 보다는 신뢰성 있는 전송이 필요할 때 사용함
  * ex) 파일 전송

<br>

### TCP의 헤더

> TCP의 헤더 크기는 최저 20바이트로, 송수신지의 번호 뿐만 아니라 데이터 검증 및 순서 확인을 위한 정보등을 포함하고 있음

![TCP 헤더](https://github.com/reddevilmidzy/CS-Study/assets/78539407/8e0823c5-4f2f-436b-a055-ea63d0902792)

| 종류                                   | 설명                                                                                                                            |
| ------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------- |
| Source/Destination Port(송신/수신 포트 번호) | 세그먼트의 출발지와 목적지를 나타내는 필드로, 애플리케이션 식별을 위한 포트 번호가 필요함(IP 주소는 네트워크 계층에 있는 IP 헤더에 담김)                                              |
| Sequence Number                      | TCP 세그먼트를 올바른 순서로 정렬하기 위해 사용되는 필드로, 송신 측 단말은 애플리케이션에서 받은 데이터의 각 바이트에 대해 **초기 시퀀스 번호**(ISN, Initial Sequence Number)에서 연번을 부여함 |
| Acknowledgement Number               | 확인 응답 번호(ACK)는 다음 수신을 기대하는 데이터의 시퀀스 번호를 의미함                                                                                   |
| Data Offset(Header Length)           | TCP 세그먼트가 시작되는 위치를 기준으로 헤더의 길이를 나타내는 필드                                                                                       |
| Code Bit(Flags)                      | 컨트롤 비트는 커넥션의 상태를 나타내는 필드                                                                                                      |
| Window                               | 한 번에 전송할 수 있는 데이터의 양을 의미하는 값으로, 단위는 바이트                                                                                       |
| Checksum                             | 데이터 송신 중에 발생될 수 있는 오류를 검출하기 위한 값                                                                                              |
| Urgent Pointer                       | 긴급 포인터는 컨트롤 비트의 URG 플래그가 `1`로 설정됐을때 유효한 필드로, 긴급 데이터가 있을 때 긴급 데이터를 나타내는 가장 마지막 바이트의 시퀀스 번호가 설정됨                                |
| Options                              | TCP에 관련된 확장 기능을 알리기 위해 사용함                                                                                                    |

* Checksum
  * 헤더 및 데이터를 16비트 단위로 분할하여 비트 합을 구한 뒤, 이에 대한 1의 보수를 취함으로써 계산함
  * 만약 carry(자리 수가 하나 올라간 부분)가 발생한다면 wrap around(넘친 부분만 떼어내어 다시 더해줌)를 적용함
* Code Bit(Flags)

<br>

## TCP의 전송 제어 기법

> `흐름 제어`, `오류 제어`, `혼잡 제어`

<br>

#### 데이터 전송 과정

1. 응용 계층(Application Layer)에서 데이터를 전송할 때, 송신자(sender)의 애플리케이션(Application)은 소켓(Socket)에 데이터를 씀
2. 이 데이터는 전송 계층(Transport Layer)으로 전달되어 세그먼트(Segment)라는 작은 단위로 나누어짐
3. 전송 계층은 이 세그먼트를 네트워크 계층(Network Layer)으로 넘겨줌
4. 전송된 데이터는 수신자(receiver)쪽으로 전달되어 수신 버퍼(Receive Buffer)에 저장됨
   * 이때 수신자 쪽에서는 수신 버퍼의 용량을 넘치지 않게 조절해야 함
   * `흐름 제어 (Flow Control)` 과정
     * 수신자 쪽에서 자신의 수신 버퍼의 남은 용량을 송신자에게 알려주는데, 이를 수신 윈도우(Receive Window)라고 함
     * 송신자는 수신자의 수신 윈도우를 확인하여 수신자의 수신 버퍼 용량을 초과하지 않도록 데이터를 전송함
     * 이를 통해 데이터 전송 중에 수신 버퍼가 넘치는 현상을 방지하면서, 안정적인 데이터 전송을 보장함
5. 수신 측 애플리케이션이 준비가 되면 수신 버퍼에 있는 내용을 읽기 시작함

<br>

### 1. 흐름 제어 (Flow Control)

> 데이터 전송 중에 발생하는 수신 버퍼의 오버플로우를 방지하면서, 안정적인 데이터 전송을 위해 중요한 기술

* 수신측이 송신측보다 데이터 처리 속도가 빠르면 문제 없지만, 송신측의 속도가 빠를 경우 문제가 발생함
  * 수신측에서 제한된 저장 용량을 초과한 이후에 도착하는 데이터는 손실될 수 있으며, 만약 손실된다면 불필요한 응답과 데이터 전송이 발생함
* 흐름 제어는 이러한 송신측과 수신측의 데이터 처리 속도 차이를 해결하기 위한 기법으로, 수신자가 패킷을 지나치게 많이 받지 않도록 조절하는 것
  * 기본 개념은 수신자가 송신자에게 현재 자신의 상태를 feedback한다는 점

<br>

#### 흐름 제어 기법

* `Stop and Wait`
  * 매번 전송한 패킷에 대해 확인 응답(ACK)을 받아야만 그 다음 패킷을 전송하는 방법

    ![Stop and Wait](https://github.com/jmxx219/CS-Study/assets/52346113/b103894a-65bc-4d3f-bd64-d44f7c38e1e5)
  * 패킷을 하나씩 보내기 때문에 비효율적인 방법
* `Sliding Window`
  * 수신측에서 설정한 윈도우 크기만큼 송신측에서 확인 응답없이 세그먼트를 전송할 수 있게 하여 데이터 흐름을 동적으로 조절하는 제어 기법
  * 최초의 윈도우 크기(수신 측이 한 번에 처리할 수 있는 데이터의 양)는 3-way handshake 과정에서 수신 측의 윈도우 크기가 송신 측에 전달됨
    * 이후 수신 측의 버퍼에 남아있는 공간에 따라 변함
    * 수신 측에서 송신 측으로 확인 응답(ACK)를 보낼 때 TCP 헤더(window size)에 담아서 보냄

<br>

### 2. 오류 제어(Error Control)

* TCP 통신 중에 오류(데이터 유실 or 잘못된 데이터 수신)가 발생하면 해당 데이터를 재전송함
  * 재전송 기반 오류 제어 ARQ(Automatic Repeat Request)를 사용함
* 오류를 알 수 있는 방법
  * 송신 측이 ACK를 받지 못함(송신 측이 보낸 데이터가 유실되거나 수신 측이 보낸 ACK 데이터가 유실된 경우)
  * 중복된 ACK는 받는 경우
  * 수신 측이 NACK(부정 응답)을 보내는 경우

<br>

#### 오류 제어 기법

![](https://github.com/jmxx219/CS-Study/assets/52346113/8cfefb38-6811-4ae7-b652-46415199765f)

* `Go Back N`
  * 어느 데이터로부터 오류가 발생했는지 파악하여, 오류가 발생한 지점부터 다시 순서대로 재전송하는 방식
  * 성공적으로 전송된 데이터까지 재전송하기 때문에 비효율적
* `Selective Repeat ARQ(선택적 재전송)`
  * 에러가 난 데이터만 재전송하고, 그 전에 받았던 순서가 잘못된 데이터 버퍼를 재정렬하여 제어함
  * 수신 측 버퍼의 데이터가 순차적이지 않기 때문에 정렬의 과정이 추가로 필요하고 별도의 버퍼가 필요함

<br>

### 3. 혼잡 제어 (Congestion Control)

* 네트워크의 혼잡을 피하기 위해 송신 측에서 보내는 데이터의 전송 속도를 강제로 줄이는 제어 기법
  * 송신측의 데이터는 지역망이나 인터넷으로 연결된 대형 네트워크를 통해 전달되는데, 만약 한 라우터에 데이터가 몰리게 되면 자신에게 온 데이터를 처리할 수 없게 됨
  * 이러한 경우 호스트들은 재전송하게 되고, 결국 혼잡만 가중시켜 오버플로우나 데이터 손실이 발생함
* 송신측의 데이터 전달과 네트워크의 데이터 처리 속도 차이를 해결하기 위한 기법
  * 흐름 제어가 송신측과 수신측 사이의 전송 속도를 다루는데 반해, 혼잡제어는 호스트와 라우터를 포함한 보다 넓은 관점에서 전송 문제를 다루게 됨

<br>

#### 혼잡 제어 기법

![](https://github.com/reddevilmidzy/CS-Study/assets/78539407/565fc390-c3f7-4de7-a314-0a34ae304daa)

* `AIMD(Additive Increase / Multiplicative Decrease)`
  * 처음에 패킷을 하나씩 보내고 이것이 문제없이 도착하면 window 크기(단위 시간 내에 보내는 패킷의 수)를 1씩 증가시켜가며 전송하는 방법
  * 패킷 전송에 실패하거나 일정 시간을 넘으면 패킷의 보내는 속도를 절반으로 줄임
  * 윈도우 크기를 너무 조금씩 늘리기 때문에 네트워크의 모든 대역을 활용하여 제대로 된 속도로 통신하기까지 시간이 오래 걸림(단점)
* `Slow Start(느린 시작)`
  * AIMD에 반해 지수 함수 꼴로 증가시켜 윈도우 크기를 더 빠르게 증가시키다가 혼잡이 감지되면 윈도우 크기를 1로 줄이는 방식
  * 보낸 데이터의 ACK가 도착할 때마다 윈도우 크기를 증가시키기 때문에 처음에는 윈도우 크기가 조금 느리게 증가할지라도, 시간이 가면 갈수록 윈도우 크기가 점점 빠르게 증가함
* `Fast Retransmit(빠른 재전송)`
  * 패킷을 받는 수신자 입장에서는 세그먼트로 분할된 내용들이 순서대로 도착하지 않는 경우가 생길 수 있음
    * 이런 상황이 발생했을 때, 수신 측에서는 순서대로 잘 도착한 마지막 패킷의 다음 순번을 ACK 패킷에 실어서 보냄
    * 그리고 이런 중복 ACK를 3개 받으면 재전송이 이루어짐
  * 송신 측은 자신이 설정한 타임 아웃 시간이 지나지 않았어도 바로 해당 패킷을 재전송할 수 있기 때문에 보다 빠른 재전송률을 유지할 수 있음
* `Fast Recovery(빠른 회복)`
  * 혼잡한 상태가 되면 window size를 1로 줄이지 않고 반으로 줄이고 선형 증가시키는 방법
  * 혼잡 상황을 한 번 겪은 이후부터는 순수한 AIMD 방식으로 동작하게 됨

\ <br>

## UDP(User Datagram Protocol)

* 개념
  * 사용자 데이터그램 프로토콜로, 데이터를 데이터그램 단위로 처리하는 프로토콜
    * 데이터그램: 독립적인 관계를 지니는 패킷
  * 데이터를 서로 다른 경로로 독립적으로 처리함
* 특징
  * 비연결형 서비스로, 데이터그램 패킷 교환 방식을 제공함
    * 연결을 위해 할당하는 논리적인 경로가 없고, 각각의 패킷은 다른 경로로 전송되며 독립적인 관계를 지님
    * 따라서 데이터의 전송 순서가 바뀔 수 있음
  * 데이터의 수신 여부를 확인하지 않음
    * TCP의 3-way handshaking과 4-way handshaking과 같은 연결을 설정하고 해제하는 과정이 없음
  * 신뢰성이 낮음
    * 흐름 제어 또는 혼잡 제어 같은 기능이 없어서 제대로 전송되었는지, 오류가 없는지 확인할 수 없음
  * TCP 보다 속도가 빠르며 네트워크 부하가 적음
  * `1:1` & `1:N` & `N:N` 통신이 가능함
    * 브로드캐스트 및 멀티캐스트 기능을 통해 하나의 UDP 전송을 여러 수신자에게 한 번에 전송할 수 있음
* 신뢰성보다는 연속성 있는 전송이 필요할 때 사용함
  * ex) 실시간 서비스(streaming)

<br>

### UDP의 헤더

> UDP의 헤더는 TCP와 비교했을 때 훨씬 더 작은 크기의 헤더를 갖고 있음

![UDP 헤더](https://github.com/reddevilmidzy/CS-Study/assets/78539407/f59652c9-eda8-4d77-bf4a-ce0bde8bd611)

* Source/Destination Port
  * UDP Datagram Length
  * Checksum

<br>

### QUIC

* TCP와 비교했을 때 UDP 헤더 포멧은 거의 백지와 마찬가지로, `User Datagram`이라는 의미는 사용자가 정의해서 사용하라는 의미임
  * 즉, 여기에 원하는 기능을 얼마든지 얹으면 되고 서버와 클라이언트의 구현에 따라 그 퍼포먼스는 크게 달라질 수 있음
  * TCP 처럼 신뢰성 있는 전송을 하고싶으면 시퀀스 번호 등을 정의하여, 서버와 클라이언트 간에 패킷 유실에 대한 대처방법도 상호 정의한다면 UDP 기반의 신뢰성 있는 프로토콜을 만들 수 있음
  * 이러한 개념에서 나온 것이 `QUIC`임
* `QUIC(Quick UDP Internet Connections)` 프로토콜은 Google을 통해 개발이 진행되었고, 현재 모든 Google 관련 제품의 기본 프로토콜로 사용됨
  * UDP 보다 안전하고 TCP 보다 빠르다는 장점을 갖고 있음
  * TCP는 클라이언트와 서버 연결 과정에서 핸드셰이크를 사용하여 커넥션을 만든다음 통신함

    ![HTTP-request-over-TCP-@3x](https://github.com/reddevilmidzy/CS-Study/assets/78539407/35cba870-bb38-4022-a161-38e0549ab648)
  * 반면에 QUIC은 사전에 핸드셰이크를 완료할 필요 없이 연결 시작 시에 클라이언트가 바로 서버에 데이터를 보낼 수 있도록 함

    ![request-over-quic-0-RTT@3x](https://github.com/reddevilmidzy/CS-Study/assets/78539407/03f54ce1-3d2e-4141-9b5c-fd14a438d1ba)

\ <br>

### TCP와 UDP 비교

| 종류             | UDP           | TCP         |
| -------------- | ------------- | ----------- |
| IP 헤더의 프로토콜 번호 | 17            | 6           |
| 연결 방식          | 비 연결지향형 프로토콜  | 연결지향형 프로토콜  |
| 패킷             | 데이터그램 TCP 패킷  | 세그먼트 UDP 패킷 |
| 패킷 교환 방식       | 데이터그램 패킷교환    | 가상회선 패킷교환   |
| 신뢰성            | 낮음            | 높음          |
| 즉시성(실시간성)      | 빠름            | 느림          |
| 순서 보장          | X             | O           |
| 통신 방식          | 1:1, 1:N, N:N | 1:1         |

\ <br>

### ref

* [TCP/IP (흐름제어/혼잡제어)](https://gyoogle.dev/blog/computer-science/network/%ED%9D%90%EB%A6%84%EC%A0%9C%EC%96%B4%20&%20%ED%98%BC%EC%9E%A1%EC%A0%9C%EC%96%B4.html)
* [QUIC과 HTTP/3 - 1. UDP기반 전송 프로토콜의 대두](https://www.saturnsoft.net/network/2019/03/21/quic-http3-1/)
* [QUIC 0-RTT 재시작으로 더 빨리 연결하기](https://blog.cloudflare.com/ko-kr/even-faster-connection-establishment-with-quic-0-rtt-resumption-ko-kr/)
* [TCP/IP 프로토콜과 패킷 교환 방식](https://tscofet.oopy.io/1888076d-f49c-464d-9499-6bcb63301787)
* [TCP 의 흐름 제어 / 오류 제어 / 혼잡 제어](https://benlee73.tistory.com/186)
