네트워크 패킷 브로커 TCP 연결의 핵심 미스터리: 트리플 핸드셰이크의 필요성을 밝혀냈습니다.

TCP 연결 설정
웹 서핑, 이메일 전송, 온라인 게임 등을 할 때 우리는 그 뒤에 숨겨진 복잡한 네트워크 연결에 대해 종종 간과합니다. 하지만 이처럼 사소해 보이는 단계들이 사용자와 서버 간의 안정적인 통신을 보장합니다. 가장 중요한 단계 중 하나는 TCP 연결 설정이며, 그 핵심은 3-웨이 핸드셰이크입니다.

이 글에서는 3-웨이 핸드셰이크의 원리, 프로세스, 그리고 중요성에 대해 자세히 설명합니다. 3-웨이 핸드셰이크가 필요한 이유, 연결 안정성과 신뢰성을 보장하는 방법, 그리고 데이터 전송에 있어 3-웨이 핸드셰이크의 중요성을 단계별로 설명합니다. 3-웨이 핸드셰이크를 더 깊이 이해함으로써 네트워크 통신의 기본 메커니즘을 더 잘 이해하고 TCP 연결의 안정성을 더욱 명확하게 이해할 수 있을 것입니다.

TCP 3방향 핸드셰이크 프로세스 및 상태 전환
TCP는 연결 지향 전송 프로토콜로, 데이터 전송 전에 연결 설정이 필요합니다. 이 연결 설정 과정은 3-웨이 핸드셰이크를 통해 이루어집니다.

 TCP 3방향 핸드셰이크

각 연결에서 전송되는 TCP 패킷을 자세히 살펴보겠습니다.

처음에는 클라이언트와 서버 모두 닫힘(CLOSED) 상태입니다. 먼저, 서버는 특정 포트에서 능동적으로 대기하고 있으며 LISTEN 상태입니다. 즉, 서버를 시작해야 합니다. 다음으로, 클라이언트는 웹페이지에 액세스할 준비가 됩니다. 클라이언트는 서버와 연결을 설정해야 합니다. 첫 번째 연결 패킷의 형식은 다음과 같습니다.

 SYN 패킷

클라이언트가 연결을 시작할 때, 임의의 초기 시퀀스 번호(client_isn)를 생성하여 TCP 헤더의 "시퀀스 번호" 필드에 입력합니다. 동시에 클라이언트는 SYN 플래그 위치를 1로 설정하여 송신 패킷이 SYN 패킷임을 나타냅니다. 클라이언트는 첫 번째 SYN 패킷을 서버로 전송하여 서버와의 연결을 설정하려 함을 나타냅니다. 이 패킷에는 애플리케이션 계층 데이터(즉, 전송된 데이터)가 포함되어 있지 않습니다. 이 시점에서 클라이언트의 상태는 SYN-SENT로 표시됩니다.

SYN+ACK 패킷

서버가 클라이언트로부터 SYN 패킷을 수신하면, 서버는 자신의 일련 번호(server_isn)를 무작위로 초기화한 후 TCP 헤더의 "일련 번호" 필드에 해당 번호를 입력합니다. 그런 다음, 서버는 "확인 응답 번호" 필드에 client_isn + 1을 입력하고 SYN 비트와 ACK 비트를 모두 1로 설정합니다. 마지막으로, 서버는 클라이언트에게 패킷을 전송하는데, 이 패킷에는 애플리케이션 계층 데이터(그리고 서버가 전송할 데이터)가 포함되어 있지 않습니다. 이 시점에서 서버는 SYN-RCVD 상태에 있습니다.

ACK 패킷

클라이언트가 서버로부터 패킷을 수신하면 최종 응답 패킷에 응답하기 위해 다음과 같은 최적화를 수행해야 합니다. 첫째, 클라이언트는 응답 패킷의 TCP 헤더의 ACK 비트를 1로 설정합니다. 둘째, 클라이언트는 "Confirm answer number" 필드에 server_isn + 1 값을 입력합니다. 마지막으로, 클라이언트는 패킷을 서버로 전송합니다. 이 패킷은 클라이언트에서 서버로 데이터를 전송할 수 있습니다. 이러한 작업이 완료되면 클라이언트는 ESTABLISHED 상태로 전환됩니다.

서버가 클라이언트로부터 응답 패킷을 수신하면 ESTABLISHED 상태로 전환됩니다.

