이 영역을 누르면 첫 페이지로 이동
천천히 꾸준히 조용히 블로그의 첫 페이지로 이동

천천히 꾸준히 조용히

페이지 맨 위로 올라가기

천천히 꾸준히 조용히

천천히 꾸준히 조용히.. i3months 블로그

[Computer Network] Transmission Control Protocol

  • 2025.10.15 23:35
  • Computer Science/Computer Network
반응형

 

 

 

다시 한 번 말하지만 전송계층은 두 프로세스간 소켓을 연결한다.

 

TCP는 이 계층에서 Reliability, Flow Control, Congestion Control, Connection Management를 수행한다.

UDP는 데이터만 빠르게 전송할 뿐 TCP 처럼 연결 설정, 재전송 등은 수행하지 않는다.

 

프로세스는 소켓을 통해 데이터를 주고받지 네트워크와 직접 통신하지는 않는다. TCP 소켓은 연결형, UDP 소켓은 비연결형이고.

 

Multiplexing

호스트 하나에는 여러 프로세스가 동시에 네트워크를 사용한다.

애플리케이션들은 걔내만의 소켓을 가지고 전송계층으로 데이터를 보내고, 전송계층은 소켓에서 온 데이터에 포트번호 등 적절한 식별자를 붙여서 구분 가능하도록 설정하고 네트워크로 보낸다. 

 

즉, 여러 개의 소켓을 사용하더라도 네트워크 계층은 하나만 사용한다.

 

Demultiplexing

수신한 데이터를 올바른 소켓에 전달해야 한다. 

송신 호스트에서 수신 호스트에 도착한 세그먼트는 전송계층으로 올라오고, 헤더에 있는 목적지 포트를 읽는다.

이제 어떤 소켓으로 가야 하는지 알았으니 그 소켓에게 데이터를 전송한다.

 

역시나 하나의 네트워크 계층을 사용하지만 여러 소켓을 처리한다.

 

 

TCP건 UDP건 Multiplexing, Demultiplexing 개념 자체는 동일하게 존재한다.

그런데 세부 동작 방식은 좀 다르다.

 

UDP는 그냥 하나만 한다. 포트번호로 Datagram을 애플리케이션으로 전달하는 것..

누구처럼 handshake, Flow Control, Congestion Control 그런거 안함.. 서버가 준비되든말든 지가 할말만 한다.

 

패킷 손실이 좀 있어도 괜찮고, 속도가 중요한 응용에서 사용된다. 게임, WebRTC, 화상회의 등..

 

 

 

헤더는 전송 제어용이고 실제 전송할 메세지는 Application Data 부분에 저장한다.

 

Source Port - 송신 측의 포트번호 

Destination Port - 수신 측의 포트번호

Length - 헤더 + 데이터의 전체 길이

 

전송만 하긴 한다 그럼에도 Checksum 은 쓰는데..

오류 검출용으로 오류 있으면 패킷 폐기하고 재전송은 안한다.

 

 

 

 

 

세그먼트를 16비트로 나누기 - 16비트 단위로 모두 더함 - 1의보수 - 체크섬필드에 넣음 

그냥 너무 단순함. 당연히 100% 오류 검출은 불가능하다.

 

TCP 에서는 당연이 이렇게 안한다. 패킷 손실 감지, 재전송 등 각잡고 신뢰성 보장하는 프로토콜이 TCP이다.

Stop-and-Wait / Go-Back-N / Selective-Repeat 등 여러 알고리즘의 장점을 섞은 방식으로 신뢰성을 보장함.

 

 

 

 


 

 

 

 

 

TCP는 1:1 통신이다. 멀티캐스트나 브로드캐스트는 지원하지 않고 송신 소켓 : 수신 소켓 쌍으로 정의된다.

MSS = MTU(1500) - IP헤더(20) - TCP헤더(20) - Maximum Segment Size

보통 1460바이트정도를 한 번에 보낼 수 있다.

 

SYN - (SYN + ACK) - ACK 

클라이언트의 요청 

서버의 수락 + 응답

클라이언트의 확인 

 

3-Way-Handshake는 위와 같은 과정으로 이루어진다.

이 과정으로 양쪽 모두 시퀀스 번호를 동기화하고, 연결 종료 후에는 4-Way-Handshake로 연결을 끊어버린다.

누구와 다르게 서로가 데이터를 주고받을 준비가 되었음을 확인하기 위해 데이터 전송 전에 Handshake로 연결을 설정한다.

 

데이터가 손실되거나 중복되더라도 순서대로 정확히 전달됨을 보장한다.

