TCP가 담당하는 것은 서버가 송신할 때와 서버가 수신한 후 애플리케이션에게 전달할 때로, 상대 서버까지 전송하는 부분은 하위 계층인 IP에 위임한다.
✍🏻 TCP의 역활은 간단히 말해서 애플리케이션이 보낸 데이터를 그 형태 그대로 상대방에게 확실하게 전달하는 것이다.
TCP에 의존하지 않고 IP만으로도 통신할 수 있지만, IP에는 데이터가 상대방에게 확실히 전달됐는지 확인하는 기능이나 도착한 순서를 확인하는 기능 등이 없다.
✍🏻TCP 핵심 기능
- 포트번호를 이용해서 데이터 전송
- 연결 생성
- 데이터 보증과 재전송 제어
- 흐름 제어와 폭주 제어
TCP는 데이터를 세그먼트라고 하는 단위로 관리하고 있다. 이 때문에 애플리케이션 데이터에 TCP 헤더를 붙여서 TCP 세그먼트를 작성한다. 헤더에는 도착 지점 포트 번호를 포함해서 TCP 세그먼트를 작성한다. 헤더에는 도착 지점 포트 번호를 포함해서 TCP 기능을 표현하기 위한 수많은 정보가 기록된다. 최종적으로 링크 계층을 사용해서 데이터를 전송하기 때문에 MSS(세그먼트 최대 데이터 크기)는 링크 계층에서 전송할 수 있는 최대 크기에 의존하며, 환경이나 설정에 따라 달라진다.
상대 서버에 데이터가 도착하면 어떤 애플케이션 데이터인지 알 수가 없다. TCP에서는 포트 번호를 사용해서 애플케이션 데이터를 어디에 보낼 지 판단한다.
✍🏻 포트 번호를 이용해서 데이터를 적합한 애플리케이션을 할당한다.
- 커널 내 TCP계층에서 가상 결로를 열어 줄 것을 의뢰한다.
- 서버의 xx번 포트에 데이터를 보내고 싶다고 통신 경로를 요청한다.
- 통신을 받는 측은 열어도 된다고 응답한다.
- httpd 프로세스에서 리슨하고 있던 xx번 포트에 통신을 받는다.
- 받은 통신에서 응답을 보내준다.
- 응답을 받으면 확인했다는 메시지를 보내준다. 그러면 가상 경로가 생성된다. 송신 측에도 자동적으로 포트 번호가 설정된 소켓이 열린다.
연결이 생성된 후에야 데이터 송수신이 시작된다. 데이터를 확실이 전달되도록 보증하는 기능이 있다.
확인 응답과 재전송에 의해 구현된다.
수신측에 TCP 세그먼트가 도착하면 수신 측은 송신 측에게 도착했다고 알린다.
이것을 ACK라고 한다. TCP 헤더에 ACK 관련 정보를 넣은 TCP 세그먼트를 반환한다.
✍🏻송신 측은 ACK가 돌아오는 것을 보고 전송한 세그먼트가 무사히 도착했다는 것을 알 수 있다.
만약에 오지 않으면 문제가 발생했다는 의미이다. 그러기 때문에 언제든지 재정송이 가능하도록 TCP 세그먼트라도 ACK가 돌아오기까지는 소켓 버퍼에 남겨 둔다.
데이터 순서를 보증하기 위해서 TCP 세그먼트에 ✨시퀀스(Sequence)번호를 붙인다.
시퀀스 번호도 TCP헤더에 기록되며, 해당 세그먼트가 가지고 있는 데이터가 전송 데이터 전체 중 몇 바이트째부터 시작하는 부분인지를 가리키고 있다.
- 타임아웃 - 특정 시간내에 도착하지 않으면 재전송을 요청한다.
- 중복 ACK - 중복돼서 도착한 경우 그 번호에 해당하는 TCP 세그먼트가 도착하지 않았다고 간주한다.
- SACK(selective ACK) - SACK 옵션에서 도착했다는 정보를 전달가능, 이를 통해서 도착하지 않은 TCP 세그먼트만 선택해서 재전송 가능하다.
ACK를 기다리지 않고 전송 가능한 데이터크기를 윈도우 크기라고 한다. 윈도우 크기를 통해서 송수신을 판단할 수 있다. 윈도우 크기 이상을 보내면 ACK를 보낼 수 없다. 윈도우 크기에 따라 흐름을 제어한다.
네트워크가 혼잡하면 폭주 윈도우 크기를 작게 해서 전송 데이터 양을 줄인다. 이것이 폭주 제어다.
그림으로 공부하는 IT인프라구조를 참고해서 작성했습니다.