위 과정에서 볼 수 있듯이, 3-웨이 핸드셰이크를 수행할 때 세 번째 핸드셰이크는 데이터를 전송할 수 있지만, 처음 두 핸드셰이크는 전송할 수 없습니다. 이는 면접에서 자주 묻는 질문입니다. 3-웨이 핸드셰이크가 완료되면 양측은 연결이 성공적으로 설정되었음을 나타내는 ESTABLISHED 상태로 전환되고, 이때 클라이언트와 서버는 서로에게 데이터를 전송할 수 있습니다.

왜 세 번 악수하는 거야? 두 번이 아니라 네 번?
일반적인 답은 "3방향 핸드셰이크가 송수신 기능을 보장하기 때문"입니다. 이 답은 맞지만, 표면적인 이유일 뿐, 근본적인 이유는 제시하지 않습니다. 아래에서는 이 문제에 대한 이해를 심화하기 위해 3방향 핸드셰이크의 이유를 세 가지 측면에서 분석해 보겠습니다.

3방향 핸드셰이크는 역사적으로 반복되는 연결의 초기화를 효과적으로 방지할 수 있습니다(주요 이유)
3방향 핸드셰이크는 양측이 모두 신뢰할 수 있는 초기 시퀀스 번호를 받았음을 보장합니다.
3자 핸드셰이크는 자원 낭비를 방지합니다.

이유 1: 과거 중복 조인을 피하세요
간단히 말해서, 3-웨이 핸드셰이크의 주된 목적은 이전의 중복 연결 초기화로 인한 혼란을 피하기 위한 것입니다. 복잡한 네트워크 환경에서는 데이터 패킷 전송이 항상 지정된 시간에 맞춰 목적지 호스트에 전송되는 것은 아니며, 네트워크 혼잡 등의 이유로 오래된 데이터 패킷이 목적지 호스트에 먼저 도착할 수도 있습니다. 이를 방지하기 위해 TCP는 3-웨이 핸드셰이크를 사용하여 연결을 설정합니다.

3방향 핸드셰이크는 과거 중복 연결을 방지합니다.

클라이언트가 네트워크 혼잡 등의 상황에서 여러 개의 SYN 연결 설정 패킷을 연속으로 보내면 다음과 같은 현상이 발생할 수 있습니다.

1- 최신 SYN 패킷보다 오래된 SYN 패킷이 서버에 도착합니다.
2- 서버는 이전 SYN 패킷을 수신한 후 클라이언트에게 SYN + ACK 패킷을 응답합니다.
3- 클라이언트가 SYN + ACK 패킷을 수신하면, 자신의 컨텍스트에 따라 해당 연결이 과거 연결(시퀀스 번호 만료 또는 시간 초과)인지 판단한 후, RST 패킷을 서버로 전송하여 연결을 중단합니다.

2-핸드셰이크 연결에서는 현재 연결이 과거 연결인지 확인할 방법이 없습니다. 3-웨이 핸드셰이크를 사용하면 클라이언트가 세 번째 패킷을 전송할 준비가 되었을 때 컨텍스트를 기반으로 현재 연결이 과거 연결인지 확인할 수 있습니다.

1- 과거 연결(시퀀스 번호 만료 또는 시간 초과)인 경우, 세 번째 핸드셰이크에서 전송된 패킷은 과거 연결을 중단하기 위한 RST 패킷입니다.
2- 기존 연결이 아닌 경우, 세 번째로 전송된 패킷은 ACK 패킷이며, 두 통신 당사자는 성공적으로 연결을 설정합니다.

따라서 TCP가 3방향 핸드셰이크를 사용하는 주된 이유는 과거의 연결을 방지하기 위해 연결을 초기화하기 때문입니다.

이유 2: 양 당사자의 초기 시퀀스 번호를 동기화하기 위함
TCP 프로토콜의 양측은 안정적인 전송을 보장하는 핵심 요소인 일련 번호를 유지해야 합니다. 일련 번호는 TCP 연결에서 중요한 역할을 하며, 다음과 같은 기능을 합니다.

수신기는 중복된 데이터를 제거하고 데이터의 정확성을 보장할 수 있습니다.

수신기는 패킷을 순서 번호 순서대로 수신하여 데이터 무결성을 보장할 수 있습니다.