전송 단위는 세그먼트인데 응용 프로그램에서는 연속된 바이트 스트림으로 보낸다.

네트워크에서는 세그먼트 단위, 수신 측에서는 그 세그먼트를 시퀀스 번호로 재조립해 바이트 스트림으로 본다는 것.

 

수신 측 버퍼가 넘치지 않도록 송신 측은 수신 측이 보낸 rwnd 값을 참조해 보낼 수 있는 데이터의 양을 제한하고,

네트워크 전체가 과부하되지 않도록 송신 속도를 조절한다.

 

 

 

 

 

 

헤더에는 앞서 말한 전송제어, 오류검출, 흐름제어에 필요한 정보를 담아둔다. (32bit)

 

Source Port / Dest Port - 송신자와 수신자의 포트번호를 의미한다. 프로세스가 통신을 위해 필수 

Sequence Number - 이 세그먼트가 데이터 스트림에서 몇 번째 바이트부터 시작하는지를 나타낸다. 조립에 필수 

ACK - 수신자가 송신자에게 다음에 받고 싶은 바이트 번호를 알려준다. 즉, 그 전까진 잘 받았다는 것 

Control Flags - 긴급 데이터 존재, ACK 번호 유효, 연결 종료, 연결 시작 등 여러 의미를 가진다. 

Receive Window - 수신 측이 송신 측에게 지금 내가 받을 수 있는 버퍼 크기를 알려준다. 흐름 제어에 필수 

Checksum - TCP 헤더와 데이터 전체에 대해 계산된 인터넷 체크섬으로 데이터 손상 여부를 확인한다.

Application Data - 헤더 뒤에 실제 응용프로그램의 데이터를 붙인다.

 

 

신뢰성 보장을 위해 패킷 손실 시 재전송 해야 하는데.

너무 빠르면 중복, 너무 늦으면 속도가 느려진다.

 

TCP는 RTT를 기반으로 Timeout을 자동으로 계산한다. - RTT는 데이터 세그먼트를 보낸 순간부터 ACK를 받기까지의 시간.

 

그리디하게 최근 값 하나만 보고 Timeout 정하면 당연히 안된다. 매번 데이터를 보낼 때 마다 RTT를 직접 측정하고, 평균화 + 변동 보정을 넣어서 제대로 측정한다.

이 때 Exponential Weighted Moving Average를 사용하고, RTT Derivation도 함께 계산한다.

 

$$
\begin{align*}
\text{EstimatedRTT} &= (1 - \alpha) \times \text{EstimatedRTT} + \alpha \times \text{SampleRTT} \\
\text{DevRTT} &= (1 - \beta) \times \text{DevRTT} + \beta \times |\text{SampleRTT} - \text{EstimatedRTT}| \\
\text{TimeoutInterval} &= \text{EstimatedRTT} + 4 \times \text{DevRTT}
\end{align*}
$$

 

EstimatedRTT 의 기본 a 값은 0.125

DevRTT의 기본 B 값은 0.25

TimeoutInterval의 재전송 타이머는 여유계수 4를 설정한다.

 

 

아직 ACK를 받지 못한 가장 오래된 세그먼트에 대해 타이머를 걸어주자.

타임아웃 발생 시 손실로 판단하고 해당 세그먼트를 재전송하고 타이머를 재시작한다.

 

ACK를 수신하면 확인된 세그먼트를 표시하고 타이머를 조정한다. 

즉, ACK 도착 시 이 ACK가 아직 확인되지 않은 세그먼트를 포함하는지를 확인한다.

 

수신 측은 데이터를 받았다고 바로 ACK를 보내지 않는다. 최대 500ms 까지 다음 세그먼트를 기다리고, 하나 더 오면 같이 보낸다.

ACK를 보내는 것 자체도 오버헤드가 있다. 가능하면 한 번에 많은 세그먼트를 처리하는게 합리적이다.

애초에 TCP는 Stop-and-Wait 처럼 한 번에 하나만 보내지 않고, 파이프라인 방식으로 여러 세그먼트를 동시에 전송한다.

 

TCP의 타임아웃 시간은 상당히 길다. 패킷 하나를 잃어버렸다고 타임아웃까지 기다리면 성능이 떨어짐.

 

송신자는 여러 세그먼트를 Pipelining으로 보내는데, 1 2 3 4 5 중에서 2만 유실됐다고 하자.

이러면 수신자는 3 4 5를 받을 때 마다 ACK 2로 2를 못 받았다는 신호를 보낸다.

송신자 입장에서는 같은 ACK를 연속으로 여러 번 받게 됨.

 

즉, out-of-order 세그먼트가 도착하면 Duplicate ACK로 다음 기대 바이트 번호를 보낸다.

 

