컴퓨터망 12) TCP

zh025700·2022년 7월 3일
1

컴퓨터네트워크

목록 보기
12/26
post-custom-banner

컴퓨터망

12. TCP

앞에서 얘기했듯, TCP/IP 프로토콜 transport 계층에 몇 가지 프로토콜이 지정되었다
이 장에서는 TCP에 대해 설명하겠다
TCP는 광범위한 서비스를 제공하는 핵심이며, 복잡한 프로토콜이다

TCP services

그림은 TCP와 TCP/IP의 다른 프로토콜에 대한 TCP의 관계를 보여준다
TCP는 애플리케이션 계층과 네트워크 계층 사이에 위치하며, 애플리케이션 프로그램과 네트워크 작업 사이의 중개자 역할을 한다

TCP

  • process to process communication
  • stream delivery service
    • datagram이 아니다
  • full duplex communication
    • 양방향 통신이 가능하다
  • multiplexing and demultiplexing
  • connection oriented service
    • connection less가 아니다
    • 연결이 필요하다
  • reliable service
    • 에러 관리
    • 혼잡 제어

UDP는 connectionless에다 unreliable했다
TCP는 UDP보다 더욱 많은 기능을 제공한다
위의 기능들에 대해 알아보자

Process to process communication

UDP와 마찬가지로 TCP는 포트 번호를 사용하여 프로세스 간 통신을 제공

  • 표는 TCP에서 사용하는 well known port 번호다

Stream delivery

  • UDP와 달리 TCP는 stream oriented 프로토콜이다

    • UDP

      • UDP에서 프로세스는 경계를 가진 메시지를 UDP로 보낸다
      • UDP는 각각의 메시지에 자체 헤더를 추가하여 IP로 전송한다
      • 프로세스의 각 메시지는 user datagram이라고 불리며, destinaion에서 하나의 IP 데이터그램이 된다
    • TCP

      • 송신 프로세스가 바이트 스트림으로 데이터를 전달할 수 있게 하고 수신 프로세스가 바이트 스트림으로 데이터를 얻을 수 있게 한다
      • TCP는 두 프로세스가 인터넷을 통해 바이트를 전달하는 가상의 "tube"에 의해 연결된 것처럼 보이는 환경을 만든다
      • 송신 프로세스는 바이트 스트림을 생성(쓰기)하고 수신 프로세스는 바이트 스트림을 소비(읽기)한다

Sending and Receiving buffers

  • 송신과 수신 프로세스가 같은 속도로 데이터를 사용하지 않기 때문에 TCP는 저장을 위한 버퍼가 필요하다
  • 송신 버퍼와 수신 버퍼의 두 가지 버퍼가 있으며, 각 방향마다 하나씩 있다
  • 버퍼를 구현하는 한 가지 방법은 그림과 같이 1바이트 위치의 순환 배열을 사용하는 것이다
  • 버퍼의 크기는 서로 동일하지 않을 수 있다

그림은 데이터의 한 방향으로 이동을 보여준다

sending buffer

  • 송신버퍼에는 세 가지 유형의 칸이 있다

    • 흰색 섹션

      • 송신 프로세스(생산자)가 채우는 빈 칸이다
    • 분홍색 영역

      • 전송되었지만 목적지에서 아직 확인되지 않은 바이트가 있다
      • TCP sender는 receiver로부터 수신 확인을 수신할 때까지 보낸 바이트를 버퍼에 보관한다
    • 회색 영역

      • 송신 TCP에서 보낼 바이트가 있다
        • 그러나 TCP는 이 부분의 일부만 전송할 수 있다
        • 네트워크 트래픽과 받는 프로세스를 고려한 결과이다
  • 분홍색 영역의 바이트가 확인되면 영역은 재활용된다

    • 즉 칸이 순환된다

receiving buffer

  • 원형 버퍼는 두 영역으로 나뉜다
    • 흰색 영역
      • 빈 영역
        • 데이터가 오면 채울 것이다
      • 분홍 영역
        • 수신 프로세스(받은 데이터를 사용할 프로세스)에서 읽을 수 있는 바이트 저장
          • 받은 데이터
        • 수신 프로세스에서 바이트를 읽을 때 영역은 재활용되고 빈 영역에 추가

TCP segments

버퍼링은 두 프로세스 간의 속도 차이를 처리하지만, 데이터를 전송하려면 한 단계가 더 필요하다
IP 계층은 바이트 스트림이 아닌 패킷으로 데이터를 전송해야 한다

  1. transport 계층에서 TCP는 여러 바이트를 세그먼트라고 불리는 패킷으로 그룹화한다

  2. TCP는 각 세그먼트에 헤더를 추가하고(제어 목적으로) 해당 세그먼트를 IP 계층으로 전송한다

  3. 세그먼트들은 IP 데이터그램에 캡슐화되어 전송된다

그림은 버퍼의 바이트에서 세그먼트가 생성되는 것을 보여준다
세그먼트의 크기는 모두 동일할 필요는 없다

Full duplex communication

  • TCP는 데이터가 동시에 양방향으로 제공될 수 있는 full duplex 서비스를 제공한다
  • 각 TCP는 자체 송수신 버퍼를 가지며 세그먼트는 양방향으로 이동한다

Multiplexing and demultiplexing

  • UDP와 마찬가지로 TCP는 sender에서 멀티플렉싱을 수행
  • receiver에서 디멀티플렉싱을 수행

connection oriented services

UDP와 달리 TCP는 연결 지향 프로토콜이다
A의 프로세스가 B의 다른 프로세스와 데이터를 주고받기를 원할 때, 다음과 같은 세 가지 단계가 발생한다

  1. 두 TCP는 서로 가상 연결을 설정
  2. 데이터는 양방향으로 교환
  3. 연결 종료
  • 이 연결은 물리적 연결이 아닌 가상 연결이다

    • 물리적 연결이 없다
  • TCP 세그먼트는 IP 데이터그램에 캡슐화되어 있으며, 순서가 잘못되어 전송되거나 분실되거나 손상되어 재발송될 수 있다

  • 각각은 목적지에 도달하기 위해 다른 경로를 통해 라우팅될 수 있다

  • TCP는 다른 프로세스로 바이트를 전달하는 스트림 oriented 환경을 만든다.

