영호
[Network] Transport layer(2) - TCP reliable data transfer 본문
TCP란
- Transport layer의 프로토콜 중 하나로 연결 지향적인 프로토콜입니다.
- 패킷 손실 복구, 패킷 순서 보장, 흐름 제어, 혼잡 제어 등의 기능을 제공합니다.
- 두 개의 host 간 connection이 설정되면 양방향 소통이 가능합니다.
- handshaking 과정을 통해 연결 초기 설정을 합니다.
- receiver의 상태에 따라 패킷 전송속도를 조절합니다.
- TCP헤더는 기본 20byte이고, 옵션 추가에 따라 60byte까지 늘어날 수 있습니다.
- 헤더의 Sequence number, Acknowledgement number필드를 통해 reliable data transfer가 가능합니다.
- 헤더의 Window size필드를 통해 receiver의 상태를 파악해 데이터 전송 속도를 조절합니다.
TCP헤더(Sequence number)
- 전송할 segment의 데이터 필드의 시작 byte에 부여된 바이트 단위의 순서 번호를 의미합니다.
- sequence number는 무조건 0부터 시작하는 것이 아닌 난수 발생기를 통해 결정합니다.
- Receiver 측에서 sequence number를 보고 데이터를 조립합니다.
TCP헤더(Acknowledgement number)
- 전송받기를 원하는 다음 byte의 sequence number를 의미합니다.
- sequence number 10까지 받았다면 Acknowledge number는 11이 되고, 이것은 sequence number 10 까지는 받았다는 것을 의미 함으로, cumulative Ack 기능을 합니다.
TCP 동작 과정
- 위 사진은 telenet을 사용하는 시나리오입니다. telnet은 한 글자를 타이핑할 때마다 전송합니다..
- host A가 host B에게 seq=42, data = "C"로 헤더를 채워서 전송을 합니다.
- ACK=79는 이전에 host B가 seq=78을 보냈다고 유추할 수 있습니다.
- data="C"에 해당하는 sequence number는 42를 의미합니다.
- host B는 Ack를 seq=42까지 받았다는 의미로 ACK=43으로 채우고, 자신이 보낼 데이터와 해당 데이터의 sequence number를 채워서 host A에게 전송합니다.
TCP Reliable data transfer
TCP는 기본적으로
- 이전 포스팅에서 살펴본 pipelined segments
- cumulative ack
- 하나의 timer
위 3가지를 사용해 reliable 한 데이터 전송을 지원합니다. cumulative ack, pipiline을 사용하기 때문에 Go-Back-N을 사용한다고 생각할 수 있지만, TCP에서는 timeout이 발생하면 해당 패킷 하나만 재전송하는 점에서 Go-Back-N과 차이점이 있습니다.
재전송 trigger
- timeout
- duplicate acks
TCP Sender
위 사진은 TCP의 sender입장에서 일어나는 일들을 간단하게 FSM으로 나타낸 것입니다.
우선 가장 초기 작업인 1번을 보면 NextSeqNum, SendBase를 InitialSeqNum으로 설정해줍니다. 이때 InitialSeqNum은 무조건 0이 아닌 난수 생성기를 통해 생성됩니다.
이후 Application layer로부터 데이터를 받은 상황인 2번을 보게 되면 Application layer로부터 받은 데이터로 세그먼트를 만들고 Network layer로 전송해줍니다. 이후 NextSeqNum을 보낸 데이터의 길이만큼 늘려줍니다. 이때 동작하고 있는 timer가 없다면 timer를 동작시킵니다.
3번은 timeout이 발생한 상황입니다. 이 때는 아직 Ack를 받지 않은 세그먼트들 중 seq num이 가장 작은 세그먼트에 대해서만 재전송이 이루어지고 타이머를 재시작합니다.
4번은 Ack가 온 상황입니다. TCP는 cumulative Ack를 사용하기 때문에 받은 Ack 번호 이전 세그먼트들 중 아직 Ack를 못 받은 세그먼트들도 모두 Ack를 받았다고 표시해주고 sendbase를 옮깁니다.
TCP 재전송 시나리오(timeout)
위 사진은 timeout이 발생할 경우 TCP가 어떤 식으로 재전송해서 데이터의 손실 방지, 순서를 보장해주는지 보여주는 사진입니다.
1번의 경우
- Host A는 Seq=92, 8byte의 데이터(92~99)를 보냅니다.
- Host B에 정상적으로 도착을 했기 때문에 이제 Host B는 seq 100의 세그먼트를 받기를 원하기 때문에 Ack=100으로 설정한 뒤 Host A에 보냅니다.
- 이때 Host B가 Host A에게 보낼 세그먼트가 있다면 추가해서 보내게 됩니다.
- 이 과정에서 Ack가 손실이 됐기 때문에 Host A에선 timeout이 발생합니다.
- 그래서 아직 Ack를 받지 않은 세그먼트 중 seq num이 가장 작은 seq=92를 재전송합니다.
2번의 경우 1번과 비슷합니다. 다만 Ack가 손실이 나진 않았지만 네트워크 상황에 의해 delay가 발생해 Host A에 늦게 도착했기 때문에 도착 이전에 timeout이 발생합니다.
- Host A입장에선 {seq=92, 8byte 데이터(92~99)}, {seq = 100, 20byte 데이터(100~119)} 보냈고,
- Host B는 이를 모두 정상적으로 받았기 때문에 이제 seq=120 세그먼트를 받길 희망합니다.
- 그러나 이 과정에서 Host B의 Ack가 delay에 의해 Host A에 늦게 도착했고, timeout이 발생했기 때문에 Host A는 seq=92, 8byte의 데이터를 재전송합니다.
- 이에 Host B는 본인이 원하는 seq=120이 아니기 때문에, Host A에게 다시 Ack=120을 보냅니다.
- 이를 받은 Sender는 cumulative Ack에 의해 119 세그먼트 까지는 정상적으로 도착했다는 것을 알게 됐고, sendbase를 120으로 수정하고 이후, 이를 토대로 세그먼트를 전송하게 됩니다.
TCP 재전송 시나리오(duplicate Ack)
위 사진에는 없지만 재전송 trigger부분에서 언급한 duplicate Ack는 만약 sender가 동일한 Ack를 3개 받게 되면 timeout과 동일하게 아직 Ack를 못 받은 세그먼트 중 seq num이 가장 작은 세그먼트를 재전송하게 됩니다. 이를 'triple duplicate Ack'라고 합니다.
아래 사진이 'triple duplicate Ack'에 관한 내용입니다.
위 사진을 보면 Host A는 아직 timeout이 발생하지 않았지만 동일한 Ack를 3개 받자 재전송하는 것을 볼 수 있습니다.
- Ack=100을 4개 받고 보냈다고 생각할 수 있지만 처음 온 Ack=100은 Seq=92, 8byte 데이터에 대한 Ack입니다.
- 이후로 오는 Ack=100들은 Seq=100의 손실로 인해 오는 duplicate Ack이기 때문에, 3개의 동일한 Ack를 받고 재전송하는 것입니다.
다음으로
위와 같은 방식을 이용해 TCP는 reliable data transfer기능을 제공해줍니다. 다음에는 TCP는 연결 지향형 프로토콜이기 때문에 Handshaking에 대해 알아보겠습니다.
출처
https://www.gatevidyalay.com/transmission-control-protocol-tcp-header/
'Network' 카테고리의 다른 글
[Network] Transport layer(1) (0) | 2022.07.20 |
---|---|
[Network] DNS(Domain Name System) (0) | 2022.07.16 |