기본적으로 클라이언트와 서버가 HTTP통신을 하려면 그 전에 TCP Connection(연결)이 되어야 합니다. 커넥션이 맺어지면 서로 간에 주고받는 메시지들은 손상되거나 순서가 바뀌지 않고 안전하게 전달된다.
TCP 커넥션은 발신지(클라이언트)의 IP와 Port, 수신지(서버)의 IP와 Port 이렇게 4가지 값으로 식별합니다.
💡 `<발신지 IP 주소, 발신지 Port, 수신지 IP 주소, 수신지 Port>
패킷 전송 방식의 패킷은 데이터를 효율적으로 전송하기 위해 데이터를 작은 조각으로 분할하고 분할된 조각에 헤더를 붙여 캡슐화 데이터를 의미합니다. 그리고 이 패킷을 라우터가 라우팅을 통해 송신 호스트에서 수신 호스트까지 전송하는 것이 패킷 교환 방식입니다.
*1 TCP헤더에선 세그먼트라는 단위로 데이터 스트림을 나눈다.
*2 IP헤더에선 세그먼트를 IP패킷에 담는다.
IP패킷(데이터 단위) 상세구조
TCP/IP프로토콜을 활용해 HTTP 통신 요청을 하기 위해서는 요청 전 논리적인 TCP연결(커넥션 확립)이 필요합니다.
논리적인 TCP 커넥션 확립이란, 애플리케이션 간의 송수신을 하는 데이터 통로를 의미하며 실제 케이블로 연결된 개념이 아닌 가상의 통신로를 의미합니다.
TCP 커넥션 확립을 하기 위해 연결을 생성할 때 거치는 핸드쉐이크 과정을 3 Way-Handshake라고 합니다. 3 Way라는 말 그대로 총 3번의 통신 과정을 거칩니다.
연결을 생성할 때와 마찬가지로, 연결을 종료할 때도 4 Way-Handshake과정을 거쳐 연결을 종료합니다. 한 쪽에서 일방적으로 연결을 끝어버리면 다른 한 쪽은 연결이 끊어졌는지 지속되고 있는지 알 방법이 없다. 또한 연결을 종료하기 전 처리하지 못한 데이터가 있을 수 있기 때문에 양방향 다 정상적으로 연결을 종료할 준비가 되었는 지를 확인하기 위해 4 Way-Handshake과정이 필요하다.
① : 1-2참조
② : 1-1참조
③ : 1-3참조
*tcp연결 상세정보 : https://evan-moon.github.io/2019/11/17/tcp-handshake/
기본적으로 HTTP통신는 TCP 프로토콜 기반으로 동작합니다. TCP가 전송이 끝나면 앞 사진의 내용처럼 연결이 끊어지듯이 HTTP도 전송이 끝나면 끊어집니다(비연결성). 매번 똑같은 주소로 요청을 할 때마다 새로운 연결을 설정하고 끊어야 한다면 자원이 낭비됩니다.
그래서 연결을
여러 개의 요청 있을 경우 순차적으로 각 요청에 대해 1-4 그림처럼 진행하게 된다면 많은 자원(resource)이 낭비하게 된다. 이런 단점을 보완하게 위해 나온 기술이 있다.
병렬 커넥션은 클라이언트가 여러 개의 커넥션을 맺음으로써 여러 개의 HTTP 트랜잭션을 병렬로 처리할 수 있게 하는 방법입니다. 위의 사진에서는 트랜잭션2, 3, 4이 할당받은 각 TCP 커넥션상의 트랜잭션을 통해 병렬로 내려받습니다.
처리가 완료된 후에도 계속 연결된 상태로 있는 TCP 커넥션을 지속 커넥션이라고 한다.
비지속(단일) 커넥션은 각 처리가 끝날 때마다 커넥션을 끊지만, 지속 커넥션은 클라이언트나 서버가 커넥션을 끊기 전까지는 트랜잭션 간에도 커넥션을 유지한다.
HTTP 1.0 기반에서는 각각의 웹컨텐츠별로 TCP 커넥션이 모두 필요했다.
과거 웹페이지가 텍스트 기반 아래 간단한 형태였을 때는 크게 문제가 되지 않았으나, 점점 어플리케이션이 복잡하고 화려해지면서 성능에 문제가 되기 시작했다.
ex) 하나의 HTML과 그 안에 CSS가 10개가 있을 경우 11번의 TCP커넥션이 필요했음
HTTP 1.0 기반에서 지속 커넥션을 사용하기 위해선 클라이언트 측에서 요청을 할 때
Connection: Keep-Alive 헤더를 포함시킨다. 요청을 받은 서버는 지속 커넥션을 받고자 한다면, 응답헤더에 같은 헤더를 포함시키고 또한, Keep-Alive헤더와 최대시간(timeout), 최대 요청(max request)의 수를 알려줘야 합니다.
그러나 HTTP/1.1부터는 지속 커넥션이 기본값이기에 "Connection: keep-alive"가 불필요한 경우가 많습니다.
"Connection: keep-alive" 헤더가 초기HTTP 요청 또는 응답에 사용되는 경우에는 기존처럼 3 Way-Handshake를 초기 연결 설정 중에 한 번만 수행하고 그 이후의 후속 요청들에 대해선 3 Way-Handshake를 수행할 필요 없이 여러 HTTP 트랜잭션에 대해 TCP 연결을 열어 둡니다.
HTTP 1.1 부터는 기본적으로 요청에 대한 연결을 일정시간동안 끊지않도록 되어있기 때문에 keep-alive 헤더를 사용할 필요가 없다.