reliable service

  • TCP는 신뢰할 수 있는 전송 프로토콜
    • 데이터의 안전한 도착을 확인하기 위해 ack 메커니즘을 사용

TCP Features

TCP의 여러 기능을 제공하기 위해 TCP에는 이 섹션에서 간략하게 요약하고 나중에 자세히 설명하는 몇 가지 기능이 있다

  • numbering system
  • flow control
  • error control
  • congestion control

Numbering system

TCP는 전송 또는 수신되는 세그먼트를 추적하지만 세그먼트 헤더에는 세그먼트 번호 값에 대한 field가 없다
대신 sequence number와 acknowledgement number라는 두 개의 필드가 있다
이 두 개의 필드는 세그먼트 번호가 아닌 바이트 번호를 나타낸다

바이트 번호

  • TCP는 전송되는 모든 데이터 바이트에 번호를 부여

    • 번호는 각 방향에서 독립적
    • TCP가 프로세스로부터 바이트의 데이터를 수신하면 TCP는 바이트를 송신 버퍼에 저장하고 번호를 매긴다
    • TCP는 첫 번째 번호로 0에서 2^32 - 1 사이의 임의의 숫자를 선택
    • 바이트 번호가 flow 및 error 제어에 사용

각 연결에서 전송되는 데이터의 바이트는 TCP에 의해 넘버링
번호는 임의로 생성된 번호로 시작

sequence number

  • 바이트에 번호가 매겨진 후 TCP는 전송되는 각 세그먼트에 시퀀스 번호를 할당
  • 각 세그먼트의 시퀀스 번호는 해당 세그먼트에서 전송되는 데이터의 첫 번째 바이트 번호

세그먼트의 sequence number의 값은 해당 세그먼트에 포함된 첫 번째 데이터 바이트에 할당된 번호로 정의

Acknowledgement number

TCP는 연결이 설정되면 양쪽 모두 동시에 데이터를 주고받을 수 있다
각 호스트?의 바이트 번호는 보통 다르다
각 방향의 시퀀스 번호는 전달되는 첫 번째 바이트 넘버이다

ack num

  • 각 호스트?는 수신한 바이트 넘버를 확인하기 위해 ack num을 사용
  • ack num은 당사자가 수신할 것으로 예상되는 다음 바이트의 넘버를 정의
  • ack num은 누적이 된다
    • 즉, 수신한 마지막 바이트 넘버를 안전하게 가져와서 여기에 1을 더하고 이 합계를 ack num으로 알림
      • 당사자가 5,643을 승인번호로 사용할 경우 처음부터 5,642까지 모든 바이트를 수신했음을 의미

세그먼트에 있는 ack의 값은 당사자가 수신할 것으로 예상되는 다음 바이트의 수를 정의
ack 넘버는 누적된다

Flow control

  • UDP와 달리 TCP는 flow control을 제공
  • 송신 TCP는 송신 프로세스로부터 수신할 수 있는 데이터의 양을 제어
  • 수신 TCP는 송신 TCP에 의해 송신될 수 있는 데이터의 양을 제어
    • 이는 수신기가 데이터로 가득 차는 것을 방지하기 위해 수행

Error control

  • TCP는 error control 메커니즘을 구현

Congestion control

  • UDP와 달리 TCP는 네트워크의 congestion control이 있다
  • 송신자에 의해 전송되는 데이터의 양은 수신자에 의해 제어될 뿐만 아니라, 네트워크의 혼잡 수준에 의해서도 결정된다.

Segment

TCP에 대해 더 자세히 설명하기 전에 TCP 패킷 자체에 대해 알아보겠다
TCP에서 패킷을 세그먼트라고 한다

TCP segment format

세그먼트는 20 ~ 60 바이트의 헤더와 애플리케이션 프로그램의 데이터로 구성된다

옵션이 없는 경우 헤더는 20바이트이고 옵션이 포함된 경우 최대 60바이트이다

Source port address

  • 세그먼트를 보내는 호스트에서 응용 프로그램의 포트 번호를 정의하는 16비트 필드
  • UDP 헤더의 소스 포트 주소와 같은 용도로 사용

Destination port address

  • 세그먼트를 수신하는 호스트에 응용 프로그램의 포트 번호를 정의하는 16비트 필드
  • UDP 헤더의 destination 포트 주소와 같은 용도로 사용

sequence number

  • 32비트
  • 세그먼트에 포함된 데이터의 첫 번째 바이트에 할당된 숫자를 정의
    • 연결을 보장하기 위해 전송될 각 바이트에 번호가 매겨짐
    • 시퀀스 번호는 이 세그먼트의 첫 번째 바이트를 지칭
    • 연결 설정 중 랜덤으로 번호를 뽑아 초기 시퀀스 번호(ISN)를 생성

acknowledgement number

  • 32비트
  • 세그먼트의 수신자가 상대방으로부터 수신할 것으로 예상되는 바이트 번호를 정의
    • 세그먼트의 receiver가 상대편으로부터 바이트 번호 x를 성공적으로 수신한 경우 x + 1을 수신 확인 번호로 반환

HLEN

  • 4비트
  • TCP 헤더에 있는 워드의 수를 나타낸다
  • 헤더의 길이는 20바이트에서 60바이트 사이일 수 있다
    • 따라서 이 값은 항상 5 (5 × 4 = 20)에서 15 (15 × 4 = 60) 사이

Reserved

  • 그냥 여분

Control

  • 6개의 다른 제어 플래그
    • 하나 이상 한 번에 설정할 수 있다
  • TCP에서 flow 제어, 연결 설정 및 종료, 연결 중단 및 데이터 전송 모드를 설정

Window size

  • 16비트
    • window의 최대 크기가 65535 바이트임을 의미
  • 송신 TCP의 window 크기를 바이트 단위로 정의
  • 이 값은 일반적으로 수신 window(rwnd)라고 하며 수신기에 의해 결정
    • 이 경우 sender는 receiver의 지시에 따라야

