[Network] Transport Layer 4 - TCP의 Flow control 과 커넥션 방법

chxghee·2024년 10월 31일

Flow control

TCP는 수신자 버퍼의 오버플로우로 인한 packet loss 를 막기 위해 송신시 data의 전송속도를 조절한다.

  • 송신자가 수신자의 버퍼가 감당할수 없을 만큼 데이터를 빠르게 보내게 되면, loss가 발생한다.

  • 때문에 리시버는 자신의 윈도우사이즈를 보낸다.
    (TCP 헤더의 receiver window - 16 bit)
    ➡️ 수신자 버퍼의 여유 공간을 보내는 것이다

  • 송신자는 이 필드를 통해 자신의 data 전송을 조절한다.

TCP 수신자 버퍼

RcvBuffer : 전체 버퍼 사이즈 (4096 바이트)
rwnd : 버퍼의 여유공간
Buffered data : sender가 보낸 총 data - 어플에 올려보낼 data(버퍼에 대기 중)

즉, 받은 데이터 중에 아직 어플에 올라가지 못한 데이터가 버퍼에 남아 있다.

송신자는 수신자 윈도우(received rwnd) 크기에 따라 확인 응답(ACK)을 받지 않은, 즉 in-flight 상태의 데이터를 제한한다.

좀 더 쉽게 말해,
송신자는 수신 윈도우 크기만큼 데이터를 다 보냈으면, ACK 응답을 받지 않은 상태에서는 추가로 데이터를 보내지 않는다는 것이다.

정리하자면 송신자는 자신의 윈도우 사이즈를 조절하여 수신자의 윈도우 사이즈rwnd 를 넘지 않을 만큼의 데이터를 전송한다.



TCP connection menagement

TCP는 handshake를 통해 사전 연결을 진행한다.

TCP는 연결지향적이고 양방향으로 통신이 이루어진다.

떄문에 양쪽 모두 커넥션과 관련된 파라미터를 똑같이 가져야 한다.

그렇다면 어떤 방식으로 연결을 할까?
우선 TCP에서 사용하지는 않지만 2-way handshake부터 알아보자.


2-way handshake

송신자가 연결을 요청하면 수신자가 ok 응답을 보내는 2번의 메세지를 주고 받아 연결하는 간단한 방법.

위와 같이 연결하자 요청을 하면 ok응답을 보내 연결하는 방법이다.

2-way handshake서는 서버가 클라이언트로부터 요청을 받으면 바로 연결을 수락하고 바로 데이터를 전송한다.

그러나 이 과정에서 클라이언트가 실제로 서버의 응답을 받았는지 확인하지 않기 때문에 연결의 신뢰성에 문제가 생길 수 있다.

그럼 어떤 상황에서 문제가 발생할 수 있는지 살펴보자.

2-way handshake의 문제점

  1. 네트워크의 지연이 발생할 수 있다.

    • 연결이 성공하여 서버가 ok를 보냈지만 time out이 발생하면,
      재요청을 보내 연결이 중복되는 상황이 발생 가능하다.
  2. loss가 발생할 수 있다.

    • 연결이 성공했지만 서버의 ok응답이 loss가 발생하면
      재요청을 보내 연결이 중복되는 상황이 발생 가능하다.
  3. 패킷의 순서가 바뀔 수 있다.

그럼 좀더 자세한 시나리오를 살펴보자.

1. 정상적인 상황.

2. 비정상적인 상황

반열림 연결이 발생하거나, 중복된 데이터를 받는 상황이 발생할 수 있다.

1. 반 열림 연결

위와 같이 연결이 성공하여 서버가 ok를 보냈지만 네트워크의 지연으로 time out이 발생하면, 연결요청을 재전송 하게 된다.

이때 연결이 끝난뒤 이 재전송 연결이 늦게 도착하게 되면 서버 혼자만 연결된
반 열림 연결이 발생한다.

2. 중복 데이터 받는 상황

반 열림 상황이 발생하고
이전 연결의 데이터 재전송이 (서버는 데이터를 잘 받았지만 loss/딜레이로 인한 재전송)
늦게 도착하게되면 중복된 데이터를 받는 상황이 발생한다.


위와 같은 문제를 방지하기 위해 3-way handshake 를 통해 연결을 한다.

3-way handshake

클라이언트와 서버는 서로의 연결 의사를 확인하고, 연결이 원활히 설정되었음을 확인한다.

1단계: 클라이언트가 서버에 SYN 패킷을 전송

  • 클라이언트는 서버에 연결을 요청하는 SYN(Synchronize) 패킷을 보낸다.

2단계: 서버가 SYN-ACK 패킷을 클라이언트에 전송

  • 서버는 클라이언트로부터 SYN 패킷을 수신하면 연결 요청을 수락.

  • 그 후, SYN-ACK 패킷을 클라이언트에 보냄.
    여기에는 서버의 초기 시퀀스 번호와 클라이언트의 SYN 요청에 대한 확인 응답(ACK) 정보가 포함됩니다.

3단계: 클라이언트가 ACK 패킷을 서버에 전송

  • 서버로부터 SYN-ACK 패킷을 받으면, 서버가 연결 요청을 수락했음을 확인.

  • 그 후, ACK 패킷을 서버에 다시 보내면서, 클라이언트와 서버의 연결이 완료됩니다.

  • 이떄 바로 메세지 데이터를 같이 넣어 보내 통신가능

  • 클라이언트가 서버에 연결을 요청할 때, SYN 비트를 1로 설정한 패킷을 보낸다

  • 서버는 이에대한 ACK 응답과 자신도 연결을 한다는 의미로 SYN 을 설정하여 패킷을 보냄


TCP 커넥션의 종료

TCP연결 해제는 FIN bit를 1로 설정한 패킷을 보내 연결종료의사를 알린다.

  • 서버와 클라의 TCP 통신은 양방향이므로 둘다 자신의 연결 종료의사를 보낼수 있다.
    (FIN bit 1로 설정한 패킷을 보내 연결 종료를 요청할 수 있다)

  • FIN 패킷을 보내면 응답으로 FIN-ACK 패킷을 보낸다.


profile
다 같이 화이팅! 🙋‍♂️

0개의 댓글