window
TCP(1)
TCP
TCP 란 연결지향형 프로토콜이며, 다음과 같은 특징이 있다.
- point-to-point: 소켓과 소켓 간의 연결 (한쌍의 소켓 간의 연결이다)
- reliable, in-order byte stream : 신뢰성 및 순서 보장
- pipelined : 여러 데이터를 한번에 보낼수 있다.
- full duplex data: 송신자이자 수신자가 될수 있다.
- connection oriented : handshaking 을 연결단계에 한다.
- flow controlled: 상대방의 컴퓨터 성능에 맞춰 segment를 보낸다.
- congestion controll: 네트워크 상태에 따라 보내는 속도를 조절한다.
TCP 세그먼트 구조
위 사진은 TCP 세그먼트 구조를 나타낸다.
순서 번호 (sequence number)
순서번호는 특정 세그먼트의 첫번째 바이트 이다. 예를 들어, 첫 번째 세그먼트가 100바이트 크기를 가지고 시작 순서 번호가 0이라면, 이 세그먼트는 0번 바이트부터 99번 바이트까지의 데이터를 포함한다. 따라서 다음 세그먼트의 시작 순서 번호는 100이 된다.
확인 응답 번호 (acknowledgement number)
확인 응답 번호는 다음으로 기대하는 바이트 이다. 만약 ACK#100 이라면, 나는 sequence number 가 99 번인것까지는 모두 정상적으로 받았고 이제 sequence number가 100번인 데이터를 받기를 기대한다 라는 의미이다.
Window
TCP 연결을 하게되면 송신 수신 시스템 모두 Send Buffer 와 Rcv Buffer 를 가지게 된다.
이때 TCP 프로토콜은 애플리케이션 계층으로부터 받은 데이터를 Send Buffer에 넣은후 수신시스템인 B의 Rcv Buffer에 전송하게 된다.
애플리케이션 계층은 TCP 의 전송속도를 고려하여 소켓에 메세지를 보내지 않는다. 즉 Send Buffer엔 TCP 프로토콜에 의해 보내지는 데이터보다 더 많은 데이터가 쌓여있다.
Window란 Send Buffer에서 TCP프로토콜이 한번에 보낼수 있는 데이터의 양이다.
즉 Window의 크기가 1000byte 라면 TCP 프로토콜은 한번에 1000byte의 데이터를 TCP가 연결된 상대방에게 보낼수 있는 것이다.
TCP 커넥션에서 타이머 및 Send Buffer Rcv Buffer의 상세한 동작과정은 컴퓨터 네트워크 강의 해당 강의 38:00 부터 보면된다.
위 강의를 기반으로 TCP 연결에서의 버퍼 동작과정을 간단하게 정리를 하자면
- Send Buffer 는 결국 재전송을 위한 버퍼이다. base send에 타이머가 물려있으며, 전송해야하는 데이터에 대한 ACK 응답을 받으면 타이머를 이동시킨다.
- Rcv Buffer 는 in-order 를 위한 버퍼이다. sequence number를 기반으로 데이터가 순서에 맞춰 잘 들어 왔는지 확인한다.
- A,B 모두 데이터를 보내고 받을수 있다. 실제 TCP 동작에선 Send Buffer에서 데이터를 보낼때 해당 데이터의 헤더의acknowledgement number에 ACK 응답을 포함한다. (sequence number에는 보내는 데이터의 sequence number가 들어간다.)
Timer 한계 극복
Timer 라는건 Send Buffer의 base send(보내야하는 맨앞 데이터)를 가리키고있다.
해당 데이터에 대한 ACK응답이 도착하면 Send Buffer에서 해당 데이터를 지운다. 만약 데이터가 중간에 유실되었다고 가정해보면, Timer의 timeout 전까지는 재전송을 하지 않으며, 이는 생각보다 비효율 적이다.
Timer의 timeout은 기본적으로 평균 rtt + margin 정도의 시간을 가지는데 이는 생각보다 긴 시간이다.
이러한 문제점을 해결하기위해 fast retransmit(빠른 재전송) 을 사용한다.
위 그림과 같이 윈도우의 크기가 400바이트 이며, 각각의 segment는 100바이트라고 가정을 해보자.
이때 sequence number가 100인 데이터가 전송되는 과정에서 유실되었다고 하면, 수신 시스템에서의 Rcv Buffer는 위와 같이 sequence number가 100인 segment를 제외한 나머지 segment만 있을 것이다.
이때 수신 시스템에서는 ACK 응답을 보내야하는데, 아래와 같이 보낸다.
- sequence number가 0인 데이터에 대해서는 ACK#100 (0~99까지는 잘받았으니 이제 받아야하는게 sequence number가 100인 data야~)
- sequence number가 200인데이터에 대해서도 ACK#100 이 전송된다. 왜냐하면 TCP 프로토콜은 순서를 보장해야한다. 따라서 Rev Buffer는 아직 100번째 segment가 오지 않았기때문에 ACK#100을 응답으로 전송한다.
- sequence number가 300 인 데이터에 대해서도 위와같은 이유로 ACK#100이 응답으로 전송된다.
위과정에서 결국 sequence number가 100인 데이터가 재전송이 되겠지만, timeout이 걸릴때까지 대기해야한다. 따라서 TCP는 3개의 중복 ACK를 수신할 때, 타이머에 관계없이 세그먼트를 재전송하는 fast retransmit을 사용한다. 이때 주의해야 하는점은 3개의 중복 ACK가 의미하는건 알맞은 응답에 대한 ACK 를 제외한 3개의 중복 ACK를 받아야 재전송한다는 의미이다.
위 사진처럼 실제론 4개의 응답을 받아야 fast retransmit에 의해 segment를 재전송 한다.
즉 Timeout 이 지나지 않더라도, fast retransmit(빠른 재전송) 을 사용하게되면 더 효율적으로 TCP 통신을 할수 있다.
'네트워크' 카테고리의 다른 글
RDT(Reliable Data Transfer) (1) | 2023.11.21 |
---|---|
Multiplexing, deMultiplexing (0) | 2023.10.25 |
소켓 (0) | 2023.10.23 |
DNS (0) | 2023.10.19 |
HTTP1/HTTP2/HTTP3 (0) | 2023.10.19 |