Checksum

  • 16비트
  • TCP 체크섬의 계산은 UDP에 대해 설명한 것과 동일한 절차
    • 그러나 UDP 데이터그램에서 체크섬 사용은 선택 사항이지만 TCP에 체크섬 사용은 필수 사항
  • UDP와 동일한 슈도 헤더가 세그먼트에 추가
  • TCP 슈도 헤더의 경우 프로토콜 값은 6

TCP에서 체크섬은 의무적으로 사용한다

urgent pointer

  • 16 bit
  • 긴급 flag 설정된 경우에만 유효
    • 세그먼트에 긴급 데이터가 포함된 경우에 사용
  • 긴급 데이터의 위치를 알려준다

options

  • TCP 헤더에는 최대 40바이트의 옵션이 가능

Encapsulation

  • TCP 세그먼트는 애플리케이션 계층으로부터 수신된 데이터를 캡슐화
  • TCP 세그먼트는 IP 데이터그램으로 캡슐화되며, 이는 그림과 같이 데이터 링크 계층의 프레임으로 캡슐화

TCP connection

TCP는 연결 지향적이다
연결 지향 전송 프로토콜은 소스와 목적지 사이에 가상 경로를 설정한다
그러면 메시지에 속한 모든 세그먼트가 이 가상 경로를 통해 전송된다
전체 메시지에 대해 단일 가상 경로를 사용하면 확인 프로세스와 손상되거나 손실된 프레임의 재전송이 용이해집니다
요점은 TCP 연결이 물리적 연결이 아니라 가상이라는 것이다
TCP는 IP 서비스를 사용하여 개별 세그먼트를 수신자에게 전달하지만 연결 자체를 제어한다
세그먼트가 손실되거나 손상되면 다시 전송된다
TCP와 달리 IP는 이 재전송을 인식하지 못한다
세그먼트가 잘못된 순서로 도착하면 TCP는 누락된 세그먼트가 도착할 때까지 세그먼트를 유지한다
IP는 세그멘트의 순서를 알지 못한다
TCP에서 연결 지향 전송은 연결 설정, 데이터 전송, 연결 종료의 세 단계를 필요로 한다

Connection Establishment

TCP는 양방향으로 데이터를 전송한다
두 대의 컴퓨터에 있는 두 개의 TCP가 연결되면 서로 동시에 세그먼트를 전송할 수 있다
이는 데이터가 전송되기 전에 상대방으로부터 승인을 받아야 함을 의미한다

Three way handshaking

서버

  • 프로세스는 서버에서 시작
  • 서버 프로그램은 TCP에 연결을 허용할 준비가 되었음 passive open을 통해 알림

클라이언트

  • 클라이언트 프로그램이 active open을 실행
  • 열린 서버에 연결하려는 클라이언트는 TCP에 특정 서버에 연결하도록 지시
  • 이제 TCP는 그림과 같이 3way handshaking 프로세스를 시작할 수 있다

  1. 클라이언트는 첫번째 세그멘트인 SYN(SYN 세그먼트)을 전송

    • 이 세그먼트에서는 SYN만 설정한다
      • 시퀀스 넘버의 동기화를 위한 것
    • 클라이언트는 첫 번째 시퀀스 번호로 임의의 숫자를 선택하고 이 번호를 서버로 보낸다
      • 이 시퀀스 번호를 초기 시퀀스 번호(ISN)라고 한다
    • 이 세그먼트에는 ack num이 없다
    • window 크기도 정의 되어있지 않다
      • window 크기는 ack가 포함된 경우에만 의미가 있다
    • 몇 가지 옵션이 포함될 수 있다
    • 데이터 전송이 시작되면 ISN이 1씩 증가

SYN 세그먼트는 데이터를 전송할 수 없지만 하나의 시퀀스 넘버를 사용

  1. 서버는 두번째 세그멘트인 SYN + ACK 세그멘트를 전송

    • 이 세그먼트의 두가지 목적
      • 다른 방향의 통신을 위한 SYN 세그먼트
        • 서버는 이 세그먼트를 사용하여 서버에서 클라이언트로 보낸 바이트의 넘버를 초기화
      • 서버는 ACK flag를 설정하고 클라이언트로부터 수신할 것으로 예상되는 다음 시퀀스 넘버를 나타내 클라이언트로부터 1의 메시지 수신을 승인
      • 수신 윈도우 크기 rwnd(클라이언트에서 사용)도 정의
        • 수신 버퍼 크기

SYN + ACK 세그먼트는 데이터를 전송할 수 없지만 하나의 시퀀스 넘버를 사용

  1. 클라이언트가 세 번째 세그먼트인 ACK 세그먼트 보냄

    • ACK flag 및 ack num으로 두 번째 세그먼트의 수신을 승인
      • 2번째 세그멘트 동기화 값에 1 추가해서 응답해야지
    • 시퀀스 넘버는 SYN 세그먼트(1)의 시퀀스 번호와 동일
      • 이 세그먼트는 시퀀스 넘버를 쓰지 않는다
      • 보내는 데이터가 없으므로
    • 클라이언트는 서버 창 크기를 정의
      • 송신 버퍼 크기

ACK 세그먼트는 데이터가 없는 경우 시퀀스 번호를 사용하지 않는다

즉 동기화를 보내면 그에 맞는 응답(동기화 + 1) 값을 보내야하며 송수신버퍼 사이즈도 연결할때 보내야한다

Data Transfer

연결이 설정된 후에는 양방향 데이터 전송이 이루어질 수 있다
클라이언트와 서버는 양방향으로 데이터와 확인 응답을 보낼 수 있다

  1. 클라이언트가 두 세그먼트에 2,000바이트의 데이터를 전송한다
  2. 서버는 한 세그먼트에 2,000바이트를 보낸다
  3. 클라이언트가 세그먼트를 하나 더 보낸다
  4. 마지막 세그먼트는 더 이상 전송할 데이터가 없기 때문에 ack num만 전송한다

시퀀스 및 ack 넘버의 값을 기록한다

Connection Termination

클라이언트 서버 둘 다 연결을 닫을 수 있다

3 way handshake