● 시퀀스 번호는 상대방이 수신한 데이터 패킷을 식별할 수 있어 안정적인 데이터 전송을 가능하게 합니다.

따라서 TCP 연결이 설정되면 클라이언트는 초기 시퀀스 번호를 포함한 SYN 패킷을 전송하고, 서버는 클라이언트의 SYN 패킷 수신 성공을 나타내는 ACK 패킷으로 응답해야 합니다. 그런 다음, 서버는 초기 시퀀스 번호를 포함한 SYN 패킷을 클라이언트에게 전송하고 클라이언트의 응답을 기다립니다. 이렇게 하면 초기 시퀀스 번호가 안정적으로 동기화됩니다.

양 당사자의 초기 일련번호를 동기화합니다.

4-웨이 핸드셰이크를 통해 양측의 초기 일련 번호를 안정적으로 동기화할 수도 있지만, 두 번째와 세 번째 단계를 하나의 단계로 통합하여 3-웨이 핸드셰이크를 만들 수도 있습니다. 그러나 두 번의 핸드셰이크는 한쪽 당사자의 초기 일련 번호가 다른 당사자에게 성공적으로 수신되었음을 보장할 뿐, 양측의 초기 일련 번호를 확인할 수 있다는 보장은 없습니다. 따라서 TCP 연결의 안정성과 신뢰성을 보장하기 위해서는 3-웨이 핸드셰이크가 최선의 선택입니다.

이유 3: 자원 낭비를 피하세요
"투 핸드셰이크"만 있는 경우, 클라이언트의 SYN 요청이 네트워크에서 차단되면 클라이언트는 서버가 보낸 ACK 패킷을 수신할 수 없으므로 SYN이 재전송됩니다. 그러나 세 번째 핸드셰이크가 없으므로 서버는 클라이언트가 연결 설정에 필요한 ACK를 수신했는지 확인할 수 없습니다. 따라서 서버는 각 SYN 요청을 수신한 후에만 연결을 사전에 설정할 수 있습니다. 이로 인해 다음과 같은 문제가 발생합니다.

자원 낭비: 클라이언트의 SYN 요청이 차단되어 여러 SYN 패킷이 반복적으로 전송되는 경우, 서버는 요청을 수신한 후 여러 개의 중복된 유효하지 않은 연결을 설정하게 됩니다. 이로 인해 서버 자원이 불필요하게 낭비됩니다.

메시지 보존: 세 번째 핸드셰이크가 없기 때문에 서버는 클라이언트가 연결 설정에 필요한 ACK를 제대로 수신했는지 확인할 방법이 없습니다. 결과적으로 메시지가 네트워크에 정체되면 클라이언트는 SYN 요청을 계속해서 보내게 되고, 서버는 끊임없이 새로운 연결을 설정하게 됩니다. 이는 네트워크 혼잡과 지연을 증가시키고 전반적인 네트워크 성능에 부정적인 영향을 미칩니다.

자원 낭비를 피하세요

따라서 네트워크 연결의 안정성과 신뢰성을 보장하기 위해 TCP는 3방향 핸드셰이크를 사용하여 연결을 설정하여 이러한 문제가 발생하지 않도록 합니다.

요약
그만큼네트워크 패킷 브로커TCP 연결은 3방향 핸드셰이크를 통해 이루어집니다. 3방향 핸드셰이크 과정에서 클라이언트는 먼저 SYN 플래그가 포함된 패킷을 서버로 전송하여 연결 설정을 원함을 나타냅니다. 클라이언트의 요청을 수신한 서버는 SYN 플래그와 ACK 플래그가 포함된 패킷을 클라이언트에게 응답하여 연결 요청이 수락되었음을 알리고, 자신의 초기 시퀀스 번호를 전송합니다. 마지막으로 클라이언트는 ACK 플래그를 서버에게 전송하여 연결이 성공적으로 설정되었음을 나타냅니다. 따라서 두 당사자는 ESTABLISHED 상태가 되어 서로에게 데이터를 전송할 수 있습니다.

일반적으로 TCP 연결을 설정하기 위한 3방향 핸드셰이크 프로세스는 연결의 안정성과 신뢰성을 보장하고, 과거 연결로 인한 혼란과 리소스 낭비를 피하고, 양측이 데이터를 수신하고 보낼 수 있도록 설계되었습니다.


게시 시간: 2025년 1월 8일