송신자는 데이터를 빠르게 보내는데, 수신자는 데이터를 느리게 처리하면 수신자의 버퍼에서 오버플로우가 발생한다.

그러니, 수신자는 송신자에게 여유 공간을 함께 보낸다. (Receive Window)

RcvWindow = RcvBuffer - [LastByteReceived - LastByteRead]

 

 

 

 

 

3-way-handshake로 연결하는 작업과 4-way로 연결을 종료하는 과정은 데통때 했으니 간단하게 참고만 하기. 

 

ESTABLISHED - 서로 연결되어 데이터를 주고받음 

TIME_WAIT - 연결을 끊은 쪽에 남아 미아 패킷을 위해 잠시 기다림

CLOSE_WAIT - 상대는 나갔는데 서버가 문을 닫지 않음 

 

CLOSE_WAIT 상태에서 벗어나려면 응용 프로그램이 명시적으로 close 함수를 호출해 줘야 함.

호출 안하면 좀비프로세스가 되어 서버가 죽음 

 

 

 

 

 

 

공부하기 가장 좋은 방법은 와이어샤크로 패킷 캡쳐해서 확인하는거.. 

 

반응형
저작자표시 (새창열림)

'Computer Science > Computer Network' 카테고리의 다른 글

[Computer Network] Router  (0) 2025.12.13
[Computer Network] Congestion Control  (0) 2025.11.02
[Computer Network] Transport Layer Security  (0) 2025.10.14
[Computer Network] Domain Name System  (0) 2025.10.14
[Computer Network] Cookie && Cache  (2) 2025.10.14

댓글

이 글 공유하기

  • 구독하기

    구독하기

  • 카카오톡

    카카오톡

  • 라인

    라인

  • 트위터

    트위터

  • Facebook

    Facebook

  • 카카오스토리

    카카오스토리

  • 밴드

    밴드

  • 네이버 블로그

    네이버 블로그

  • Pocket

    Pocket

  • Evernote

    Evernote

다른 글

  • [Computer Network] Router

    [Computer Network] Router

    2025.12.13
  • [Computer Network] Congestion Control

    [Computer Network] Congestion Control

    2025.11.02
  • [Computer Network] Transport Layer Security

    [Computer Network] Transport Layer Security

    2025.10.14
  • [Computer Network] Domain Name System

    [Computer Network] Domain Name System

    2025.10.14
다른 글 더 둘러보기

정보

천천히 꾸준히 조용히 블로그의 첫 페이지로 이동

천천히 꾸준히 조용히

  • 천천히 꾸준히 조용히의 첫 페이지로 이동

검색

방문자

  • 전체 방문자
  • 오늘
  • 어제

카테고리

  • 분류 전체보기 (664)
    • Algorithm (205)
      • Data Structure (5)
      • Theory && Tip (33)
      • Baekjoon (166)
      • ALGOSPOT (1)
    • Spring (123)
      • Spring (28)
      • Spring Web MVC (20)
      • Spring Database (14)
      • Spring Boot (6)
      • Spring 3.1 (11)
      • Spring Batch (6)
      • Spring Security (16)
      • JPA (12)
      • Spring Data JPA (5)
      • QueryDSL (4)
      • eGovFramework (1)
    • Programming Language (74)
      • C (25)
      • C++ (12)
      • Java (19)
      • JavaScript (15)
      • Python (1)
      • PHP (2)
    • Computer Science (142)
      • Machine Learning (38)
      • Operating System (18)
      • Computer Network (28)
      • System Programming (22)
      • Universial Programming Lang.. (8)
      • Computer Architecture (4)
      • Compiler Design (11)
      • Computer Security (13)
    • Database (21)
      • Database (7)
      • MySQL (3)
      • Oracle (3)
      • Redis (5)
      • Elasticsearch (3)
    • DevOps (20)
      • Docker && Kubernetes (8)
      • Jenkins (4)
      • Amazon Web Service (8)
    • Mobile (28)
      • Android (21)
      • Flutter (7)
    • 💡 솔루션 (16)
    • 💬 기록 (10)
    • 📚 공부 (0)
    • 📝 낙서장 (25)

최근 글

나의 외부 링크

메뉴

  • 홈
반응형

정보

i3months의 천천히 꾸준히 조용히

천천히 꾸준히 조용히

i3months

블로그 구독하기

  • 구독하기
  • RSS 피드

티스토리

  • 티스토리 홈
  • 이 블로그 관리하기
  • 글쓰기
Powered by Tistory / Kakao. Copyright © i3months.

티스토리툴바