오늘날 대부분의 구현에서는 연결 종료를 위한 3 way 핸드셰이킹을 허용한다

  1. 클라이언트 TCP는 FIN flag가 설정된 FIN 세그먼트를 전송
    • FIN 세그먼트는 클라이언트가 보낸 마지막 데이터 청크를 포함할 수도 있고 그림과 같이 제어 세그먼트일 수도 있다
    • 제어 세그먼트만 있는 경우 하나의 시퀀스 번호만 소비

FIN 세그먼트는 데이터를 전송하지 않는 경우 하나의 시퀀스 번호를 소비

  1. 서버 TCP는 FIN 세그먼트를 수신한 후 두 번째 세그먼트인 FIN+ACK 세그먼트를 전송

    • 클라이언트로부터 FIN 세그먼트의 수신을 확인함과 동시에 다른 방향의 연결 종료를 알린다
    • 이 세그먼트는 서버의 마지막 데이터 청크를 포함할 수도 있다 데이터를 전송하지 않으면 하나의 시퀀스 번호만 소비한다
  2. 클라이언트 TCP는 마지막 세그먼트인 ACK 세그먼트를 전송하여 TCP 서버로부터 FIN 세그먼트의 수신을 확인

    • 이 세그먼트에는 서버에서 FIN 세그먼트에서 수신한 시퀀스 번호에 1을 더한 확인 번호가 포함
    • 이 세그먼트는 데이터를 전송할 수 없으며 시퀀스 번호를 사용하지 않는다

Half close

  • 한 쪽은 연결 종료가 되었지만 다른 쪽은 계속 데이터를 받을 수 있다

  • 서버 또는 클라이언트 중 하나가 하프 클로즈 요청을 실행할 수 있다

FIN + ACK 세그먼트는 데이터를 전송하지 않는 경우 하나의 시퀀스 번호를 소비

클라이언트에서 서버로 데이터 전송이 중지된다
클라이언트는 FIN 세그먼트를 전송하여 연결을 절반으로 닫는다
서버는 ACK 세그먼트를 전송하여 하프 클로즈를 수락한다
그러나 서버는 여전히 데이터를 전송할 수 있다
서버는 처리된 모든 데이터를 전송하면 클라이언트의 ACK에 의해 확인되는 FIN 세그먼트를 전송한다
Half close를 한 후 데이터는 서버에서 클라이언트로 전송되고 ack은 클라이언트에서 서버로 전송될 수 있다
클라이언트가 서버에 데이터를 더 이상 보낼 수 없다
두 번째 세그먼트(ACK)는 시퀀스 넘버를 사용하지 않는다
클라이언트가 시퀀스 넘버 y-1을 수신하고 y를 예상하지만 서버 시퀀스 넘버는 여전히 y -1이다
연결이 닫힐 때 마지막 ACK 세그먼트의 시퀀스 넘버는 여전히 x다
왜냐하면 해당 방향으로 데이터를 전송하는 동안 시퀀스 넘버가 소비되지 않기 때문이다

State transition diagram

연결 설정, 연결 종료 및 데이터 전송 중에 발생하는 모든 다양한 이벤트를 추적하기 위해 TCP는 state 머신으로 나타내 진다

Scnarios

TCP state machine과 transition 다이어그램을 이해하기 위해 몇 가지 시나리오를 본다

Connection 설정, half close termination(4way로 한다)

클라이언트

  1. 클라이언트 프로세스는 TCP에 명령을 실행하여 특정 소켓 주소에 대한 연결을 요청

    • 이를 active open이라고 한다
  2. TCP는 SYN 세그먼트를 전송하고 SYN-SENT 상태로 이동

  3. SYN+ACK 세그먼트를 수신한 후, TCP는 ACK 세그먼트를 전송하고 Established 상태로 이행

  4. 데이터는 양방향으로 전송되고 확인된다

  5. 클라이언트 프로세스에 보낼 데이터가 더 이상 없으면 active close라는 명령을 실행 클라이언트 TCP는 FIN 세그먼트를 전송하고 FIN-WAIT-1 상태로 이동

  6. 전송된 FIN에 대한 ACK를 수신하면 FIN-WAIT-2 상태가 되고 서버로부터 FIN 세그먼트를 수신할 때까지 유지

  7. FIN 세그먼트가 수신되면 클라이언트는 ACK 세그먼트를 전송하고 TIME-WAIT 상태로 전환하고 최대 세그먼트 lifetime(MSL)의 2배의 시간 초과 값에 대한 타이머를 설정

    • MSL은 세그먼트가 삭제되기 전에 인터넷에 존재할 수 있는 최대 시간
    • TCP 세그먼트는 제한된 수명(TTL)을 갖는 IP 데이터그램에 캡슐화된다
  8. time out이 되면 close

서버

  1. 서버 프로세스는 open을 실행
    • 클라이언트가 열린 명령을 실행하기 전에 이 문제가 발생해야 합니다.
  2. 서버 TCP는 LISTEN 상태가 되고 SYN 세그먼트를 수신할 때까지 수동적으로 유지
  3. 서버 TCP는 SYN 세그먼트를 수신하면 SYN+ACK 세그먼트를 전송하고 SYN-RCVD 상태로 전환하여 클라이언트가 ACK 세그먼트를 전송하기를 기다린다
  4. ACK 세그먼트를 수신한 후, 데이터 전송이 발생할 수 있는 Established 상태로 전환
  • TCP는 클라이언트 TCP로부터 FIN 세그먼트를 수신할 때까지 이 상태를 유지
  1. 클라이언트에서 fin이 오면 서버는 클라이언트에 ACK를 전송하고 CLOSE-WAIT 상태로 전환
  2. half close를 가정한다 서버 TCP는 여전히 클라이언트에 데이터를 보내고 수신확인을 받을 수 있지만, 이제 어떤 데이터도 다른 방향으로 보낼 수 없다
    • 응용 프로그램이 실제로 닫기 명령을 실행할 때까지 서버 TCP는 이 상태를 유지
  3. 클라이언트에 FIN을 전송하여 연결도 닫히고 있음을 보여주고 LAST-ACK 상태가 됨
    • 이 상태는 final ACK를 수신한 후 CLOSED 상태로 전환될 때까지 유지

