TCP란
TCP는 메일이나 파일 전송, 웹브라우저 등 데이터를 전송의 신뢰성을 요구하는 애플리케이션에 사용한다. TCP는 애플리케이션 데이터를 송싱하기 전에 TCP 커넥션(TCP Connection)이라는 논리적인 통신로를 만들어 통신 환경을 전비한다. TCP 커넥션은 각각의 단말에서 볼 때, 송신 전용으로 사용하는 송신 파이프와 수신 전용으로 사용하는 수신 파이프로 구성된다. TCP는 송신 측 단말과 수신 측 단말이 2개의 논리적인 파이프를 전이중으로 사용해 '보냅니다!', '받았습니다!'라고 확인해 가면서 데이터를 보내기 때문에 신뢰성이 향상된다.
3웨이 핸드셰이크 (3 way handshake)란
TCP 커넥션은 3웨이 핸드셰이크(3 way handshake)로 커넥션을 여는 것에서 시작한다. 3웨이 핸드셰이크는 커넥션을 확립하기 전에 인사를 수행하는 절차이다.
클라이언트와 서버는 3웨이 핸드셰이크 과정에서 서로 지원하는 기능이나 시퀀스 번호를 결정하고 오픈(open)이라 부르는 준비 작업을 수행한다. 이 3웨이 핸드셰이크에 의한 오픈 처리에서, 커넥션을 만들어 가는 측(클라이언트)의 처리를 액티브 오픈(active open), 커넥션을 맞는 측(서버)의 처리를 패시브 오픈(passive open)이라 부른다.
3웨이 핸드셰이크의 흐름
1. 3웨이 핸드셰이크를 시작하기 전 클라이언트는 CLOSED, 서버는 LISTEN 상태이다. CLOSED는 커넥션이 완전히 닫혀 있는 상태, 다시 말해, 아무것도 하지 않는 상태이다. LISTEN은 클라이언트로부터의 커넥션을 기다리는 상태이다. 예를 들면, 웹브라우저(웹클라이언트)로부터 웹서버에 대해 HTTP로 액세스하는 경우, 웹브라우저는 웹서버에 액세스하지 않는 한 CLOSED이다. 그에 비해, 웹서버는 기본으로 80번 포트를 LISTEN으로 하고, 커넥션을 받아들일 수 있도록 한다.
2. 클라이언트는 SYN 플래그를 '1', 시퀀스 번호에 무작위값(x)를 설정한 후 SYN 패킷을 송신하고, 오픈 처리에 들어간다. 이 처리에 따라 클라이언트는 SYN-SENT 상태로 이동하고, 계속해서 SYN/ACK 패킷을 기다린다.
3. SYN 패킷을 받아들인 서버는 패시브 오픈 처리에 들어간다. SYN 플래그와 ACK 플래그를 '1'로 설정한 SYN/ACK 패킷을 반환하고 SYN-RECEIVED 상태로 이동한다. 또한, 이때의 시퀀스 번호는 무작위(y), 확인 응답 번호는 SYN 패킷의 시퀀스 번호에 '1'을 더한 값(x + 1)이 된다.
4. SYN/ACK 패킷을 받아들인 클라이언트는 ACK 플래그를 '1'로 설정한 ACK 패킷을 반환하고, ESTABLISHED 상태로 이동한다. ESTABLISHED는 커넥션이 완료된 상태이다. 이 상태가 되면 처음으로 실제 애플리케이션 데이터를 송수신할 수 있게 된다.
5. ACK 패킷을 받아들인 서버는 ESTABLISHSED 상태로 이동한다. 이 상태가 되면 처음으로 실제 애플리케이션 데이터를 송수신할 수 있게 된다. 이제까지의 시퀀스 번호와 확인 응답 번호의 교환에 따라, 애플리케이션 데이터의 최초에 부여된 시퀀스 번호가 각각 확정한다.
* ACK란 Acknowledgment(승인)의 약자로 요청을 확인했다는 응답을 뜻한다.
* SYN이란 Synchronize(동시에 발생하다) Sequence Number의 약자이다. 연결이 이루어지도록 요청하는 의미이다.
출처 - https://velog.io/@leeesangheee/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC.-TCP-3-way-Handshake
4웨이 핸드셰이크(4 way handshake)
애플리케이션 데이터의 교환을 마치면 커넥션 종료 처리에 들어간다. 커넥션 종료 처리에 실패하면 불필요한 커넥션이 단말에 남아, 단말의 리소스가 부족해지게 된다. 그래서 커넥션 종료 처리는 오픈 처리보다 분명하고도 신중하게 진행하게 된다.
TCP는 3웨이 핸드셰이크에서 시작해, 4웨이 핸드셰이크로 완료한다. 4웨이 핸드셰이크(4 way handshake)는 커넥션을 종료하기 위한 처리 순서를 의미한다. 클라이언트와 서버는 4웨이 핸드셰이크 중 FIN 패킷(FIN 플래그가 '1'인 TCP 세그먼트)을 서로 교환하고 클로즈(CLOSE)라 부르는 정리를 수행한다. FIN 플래그는 '더이상 교환할 데이터가 없습니다'를 의미하는 플래그로, 상위 애플리케이션의 동작에 맞춘 형태로 부여된다.
커넥션 오픈은 반드시 클라이언트의 SYN으로부터 시작된다. 그에 반해 클로즈는 클라이언트, 서버 어느 쪽에서 FIN을 보내면서 시작한다고 명확하게 정의되어 있지 않다. 클라이언트, 서버의 역할에 관계없이, 먼저 FIN을 송출해서 커넥션을 종료하려는 측의 처리를 액티브 클로즈(active close), 그것을 받는 측의 처리를 패시브 클로즈(passive close)라 부른다.
4 웨이 핸드셰이크의 흐름
1. 클라이언트는 예정한 애플리케이션 데이터의 교환을 마치고, 애플리케이션으로부터 클로즈 처리 요구가 들어오면 액티브 클로즈 처리를 시작한다. FIN 플래그와 ACK 플래그를 '1'로 한 FIN/ACK 패킷을 송신한다. 그리고 이와 함께 서버로부터의 FIN/ACL 패킷을 가진 FIN-WAIT1 상태로 이동한다.
2. FIN/ACK 패킷을 받은 서버는 패시브 클로즈 서브를 시작한다. FIN/ACK 패킷에 대한 ACK 패킷을 송신하고, 애플리케이션에 대해 클로즈 처리를 의뢰한다. 그리고 이와 함께, 애플리케이션으로부터의 클로즈 요청을 기다리는 CLOSE-WAIT 상태로 이동한다.
3. ACK를 받은 클라이언트는 서버로부터의 FIN/ACK 패킷을 기다리는 FIN-WAIT2 상태로 이동한다.
4. 서버는 애플리케이션으로부터 클로즈 처리 요청이 있으면 FIN/ACK 패킷을 송신하고 자신이 송신한 FIN/ACK 패킷에 대한 ACK 패킷, 다시 말해, 클로즈 처리에 대한 최후의 ACK를 기다리는 LAST-ACK 단계로 이동한다.
5. 서버로부터 FIN/ACK를 받은 클라이언트는 그에 대한 ACK 패킷을 반송하고 TIME_WAIT 상태로 이동한다. TIME-WAIT는 혹시라도 늦게 도착할지 모를 ACK 패킷을 기다리는, 보험과 같은 상태이다.
6. ACK 패킷을 받은 서버는 CLOSED 상태로 이동하고, 커넥션을 삭제한다. 이와 함께, 이 커넥션이 확보하고 있던 자원을 모두 해제한다. 이것으로 패시브 클로즈는 종료된다.
7. TIME-WAIT에 이동한 클라이언트는 설정된 시간(타임아웃)을 기다리는 CLOSED 상태로 이동해, 커넥션을 삭제한다. 이와 함께 이 커넥션을 위해 확보한 리소스를 해방시킨다. 이것으로 액티브 클로즈는 종료된다.
TCP 빠른 재전송 (Fast Retransmit)
TCP는 ACK 패킷을 통해 패킷 유실을 감지하고, 패킷을 재전송한다.
수신 측 단말이 계기가 되어 재전송 제어가 수행되는 것을 중복 ACK라고 한다. 수신 측 단말은 받은 TCP 세그먼트의 시퀀스 범호가 듬성하면 패킷 유실이 발생했다고 판단해, 확인 응답이 같은 ACK 패킷을 연속해서 송출한다. 이 ACK 패킷을 중복 ACK(duplicate ACK)라 부른다.
송신 측 단말은 일정 수 이상 중복 ACK를 받으면 대상이 되는 TCP 세그먼트를 재전송한다. 중복 ACK를 트리거로 하는 재전송 제어를 Fast Retransmit(빠른 재전송, 고속 재전송)이라 부른다. Fast Retransmit이 발동하는 중복 ACK의 기준값은 OS나 그 버전에 따라 다르다.
혼잡 제어 (Congestion control)
혼잡 제어는 송신 측 단말이 수행하는 흐름양 조정이다. 혼잡(congestion)이란 간단히 말하면 네트워크의 복잡한 상태를 의미한다. 점심시간에 인터넷을 하다 보면 '느리다' 또는 '굼뜨다'라고 느끼는 때가 있을 것이다. 이는 점심시간에 많은 사람이 인터넷을 보면서, 네트워크상에서 패킷이 갑자기 혼잡하게 되기 때문이다. 패킷이 혼잡하게 되면 네트워크 기기가 처리할 수 없게 되거나 회선의 대역 제한이 걸려 패킷이 소실되거나 전송에 시간이 걸리게 된다. 그 결과 '느리다', '굼뜨다' 라고 체감하게 되는 것이다.
TCP는 대량의 송신 패킷에 네트워크가 혼잡하지 않도록 혼잡 제어 알고리즘 (congestion control algorithm)을 이용해 패킷 송신 수를 제어한다. 이 패킷 송신 수를 혼잡 윈도우(congestion window)라 부른다. 혼잡 제어 알고리즘은 혼잡하면 혼잡 윈도우를 줄이고 혼잡하지 않으면 윈도우를 늘린다.
흐름 제어 (Flow control)
흐름 제어는 수신 측 단말이 수행하는 흐름양 조정이다. 수신 측 단말은 *윈도우 크기 필드를 이용해 자신이 받을 수 있는 데이터양을 알린다. 송신 측 단말은 윈도우 크기 이내에는 확인 응답(ACK)을 기다리지 않고 계속 TCP 세그먼트를 보내지만, 그 이상의 데이터는 보내지 않는다. 그렇게 함으로써 수신 측 단말이 받아들이지 못하는 일이 없도록 하면서, 가능한 많은 데이터를 송신한다. 이런 일련의 동작을 슬라이딩 윈도우라고 부른다.
* 윈도우 크기
받은 데이터 크기를 알리기 위한 필드. 아무리 고성능의 단말이라도 한 번에 오류 없이 패킷을 받지 못한다. 그래서 '이만큼은 받을 수 있습니다' 와 같이 확인 응답을 기다리지 않고 받을 수 있는 데이터 크기를 윈도우 크기로 알린다.
참고 자료
[도서] 그림으로 공부하는 TCP/IP 구조