[네트워크] TCP 3-way-handshake, 4-way-handshake
1. TCP
1-1. TCP란?
TCP는 Transmission Control Protocol로써, 신뢰성이 높고 연결 지향 프로토콜이다. ”신뢰성이 높다” 의미는 두 장치 간에 정보를 전달함에 있어 안정적이고 순서대로 에러 없이 데이터를 교환할 수 있음을 의미한다.
TCP는 연결 지향 프로토콜이기 때문에 두 장치가 데이터를 교환하기 전에 연결을 맺어야 한다. 여기서 연결을 맺는다는 것은 두 장치간에 세션이 존재하는지 확인한다는 의미이다. 두 장치가 세션을 연결하기 위해서는 3-way-handshake 과정을 거쳐아 한다.
2. 3-way-handshake
STEP 1. Client → Server로 SYN 패킷 전송
SYN 요청이란 연결을 요청하는 패킷이다. 발신자가 수신자에게 SYN 요청을 보내어 연결을 맺자고 요청한다. 발신자가 최초로 SYN 패킷을 전송할 때는 임의의 Sequence Number를 설정하고 SYN 플래그 비트를 1로 설정한다. (seq = x, x = random number)
발신자는 SYN 패킷을 보내고 난 후, 수신자로부터 SYN/ACK 응답을 기다리는 SYN_SENT 상태가 된다.
STEP 2. Server → Client SYN/ACK 패킷 전송
Server는 Client로부터 요청을 기다리는 LISTEN 상태에서 SYN 요청을 받게 된다. SYN 요청을 받았다는 의미의 ACK 패킷과 Client에게 포트를 열어달라는 의미의 SYN 패킷을 전송한다. 이를 SYN/ACK 패킷이라고 한다.
Client로부터 전달받은 seq 값에 1을 더한 ACK 패킷을 생성하고, Server 측의 Sequence Number인 y 값을 생성한다. → (seq = y, ack = x+1, x는 클라이언트가 보낸 Sequence Number)
서버는 SYN 응답을 받은 상태이므로 SYN_RECEIVED 상태가 된다.
STEP 3. Client → Servet ACK 패킷 전송
Client는 Server에게 응답(SYN/ACK)을 정상적으로 받았다는 의미의 ACK 패킷을 전송한다. 이때, Server 측으로부터 받은 seq값인 y에 1을 더한 ACK 패킷(y+1)을 Server로 전송한다. (ack = y + 1, y는 서버가 보낸 Sequence Number)
이로써 Client와 Server 간에 세션이 연결되고 두 장치간에 데이터를 교환할 수 있는 ESTABLISHED 상태가 된다.
이렇게 3단계의 3-way-handshake 과정을 거치면 두 장치간에 데이터를 전송할 수 있게 된다. 3-way-handshake는 데이터를 전송하기 위해서 많은 시간을 소요한다. 이는 UDP 통신보다 느린 이유 중 하나이다.
3. TCP를 사용하는 이유
3-way-handshake로 인해 시간이 많이 소요되는 TCP 통신을 왜 하는 것일까? TCP 통신은 신뢰성이 높은 통신 방법이다. 신뢰성이 중요한 통신에서 사용되는데, 예시로 파일 전송 프로토콜(FTP), 단순 메일 전송 프로토콜(SMTP) 등에서 사용된다.
반대로 실시간 온라인 게임, 스트리밍 등은 빠른 속도를 요구하기 때문에 TCP 통신을 사용하기엔 부적절하다. 실시간성이 중요한 통신에는 TCP 대신 UDP 통신을 사용하는 것이 적절하다. UDP 통신은 비연결 지향 프로토콜이기 때문에 3-way-handshake를 수행하지 않아 속도가 빠르다. 그러나 두 장치간에 세션을 연결하지 않기 때문에 데이터 무결성을 보장하지 않는다. 이는 데이터 교환 중에 패킷 손실이 발생할 수 있다.
4. 4-way-handshake
3-way-handshake의 경우 TCP 연결을 위해 사용했다면, 4-way-handshake는 연결을 종료하기 위해 사용된다.
STEP 1. Client → Server로 연결 종료 요청 (FIN)
3-way-handshake을 통해 세션이 연결된 ESTABLISHED 상태에서 연결을 종료하기 위해 Server로 FIN(Finishing) 요청을 보낸다. FIN 요청은 Client가 더 이상 Server로 데이터를 전송하지 않을 것임을 알리는 패킷이다.
STEP 2. Server → Client로 응답 패킷 전달 (ACK)
클라이언트가 전송한 FIN 패킷을 잘 받았다는 의미로 서버에서 ACK 응답을 보낸다. 세션이 종료된 것이 아니기 때문에 클라이언트는 여전히 서버로부터 데이터를 받을 수 있다.
STEP 3. Server → Client로 연결 종료 요청 (FIN)
서버에서 남아있는 데이터를 모두 보내고 난 후, 더이상 보낼 데이터가 없다는 의미의 FIN 패킷을 클라이언트에 전송한다.
STEP 4. Client → Server로 응답 패킷 전달 (ACK)
서버로부터 받은 FIN 요청에 대한 잘 받았다는 의미의 ACK 패킷을 보낸다. STEP2에서는 클라이언트가 여전히 데이터를 받을 수 있는 상황이었지만, STEP 4에 의해 세션이 완전히 종료되면서 더 이상 데이터를 받을 수 없게 된다.