첫 번째 FIN으로 시작하는 종료 단계를 4 way 핸드쉐이크라고 한다

위 transition 다이어그램을 timeline으로 구성한 그림

Common 시나리오

연결 설정 및 연결 종료 단계에서 3way 핸드쉐이크가 일반적이다
그림은 이 시나리오에서 클라이언트와 서버에 대한 transition 다이어그램이다


아래는 time line이다
연결종료 부분만 위의 timeline과 다르다

그림은 데이터 전송 단계 이후의 모습이다

  1. 클라이언트 TCP가 FIN 세그먼트를 전송하고 FIN-WAIT-1 상태가 된다
    • 서버 TCP는 FIN 세그먼트를 수신하면 연결을 닫는다
  2. passive close를 수신한 후, 서버는 클라이언트에 FIN+ACK 세그먼트를 전송하고 LAST-ACK 상태로 이동하여 final ACK를 기다린다
  3. 클라이언트는 FIN-WAIT-2 상태를 제거하고 TIME-WAIT 상태로 바로 이동한다

simultaneous open

동시에 열린 경우 두 응용 프로그램 모두 활성 상태로 열린다
이것은 클라이언트나 서버가 없는 드문 경우이다
이 경우는 TCP에 의해 허용되지만, 양쪽이 SYN 세그먼트를 서로 전송해야 하고 세그먼트가 동시에 전송되기 때문에 발생할 가능성은 낮다
그림은 이 시나리오에 대한 연결 설정 단계를 보여준다
두 TCP는 모두 Established 상태로 가기 전에 SYN-Sent 및 SYN-RCVD 상태를 거친다
자세히 보면 두 프로세스가 모두 클라이언트와 서버 역할을 한다는 것을 알 수 있다 두 개의 SYN+ACK 세그먼트가 SYN 세그먼트를 인식하고 연결을 연다
연결 설정에는 4way 핸드셰이크가 포함된다

simultaneous close

이 경우 양쪽이 active close를 한다
두 TCP 모두 FIN-WAIT-1 상태로 전환되고 전송 중인 FIN 세그먼트를 동시에 전송한다
FIN 세그먼트를 수신한 후, 각 엔드는 CLOSING 상태가 되고 ACK 세그먼트를 보낸다
닫힘 상태는 공통 시나리오에서 FIN-WAIT-2 또는 CLOSE-WAIT를 대체한다
ACK 세그먼트를 수신한 후 각각 TIME-WAIT 상태로 이동한다
각 엔드가 손실될 수 있는 ACK를 전송했기 때문에 양 엔드에 이 기간이 필요하다

Aborting connection

클라이언트 프로세스가 갑자기 끝냈을 때 상황이다
프로세스는 연결을 닫는 대신 연결을 중단할 수 있다
이러한 경우 모두 TCP는 RST 세그먼트를 전송하여 연결을 중단할 수 있다
TCP는 RST+ACK 세그먼트를 전송하고 대기열의 모든 데이터를 버린다
서버 TCP는 또한 대기 중인 모든 데이터를 삭제하고 오류 메시지를 통해 서버 프로세스에 알린다
두 TCP는 즉시 CLOSED 상태로 전환된다
RST 세그먼트에 응답하여 ACK 세그먼트가 생성되지 않는다

Windows in TCP

TCP에서의 데이터 전송과 flow, error 및 congestion 제어와 같은 문제에 대해 논의하기 전에 TCP에서 사용되는 window에 대해 설명한다
TCP는 데이터 전송의 각 방향에 대해 두 개의 윈도우(전송과 수신)을 사용하며, 이는 양방향 통신에 4개의 윈도우가 있다는 것을 의미한다
근데 여기선 쉽게 하기 위해 단일 통신으로 가정하겠당~
버퍼 얘기다 !!

Send window

그림은 송신 윈도우의 예다
송신 윈도우 크기가 flow control과 기본 네트워크의 혼잡(congestion control)에 의해 결정된다

Receive window

Flow control

flow control은 생산자가 데이터를 생성하는 속도와 소비자가 데이터를 사용할 수 있는 속도를 균형 있게 조정한다
TCP는 flow control과 error control를 분리한다
flow control을 설명하기 위해 일시적으로 송신 TCP와 수신 TCP 사이의 논리적 채널이 오류가 없다고 가정한다
그림은 송신자와 수신자 사이의 단방향 데이터 전송을 보여준다

상대방의 버퍼를 초과하지 않게 도와준다!

  • 데이터가 송신 프로세스에서 송신 TCP로, 송신 TCP에서 수신 TCP로, 수신 TCP에서 수신 프로세스(경로 1, 2, 3)까지 전송된다는 것을 보여준다
  • 그러나 flow control 피드백은 수신 TCP에서 송신 TCP로, 송신 TCP에서 송신 프로세스(경로 4와 5)로 전달

대부분의 TCP 구현체들은 수신 프로세스에서 수신 TCP로 flow control 피드백을 제공하지 않는다

  • 즉, 수신 TCP는 송신 TCP를 제어하고 송신 TCP는 송신 프로세스를 제어한다

전송 TCP에서 전송 프로세스(경로 5)로의 flow control 피드백은 창이 꽉 찼을 때 TCP를 전송함으로써 데이터의 간단한 거부를 통해 달성된다

  • 즉, flow control에 대한 논의는 수신 TCP에서 송신 TCP로 전송된 피드백에 집중(경로 4)

EX

Opening and closing windows

  • TCP는 송신자와 수신자가 윈도 크기를 조정하도록 강제한다

수신 window

  • 수신 윈도우의 열기, 닫기 및 축소는 sender에 의해 제어
  • 송신자로부터 더 많은 바이트가 도착하면 수신 윈도우가 닫힌다(왼쪽 벽이 오른쪽으로 이동)
  • 프로세스가 더 많은 바이트를 끌어오면 수신 윈도우가 열린다(오른쪽 벽이 오른쪽으로)
  • 윈도우는 수축하지 않는다고 가정한다(우측 벽이 왼쪽으로 이동하지 않는다)

