TCP

hyeok3011·2023년 10월 25일
2

서버 개발을 하다보면 TCP를 피해갈수 없다.(안피하는게 좋음)
애플리케이션을 개발하면서 TCP소켓을 직접 다루는 일은 거의 없겠지만 기본적으로 어떻게 동작하는지는 알아야 도움이 된다고 생각한다.

TCP

인터넷 중심에는 두 개의 프로토콜 IP와 TCP가 존재한다.

  • IP(Internet Protocol)
    호스트에서 호스트로의 라우팅1과 주소할당(addressing) 기능을 제공한다.
  • TCP(Transmission Control Protocol)
    신뢰성을 보장해주는 네트워크 기능을 제공한다

신뢰할 수 없는 채널 위에 신뢰성을 추상화한 계층이 바로 TCP이다.
유실 데이터 재전송, 전송순서, 혼잡 제어 및 회피, 데이터 무결성 확인등 복잡한 기능을 처리하여
애플리케이션 구현을 한결 쉽게 만들어 준다.

만약 TCP에 이러한 기능이 없었다면 TCP가 해주는 기능을 애플리케이션 단에서 신경쓰며 개발해야할수도 있다.

TCP 특징

  • 전송된 모든 byte는 수신된 모든 바이트와 동일하며 클라이언트에서 전송한 바이트 순서대로 도착한다
  • 3WayHandshake
  • 연결형 프로토콜이다.

위 특징을 보면 알겠지만 TCP는 빠른 데이터 전송보다 정확한 데이터 전송에 특화되어있다.
(이 점이 우리가 사용할때 최적화해야할 요소이기도 하다.)

3Way Handshake

모든 TCP연결은 3Way Handshake를 진행한다.

3way handshake는 왜 하는 것일까?

  • 핸드쉐이크를 진행하는 이유는 양쪽모두 데이터를 전송할 준비가 되었다는 것을 확인
  • 수신자가 자신의 수신 윈도우 사이즈를 보내기 위함
  • 시퀀스 번호 교환 (HOL, Header와 연결된다.)

  1. Syn (Client -> Server)
    클라이언트가 랜덤으로 시퀀스번호 x를 고르고 syn패킷을 보낸다. 그밖의 다른 tcp플래그나 옵션값들을 포함할 수 있다.
  2. Syn + ACK (Server -> Client)
    서버가 x시퀀스 번호 1만큼 증가시키고 랜덤으로 시퀀스번호 y를 고른다. 서버 또한 플래그와 옵션값들을 추가한 후 보낸다.
  3. ACK (Client -> Server)
    클라이언트가 x와 y를 모두 1만큼 증가시킨 후 마지막으로 ack패킷을 보냄으로써 핸드셰이크 과정을 종료한다.

위 초기 절차는 모든 TCP연결에 다 해당된다.

4Way Handshake

3way handshake가 TCP연결 초기 절차라면 4Way Handshake는 연결을 종료 시킬때 하는 절차이다. (내 그림은 이해에 더 방해되기 때문에 더이상 넣지 않겠다.)

  1. Fin (Client -> Server)
    클라이언트가 연결을 종료하겠다는 플래그를 전송한다.
  2. ACK (Server -> Client)
    서버는 플래그를 받아 확인메시지 ACK를 클라이언트에게 보낸다.
  3. Fin (Server -> Client)
    서버는 클라이언트에게 연결 종료 준비가 완료됐다는 메시지를 보낸다.
  4. ACK (Client -> Server)
    클라이언트는 종료 준비가 끝났다는 메시지를 Server로 보낸다.

혼잡 붕괴(congestion collapse)

대역폭이 서로 다른 채널들로 구성된 네트워크에 영향을 주는 현상이다.
이 현상은 게이트웨이가 각각 다른 대역폭을 가진 네트워크와 연결되었을때 특히 더 자주 발생한다.
이 문제를 해결하기위해 양방향으로 데이터를 보내는 속도를 조절할 수 있는 메커니즘들이 도입되었다.

흐름제어

흐름 제어는 송신자가 수신자에게 처리하지 못할 만큼의 많은 데이터를 전송하는 것을 미리 방지하는 메커니즘이다
수신자가 다른 데이터를 처리하고 있거나 밀려있는 데이터가 많거나 버퍼 공간을 충분히 지정해 주지 않는경우 일어난다.
위 문제를 해결하기 위해 양쪽 TCP커넥션이 각각 자신의 리시브윈도(rwnd) 를 통지하여 수신데이터를 저장할 버퍼 공간의 크기를 서로에게 알려준다.
통신중에도 수신자가 데이터 양을 감당하지 못할 경우에는 rwnd를 재통지 할 수 있다.

이러한 작업의 흐름은 TCP커넥션이 시작할 때부터 끝날때까지 계속 된다.

SlowStart

만약 가족 구성원이 각각 방에서 대용량 파일을 다운로드 받으려고 하는데 모두 윈도우 사이즈를 최대치에 가깝게 끌어쓰면 어떻게될까?
순식간에 네트워크는 포화상태에 이르게 될것이고 패킷손실은 계속해서 발생하게 될것이다.