송신 window

  • 송신 윈도우의 열기, 닫기 및 축소는 receiver에 의해 제어
  • 새 ack가 허용되면 전송 창이 닫힌다(왼쪽 벽이 오른쪽으로 이동)
  • 송신 윈도우는 수신 윈도우 크기(rwnd)가 허용되면 (오른쪽 벽이 오른쪽) 열립니다.
  • 송신 윈도우는 가끔 수축한다

그림은 연결 설정 단계에서 송수신 창이 어떻게 설정되는지, 그리고 데이터 전송 중에 해당 상황이 어떻게 변화하는지 보여준다
어떠한 세그먼트도 손상되거나, 분실되거나, 복제되거나, 고장 난 상태로 도착하지 않는다고 가정하여 error control을 무시한다
단방향 데이터 전송을 위한 창은 두 개뿐이다

  1. 첫 번째 세그먼트는 연결을 요청하기 위해 클라이언트에서 서버(SYN 세그먼트)로 이동한다
    클라이언트는 초기 seqNo = 100을 알린다
    이 세그먼트가 서버에 도착하면 버퍼 크기를 800(가정)으로 할당하고 전체 버퍼를 포함하도록 창을 설정한다(rwnd = 800)
    다음에 도착하는 바이트 넘버는 101이다
  2. 두 번째 세그먼트는 서버에서 클라이언트로 이동한다 ACK + SYN 세그먼트이다
    세그먼트는 ackNo = 101을 사용하여 101부터 시작하는 바이트를 수신할 것으로 예상함을 나타낸다
    또한 클라이언트가 버퍼 크기를 800바이트로 설정할 수 있음을 알린다
  3. 세 번째 세그먼트는 클라이언트에서 서버로 가는 ACK 세그먼트이다
  4. 클라이언트가 서버에서 지정한 크기(800)로 창을 설정한 후 프로세스는 200바이트의 데이터를 푸시한다
    TCP 클라이언트는 이 바이트에 101에서 300까지 번호를 매긴다
    그런 다음 세그먼트를 생성하여 서버로 보낸다
    세그먼트는 시작 바이트 번호를 101로 표시하고 세그먼트는 200바이트를 전송한다
    그런 다음 클라이언트의 창은 200바이트의 데이터가 전송되었지만 확인 응답을 대기하고 있음을 표시하도록 조정된다
    이 세그먼트가 서버에서 수신되면 바이트가 저장되고 수신 창이 닫히며 다음 바이트가 301 바이트로 예상되며 저장된 바이트는 200 바이트의 버퍼를 차지한다
  5. 다섯번째 세그먼트는 서버에서 클라이언트로의 피드백이다
    서버는 300바이트(바이트 301을 수신할 예정)를 ack한다
    세그먼트는 감소 후(600) 수신 윈도우의 크기도 전달한다
    클라이언트는 이 세그먼트를 수신한 후 윈도우에서 확인된 바이트를 퍼지하고 윈도우를 닫아 전송할 다음 바이트가 바이트 301임을 표시한다
    그러나 창 크기는 600바이트로 감소한다
    할당된 버퍼는 800바이트를 저장할 수 있지만, receiver가 이를 허용하지 않기 때문에 윈도우를 열 수 없다
  6. 세그먼트 6은 프로세스가 300바이트를 더 푸시한 후 클라이언트에 의해 전송된다
    세그먼트 정의 seqNo는 301이며 300바이트를 포함한다
    이 세그먼트가 서버에 도착하면 서버는 해당 세그먼트를 저장하지만 윈도우 크기를 줄여야 한다
    이 프로세스가 100바이트의 데이터를 가져오면 윈도우는 왼쪽에서 닫히지만 오른쪽에서 100바이트의 데이터를 가져온다
    그 결과 크기가 200바이트만 줄어든다
    receiver 윈도우 크기는 이제 400바이트이다
  7. 세그먼트 7에서 서버는 데이터 수신을 승인하고 윈도우 크기가 400임을 알린다
    이 세그먼트가 클라이언트에 도착하면 클라이언트는 윈도우를 다시 줄이고 윈도우 크기를 서버에서 주는 rwnd = 400의 값으로 설정할 수밖에 없다
    송신 윈도우는 왼쪽에서 300바이트만큼 닫히고 오른쪽에서 100바이트만큼 열린다
  8. 세그먼트 8 또한 프로세스가 200바이트를 더 끌어낸 후 서버에서 온다
    윈도우 크기가 커진다
    이제 새 rwnd 값은 600이다
    세그먼트는 서버가 여전히 바이트 601을 기대하지만 서버 윈도우 크기가 600으로 확장되었음을 클라이언트에 알린다
    이 세그먼트가 클라이언트에 도착하면 클라이언트는 윈도우를 닫지 않고 200바이트만큼 연다
    그 결과 창 크기가 600바이트로 증가한다

Window shutdown

오른쪽 벽을 왼쪽으로 이동하여 송신 윈도우를 축소하는 것은 매우 권장되지 않는다
그러나 한 가지 예외가 있다
receiver는 0의 rwnd를 전송하여 창을 일시적으로 종료할 수 있다
이 문제는 어떤 이유로든 수신자가 송신자로부터 데이터를 한동안 수신하지 않으려는 경우에 발생할 수 있다
이 경우 sender는 실제로 창 크기를 축소하지 않고 새 ad가 도착할 때까지 데이터 전송을 중지한다

Error control

TCP는 신뢰할 수 있는 전송 계층 프로토콜이다
즉, TCP에 데이터 스트림을 전달하는 응용 프로그램은 TCP에 의존하여 전체 스트림을 다른 쪽의 응용 프로그램에 데이터를 순서대로 오류 없이, 그리고 어떤 부분도 손실되거나 복제되지 않고 전달한다는 것을 의미한다
TCP는 error control을 사용하여 신뢰성을 제공한다
오류 제어에는 손상된 세그먼트를 감지 및 다시 보내기, 손실된 세그먼트를 다시 보내기, 누락된 세그먼트가 도착할 때까지 잘못된 세그먼트를 저장하기, 중복된 세그먼트를 감지 및 폐기하기 위한 메커니즘이 포함된다
TCP의 오류 제어는 체크섬, ack, time out이라는 세 가지 간단한 도구를 사용하여 이루어진다

AcK

TCP는 ack를 사용해 데이터 세그먼트의 수신을 확인한다
데이터가 전송되지 않지만 시퀀스 번호를 소비하는 제어 세그먼트도 ack이다
ACK 세그먼트는 ack되지 않는다

ACK 세그먼트는 시퀀스 번호를 소비하지 않으며 ack되지 않는다

ACK 규칙

  1. A가 B로 데이터 세그먼트를 보낼 때 수신할 것으로 예상되는 다음 시퀀스 번호를 제공하는 ack을 포함해야 한다
  2. receiver에 전송할 데이터가 없고 순서대로 세그먼트(예상 시퀀스 번호 포함)를 수신하고 이전 세그먼트가 이미 승인되었으면, receiver는 다른 세그먼트가 도착하거나 일정 시간(보통 500ms)이 경과할 때까지 ACK 세그먼트 전송을 지연한다
  3. receiver가 예상하는 시퀀스 번호와 함께 세그먼트가 도착하고 이전 순서의 세그먼트가 승인되지 않은 경우, receiver는 즉시 ACK 세그먼트를 전송합니다. 즉, 한 번에 두 개 이상의 순서대로 확인되지 않은 세그먼트가 있어서는 안 된다
  4. 세그먼트가 예상보다 높은 순서에서 벗어난 시퀀스 번호로 도착하면 수신기는 즉시 다음 예상 세그먼트의 시퀀스 번호를 알리는 ACK 세그먼트를 전송합니다. 이는 누락된 세그먼트의 빠른 재전송으로 이어진다
  5. 누락된 세그먼트가 도착하면 수신기는 ACK 세그먼트를 전송하여 예상되는 다음 시퀀스 번호를 알린다 이것은 누락된 것으로 보고된 세그먼트가 수신되었음을 수신자에게 알린다
  6. 중복 세그먼트가 도착하면 수신자는 세그먼트를 폐기하지만 예상되는 다음 순서의 세그먼트를 나타내는 ack을 즉시 보냅니다.

Out of order segment

TCP는 순서가 뒤바뀐 세그먼트를 폐기하지 않는다
이러한 세그먼트는 해당 세그먼트를 임시로 저장하고 누락된 세그먼트가 도착할 때까지 out of order 세그먼트로 태그된다
그러나 순서가 잘못된 세그먼트는 프로세스에 전달되지 않는다
TCP는 데이터가 순서대로 프로세스에 전달되도록 보장한다

데이터는 수신 TCP에 의해 일시적으로 저장될 수 있지만, TCP는 프로세스에 잘못된 데이터가 전달되지 않도록 보장한다

Normal operation

두 시스템 간의 양방향 데이터 전송을 보여준다
클라이언트 TCP는 하나의 세그먼트를 보내고 서버 TCP는 세 개의 세그먼트를 보낸다
그림은 각 ack에 적용되는 규칙을 보여준다
클라이언트의 첫 번째 세그먼트와 세 개의 서버 세그먼트 모두에 규칙 1이 적용된다
전송해야 할 데이터가 있으므로 세그먼트에 예상되는 다음 바이트가 표시된다
클라이언트는 서버로부터 첫 번째 세그먼트를 수신하면 더 이상 전송할 데이터가 없으며 ACK 세그먼트만 전송하면 된다
그러나 규칙 2에 따르면, 더 많은 세그먼트가 도착하는지 확인하기 위해 500ms 동안 ack를 지연해야 한다
ACK 지연 타이머가 만료되면 ack를 보낸다
이는 클라이언트가 자신에게 다른 세그먼트가 올지 말지 모르기 때문이다
다음 세그먼트가 도착하면 다른 ACK 지연 타이머가 설정된다
그러나 타이머가 다 되기 전에 세 번째 세그먼트가 도착한다
세 번째 세그먼트의 도착은 규칙 3에 기초한 다른 ack를 작동시킨다
세그먼트가 손실되거나 지연되지 않기 때문에 RTO 타이머를 표시하지 않았다

Lost segment

세그먼트가 손실되거나 손상되었을 때 어떤 일이 일어나는지 보여준다
손실된 세그먼트는 네트워크 어딘가에서 폐기된다
손상된 세그먼트는 receiver 자체에 의해 폐기된다
둘 다 분실된 것으로 간주된다
그림은 세그먼트가 손실되는 상황을 보여준다
sender는 세그먼트 1과 2를 보내며, 이는 ACK에 의해 즉시 인식된다(규칙 3)
그러나 세그먼트 3은 손실된다
receiver는 순서가 잘못된 세그먼트 4를 수신한다
receiver는 세그먼트의 데이터를 버퍼에 저장하지만 데이터에 연속성이 없음을 나타내기 위해 간격을 둔다
receiver는 기대하는 다음 바이트(규칙 4)를 표시하는 ack를 sender에게 즉시 보낸다
receiver는 바이트 801에서 900을 저장하지만 간격이 좁혀질 때까지 이 바이트를 애플리케이션에 전달하지 않는다

수신기 TCP는 순서가 지정된 데이터만 프로세스에 전달합니다.

Fast retransmission

빠른 재전송을 보여준다
receiver는 네 번째, 다섯 번째, 여섯 번째 세그먼트를 수신할 때마다 ack를 트리거한다(규칙 4)
sender는 동일한 값(3개의 중복)을 가진 4개의 ack를 수신한다
타이머가 끝나지 않았음에도 불구하고, 빠른 전송을 위한 규칙은 이러한 모든 중복 ack에 의해 예상되는 세그먼트 3을 즉시 재발송해야 한다
이 세그먼트를 다시 보낸 후 타이머가 다시 시작된다

Lost ACK

손실된 ack가 다음 ack에 포함되는 상황을 보여준다
ack는 누적될 수 있다
그림은 데이터 수신기가 보낸 손실된 ack를 보여준다
다음 ack는 자동으로 ack의 손실을 수정한다