흐름제어는 송신자가 수신자에게 주는 부담을 막아주었으나 네트워크 자체에 주는 부담을 막는 메컴니즘은 없어 SlowStart, 혼잡회피. 빠른 재전송, 빠른회복 메커니즘이 도입되었다.

slow start는 커넥션 초반에는 작은 윈도우 사이즈로 시작해서 점점 윈도 사이즈를 키워 나가는 방법이다.

혼자 윈도(cwnd)
혼잡 윈도 크기(cwnd)클라이언트로부터 응답 확인(ACK) 신호를 받기 전에 송신자 측에서 지정하는 최대 송신 데이터량을 뜻한다.

cwnd는 rwnd와 다르게 서로 확인하는 방법이 아닌 송신자가 혼자만 가지고 있는다.
rwnd와 cwnd중 더 작은 값 설정된다.

혼잡 회피

SlowStart로 작은 윈도 사이즈로 시작하여 시스템에 설정된 임계치 크기를 넘어서거나 패킷이 손실될 때까지 계속된다.
TCP는 패킷 손실이 일어났게되면 네트워크 혼잡이 일어났다는 신호로 판단하고 윈도 사이즈를 조정한다.

혼잡 제어 알고리즘으로 AIMD,CUBIC, PRR, BBR등이 있다.(이거는 추후 다시 정리해보겠다.)

OpenAI Logo https://en.wikipedia.org/wiki/Transmission_Control_Protocol

source port, destination port

송신 포트와 수신 포트 정보이다.

sequence Number

3way handshake에서 발행한 시퀀스 정보가 헤더에 담기게 된다.
이 시퀀스 번호를 이용하여 데이터 순서보장, 무결성 보장한다.

acknowledgment Number

마지막으로 받은 시퀀스 번호에 +1를 더한 값이다. 즉 다음으로 기대하는 시퀀스 번호를 뜻한다.

Data Offset

전체 세그먼트 중에서 TCP 헤더의 크기 즉 데이터의 시작 지점을 나타낸다.

Window Size

rwnd의 크기를 뜻한다.
현재 수신할 수 있는 크기를 뜻한다.

check sum

헤더의 에러 확인을 위해 사용되는 16비트 필드이다.
전송 단계에서 문제가 생겨 헤더에 문제가 생겼더나 변조가 됐는지 확인할 수 있다.


TCP는 모든 상황에서 좋나요??

TCP는 전송 순서 보장, 손실 패킷 재전송, 흐름제어, 혼잡등 모두 제공해주니 모든 상황에서 좋겠네요???

TCP가 널리 쓰이는 것은 사실이지만 모든 상황에서 좋은것은 아니다.
TCP에서 제공하는 기능들이 경우에 따라 불필요한 지연이나 성능에 좋지 않은 영향을 끼칠 수도 있다.

Head-of-Line(HOL) 블로킹

만약 수신자에게 이동 중인 패킷 하나가 소실되면 TCP는 순서 보장, 소실 패킷 재전송을 지원하기 때문에 다른 모든 패킷들은 소실된 패킷이 재전송될 때까지 수신자 쪽 TCP 버퍼에서 대기해야만 한다.
위 과정은 TCP 계층 내에서 이뤄지기 때문에 애플리케이션에서는 내부를 살펴볼 수 없고 패킷이 재전송 되어 정상화가 되어야 데이터에 접근할 수 있다.
애플리케이션 입장에서는 소켓에서 데이터를 읽으려 했을뿐인데 전달 지연을 겪게 된다.
위 현상을 TCP head-of-lie(HOL)블로킹이라 한다.

HOL 블로킹이 발생하게 되면 레이턴시를 예측하기 어렵다. 이러한 현상을 지터jitter 라고 하는데, 지터는 애플리케이션의 성능에 좋지 않은 영향을 끼칠 수 있다.


신뢰성 보다는 성능??

어떤 경우 TCP의 신뢰성보다 성능이 더 중요한 경우가 있다.
게임이 좋은 예시가 될것 같다.
내가 게임 캐릭터를 움직이고 있어 서버로 움직이는 좌표를 계속 보내고 있다.
(0,1), (0,2), (0,3), 손실 ,(0,5)
만약 위처럼 손실이 생긴경우 다시 패킷을 받아야 할까??
아니다 물론 이상적으로는 모든 좌표를 받는 것이 좋겠지만, 하나의 좌표가 누락된다 하더라도 게임 진행에 지연이 생기는 것을 피하기 위해서는 레이턴시가 적게 발생되는 것이 더 좋은 선택이 된다.

마치며

뭔가 빼먹은 내용들이 있는거 같은데 정리하며 발견되면 추가하도록 하겠습니다.

참고한 내용

  • 네트워킹과 웹 성능 최적화 기법
  • TCP WIKI
profile
뇌가 디스크가 아니라는 사실을 깨달아 버린 사람

0개의 댓글