Lost ack corrected by resending a segment

그림은 ack가 손실되는 시나리오를 보여준다
다음 ack가 오랫동안 지연되거나 응답이 없는 경우 RTO 타이머에 의해 다시 응답없는 세그멘트를 전송한다
중복 세그먼트가 결과이다
receiver는 중복 세그먼트를 수신하면 해당 세그먼트를 폐기하고 마지막 ACK를 즉시 재전송하여 송신자에게 세그먼트가 수신되었음을 알린다
두 개의 세그먼트가 승인되지 않지만 한 개의 세그먼트만 재전송된다
송신자가 재전송된 ACK를 수신하면, ack가 누적되기 때문에 두 세그먼트가 모두 안전하고 정상임을 알 수 있다

확인이 손실되면 제대로 처리되지 않으면 교착 상태가 발생할 수 있다

Congestion control

TCP의 혼잡 제어는 open loop와 closed loop 메커니즘을 기반으로 한다
TCP는 정체를 피하고 정체가 발생하면 이를 감지하고 완화한다

Slow start exponential increase

cwnd가 2의 지수적으로 증가한다

sender는 cwnd = 1 으로 시작한다
즉, 보낸 사람이 세그먼트를 하나만 보낼 수 있다
첫 번째 ACK가 도착한 후 정체 윈도우의 크기는 1만큼 증가하며, 이는 cwnd가 현재 2라는 것을 의미한다
이제 두 개의 세그먼트를 보낼 수 있다
두 개의 ACK가 도착하면 cwnd가 이제 4가 된다
이제 4개의 세그먼트를 더 보낼 수 있다
4개의 ACK가 도착하면 창의 크기가 4만큼 증가하는데, 이는 cwnd가 현재 8이라는 것을 의미한다

이 지수적 증가는 무한정 계속할 수 없다
이 단계를 중지하려면 임계값이 있어야 한다
sender는 sstresh(느린 시작 임계값)라는 변수를 보면서 창 크기가 이 값에 도달하면 지수적 증가가 중지되고 다음 단계가 시작된다

느린 시작 알고리즘에서 정체 창의 크기는 임계값에 도달할 때까지 기하급수적으로 증가합니다.

Congestion avoidance additive increase

느린 시작 알고리즘으로 시작하면 정체 윈도우의 크기가 기하급수적으로 증가한다
혼잡이 발생하기 전에 혼잡을 피하려면, 이 지수 성장을 늦춰야 한다
TCP는 congestion 회피라고 불리는 또 다른 알고리즘을 정의한다

cwnd = i인 경우 정체 창의 크기가 느린 시작 임계값에 도달하면 느린 시작 단계가 중지되고 추가 단계가 시작된다
이 알고리즘에서 세그먼트의 전체 "윈도우"가 승인될 때마다 정체 윈도우의 크기가 1씩 증가한다
윈도우크기는 전송된 세그먼트 수이다
cwnd가 더하기로 증가한다

혼잡 회피 알고리즘에서 혼잡 창의 크기는 혼잡이 감지될 때까지 부가적으로 증가한다.

TCP 혼잡제어 요약

정체가 발생하면 정체 창 크기를 줄여야 한다
receiver가 혼잡이 발생했다고 추측할 수 있는 유일한 방법은 세그먼트를 재전송해야 하는 것이다
재전송은 RTO 타이머가 시간 초과되거나 세 개의 중복 ACK가 수신되는 두 가지 경우 중 하나에서 발생할 수 있다
두 경우 모두 임계값이 절반으로 떨어진다

  1. 시간 초과가 발생하면 혼잡이 발생할 가능성이 더 높다 이 경우 TCP는 강하게 반응한다
    a. 임계값 값을 현재 창 크기의 절반으로 설정
    b. cwnd를 다시 1로 줄임
    c. 느린 시작 단계를 다시 시작
  2. 3개의 중복 ACK가 수신되면 혼잡이 발생할 가능성이 좀 약함 이 경우 TCP는 아래와 같이 반응이 약하다
    a. 임계값 값을 현재 창 크기의 절반으로 설정
    b. cwnd를 임계값으로 설정
    c. 정체 회피 단계를 시작

EX

임계값은 처음에는 16개 세그먼트(최대 창 크기의 절반)로 설정된다
느린 시작 단계에서 창 크기는 1부터 시작하여 임계값에 도달할 때까지 기하급수적으로 증가한다
임계값에 도달한 후 "더하기 증가" 절차를 사용하면 시간 초과가 발생하거나 최대 창 크기에 도달할 때까지 창 크기가 선형적으로 증가할 수 있다
창 크기가 20일 때 시간 초과가 발생한다
이 때 곱셈 감소 절차가 처리를 이어받아 임계값을 창 크기의 절반으로 줄인다
타임아웃이 발생했을 때 창 크기가 20이었으므로 현재 새 임계값은 10이다
TCP는 느린 시작으로 다시 이동하고 창 크기가 1로 시작하며 새 임계값에 도달하면 추가 증가로 이동한다
창 크기가 12이면 3ACK 이벤트가 발생한다
곱셈 감소 절차가 다시 이어진다
임계값과 창 크기가 6으로 설정되고 TCP가 이번에는 추가 증가 단계로 들어간다
TCP는 다른 시간 초과 또는 다른 3-ACK 이벤트가 발생할 때까지 이 단계를 유지한다

TCP Timers

원활한 작동을 위해 대부분의 TCP 구현은 최소 4개의 타이머를 사용한다

Options

TCP 헤더에는 최대 40바이트의 옵션이 포함될 수 있다
옵션은 추가 정보를 대상에 전달하거나 다른 옵션을 정렬한다
1바이트 옵션과 다중바이트 옵션이라는 두 가지 옵션이 있다
1바이트 옵션에는 옵션 목록 종료와 작업 없음이라는 두 가지 유형의 옵션이 있다
다중 바이트에는 최대 세그먼트 크기, 창 스케일 팩터, 타임스탬프, SACK 허용 및 SACK의 다섯 가지 유형의 옵션이 있다

profile
정리
post-custom-banner

0개의 댓글