CS
  • CS-Study
  • database
    • B-Tree와 B+Tree
    • DB JOIN
    • DB Lock
    • DB 트래픽
    • DBCP (DB Connection Pool)
    • Flyway
    • Message Broker
    • MySQL InnoDB 스토리지 엔진
    • MySQL 엔진 아키텍처
    • RDB와 NoSQL
    • Redis
    • SQL Injection
    • 스키마 (Schema)
    • Table Scan과 Index Scan
    • Apache Kafka
    • Key
    • 뷰 (View)
    • 인덱스
    • 정규화
    • RDBMS, NoSQL의 클러스터링/리플리케이션 방식
    • 트랜잭션(Transaction)
    • 트랜잭션의 격리성(Transaction Isolation)
    • 프로시저와 트리거
    • DB 정규화 (Normalization)
  • etc
    • MSA
    • REST, REST API, RESTful
    • SOLID 원칙
    • TDD (Test-Driven Development)
    • 서버리스
    • 컨테이너와 도커
  • java
    • Collections
    • Garbage Collection
    • Generic
    • JDBC
    • Java Virtual Machine(JVM)
    • Java Thread
    • Java8 vs Java11 vs Java17
    • 객체지향 프로그래밍 OOP (Object Oriented Programing)
    • Optional
    • RxJava(Reactive Programming)
    • 문자열(String & StringBuffer & StringBuilder)
    • Synchronized
    • Virtual Thread
    • Wrapper Class
    • Equals()와 Hashcode()
    • final
    • Jackson 라이브러리
    • 리플렉션(Reflection)
    • static class와 static method
    • 스트림(Stream)과 람다(Lambda)
    • 스프링 프레임워크에서 사용되는 디자인 패턴
    • 예외처리(Exception)
    • Java Annotation
    • 추상클래스와 인터페이스
  • network
    • 3-way handshake
    • 4-way Handshake
    • DHCP(Dynamic Host Configuration Protocol)
    • DMZ(DeMilitarized Zone)
    • DNS(Domain Name System)
    • HTTP Method
    • HTTP 버전 비교
    • HTTP status code
    • HTTP
    • IP Address
    • Mutiplexing & Demultiplexing
    • OSI 7계층
    • SOP, CORS
    • TCP와 UDP
    • XSS와 CSRF
    • gRPC
    • Stateless와 Connectionless
    • 라우터 Router
    • 로드밸런서(Load Balancer)
    • 브라우저에 URL입력시 네트워크 상 일어나는 일
    • 서브넷 마스크, 게이트웨이
    • 웹 소켓과 소켓 통신
    • 쿠키(Cookie)와 세션(Session)
  • operating-system
    • IPC (Inter Process Communication)
    • 인터럽트
    • TLB
    • 스레싱 Thrashing
    • Thread Pool, Fork-Join
    • Thread Safe
    • 프로세스
    • 가상 메모리
    • 데드락 (DeadLock, 교착 상태)
    • 동기/비동기 & 블로킹/논블록킹
    • 동기화(Synchronization)
    • 메모리 할당과 단편화
    • 뮤텍스와 세마포어, 모니터
    • 세그먼테이션과 페이징
    • 운영체제
    • 캐시 메모리
    • Context switching(문맥 교환)
    • 컴파일
    • 파일 시스템
    • 페이지 교체 알고리즘(Page Replacement Algorithm)
    • 프로세서 스케줄링 알고리즘
    • 프로세스 주소 공간
  • spring
    • @Transactional
    • AOP(Aspect-Oriented Programming)
    • DTO, DAO, VO, Entity
    • DispatcherServlet
    • Hibernate, JPA, Spring Data JPA
    • Ioc와 DI
    • JPA 연관관계 맵핑
    • N+1 Problem
    • ORM
    • Persistence Context
    • SQL Mapper vs ORM vs QueryBuilder
    • Servlet Filter와 Spring Interceptor
    • Servlet
    • Spring MVC와 Spring Boot
    • Tomcat
    • WebFlux
Powered by GitBook
On this page
  • 4-way Handshake 과정
  • 연결을 종료할때 4-way-handshake를 해야하는 이유
  • TIME-WAIT
  • Flag
  • Half-Close
  1. network

4-way Handshake

Previous3-way handshakeNextDHCP(Dynamic Host Configuration Protocol)

Last updated 1 year ago

TCP 프로토콜이 3 way handshake를 통해 연결을 수립하였다면 연결 해제는 4 way handshake를 사용한다.

4-way Handshake 과정

[Step1]

  • 클라이언트가 연결 해제 요청 FIN을 서버로 전송한다.

  • 클라이언트 상태: ESTABLISHED -> FIN_WAIT_1

[Step2]

  • 서버는 연결 해제 요청을 승인한다는 의미로 클라이언트에 ACK을 전송한다.

  • 연결 해제 요청에 대한 승인으로, 바로 해제 되는 것이 아닌, CLOSE_WAIT 상태로 진입한 후 연결 해제 준비를 한다.

  • 서버 상태: ESTABLISHED -> CLOSE_WAIT

  • 클라이언트 상태: FIN_WAIT_1 -> FIN_WAIT_2

Close-Wait상태 후 애플리케이션이 종료됬다면 다음 단계로 넘어간다.

[Step3]

  • 서버는 연결 해제 준비가 완료되었다는 FIN을 클라이언트로 전송한다.

  • 서버 상태: CLOSE_WAIT -> LAST_ACK

  • 클라이언트 상태: FIN_WAIT_2 -> TIME_WAIT

[Step4]

  • 클라이언트는 TIME_WAIT 시간 만큼 대기 후 서버로 ACK을 전송함으로써 마침내 연결이 해제된다.대개의 경우 2MSL(maximum segment lifetime - 1분~4분) 동안 TIME_WAIT 상태로 대기한다.

  • 클라이언트는 연결을 해제하겠다는 ACK을 바로 서버로 보내는 대신 2MSL 동안 TIMW_WAIT 상태로 대기함으로써 서버는 아직 도착하지 못한 패킷들을 받을 수 있는 여유 시간이 생긴다.

  • 클라이언트 상태: TIME_WAIT -> CLOSED

  • 서버 상태: LAST_ACK -> CLOSED

연결을 종료할때 4-way-handshake를 해야하는 이유

클라이언트의 데이터 전송이 끝났더라도, 서버에서는 데이터를 전송하고 있을수 있기 때문이다. 클라이언트의 데이터 전송 종료(Step1)에 해당하는 FIN의 응답으로 서버에서 ACK를 보내지만, 서버에서 클라이언트로 보내는 데이터 전송이 끝나면 전송의 종료에 대한 FIN을 보내게된다.

TIME-WAIT

[Step4]에서 서버로부터 ACK를 받은후 바로 Closed가 아닌 Time-Wait하는 이유가 무엇일까?

1. 지연패킷 발생

  • 지연으로 인해 FIN보다 늦게 도착하는 데이터가 있을수 있기 때문에 유실을 방지하고자 TIME-WAIT를 둔다.

  • 지연패킷을 예상못하고 또 다른 연결을 진행했다면 해당 패킷(정말 우연으로 SEQ가 맞다면)으로 에러가 생길수 있다.

2. 원격 종단의 연결 확인 불가

  • 만약 마지막 ACK 유실시(지연 등) 상대방은 LAST_ACK 상태로 연결이 지속되게 된다.

  • 짧은 Time Out으로 새로운 연결을 위해 SYN 패킷 전달시 LAST_ACK 상태의 Passive Close는 RST 를 리턴한다. (RST는 아래 참조)

  • 새로운 연결은 오류를 내며 실패한다.

따라서 반드시 TIME_WAIT이 일정 시간 남아 패킷의 오작동을 막아야 한다. RFC 793 에는 TIME_WAIT을 2 MSL로 규정했다. 여기서 MSL은 maximum segment lifetime의 약자로 IP datagram이 네트워크에 존재할 수 있는 시간이다. TCP를 구현할 때 반드시 MSL값을 정해줘야하는데 RFC1122에 나온 추천은 2분이다. 그렇지만 Berkeley-derived implementation에서는 30초라서 보통 이 2MSL은 1분에서 4분정도 된다.

Flag

TCP 헤더에는 커넥션의 상태를 나타내는 필드가 있다. 9비트로 구성되어 있고 각각의 비트는 의미하는 바가 다르다.(ㅜㄴ)

비트
플래그 이름
설명
개요

1번째 비트

NS

CWR, ECE 필드가 실수나 악의적으로 은폐되는 경우를 막기위한 플래그

2번째 비트

CWR

Congestion Window Reduced

ECN-Echo에 따라, 혼잡 윈도우가 줄어든 것을 알리는 플래그

3번째 비트

ECE

ECN-Echo

혼잡이 발생한 것을 통신 상대에게 알리는 플래그

4번째 비트

URG

Urgent Pointer field significant

긴급을 나타내는 플래그

5번째 비트

ACK

Acknowledgment field significant

확인 응답을 나타내는 플래그

6번째 비트

PSH

Push Function

빠르게 애플리케이션에 데이터를 전달하는 플래그

7번째 비트

RST

Reset the connection

커넥션을 강제로 끊는 플래그

8번째 비트

SYN

Synchronize sequence numbers

커넥션을 여는 플래그

9번째 비트

FIN

No more data from sender

커넥션을 닫는 플래그

이 컨트롤 비트를 사용해 해당 패킷이 ACK, SYN, FIN 인지 확인 할 수 있다.

만약 TCP 커넥션을 4-way Handshake를 할 여유 없이 빨리 종료해야 하는 경우 RST 플래그를 1로 설정하면 된다. RST 플래그가 사용되는 경우는 아래와 같다.

  • 존재하지 않는 TCP 연결에 대해 비SYN 세그먼트가 수신된 경우

  • 열린 커넥션에서 일부 TCP 구현은 잘못된 헤더가 있는 세그먼트가 수신된 경우

  • 일부 구현에서 기존 TCP 연결을 종료해야 하는 경우

  • 원격 호스트에 연결할 수 없고 응답이 중지된 경우

이렇게 갑작스럽게 연결이 해제된 것을 Abrupt connection release 라고 부르고, 양쪽 커넥션이 서로 커넥션을 닫을 때까지 연결되어 있는 정상적인 종료를 Graceful connection release이라고 부른다.

Half-Close

클라이언트-서버가 연결이 되었고, 데이터를 주고받는 상황에서 클라이언트는 언제까지 데이터를 수신해야할까요?

  1. 계속 소켓(TCP연결)을 열어놓는다면? -> 블로킹상태로 에러가 나게될것입니다.

  2. 임의의 시점에 소켓을 닫아버린다면? -> 유실된 데이터로 에러가 발생할것입니다.

이러한 상황을 방지하기 위한 과정인 Half-Close 입니다.

그림과 같이 두 호스트가 연결되고, 데이터의 교환이 가능한 상태를 스트림이 형성된 상태라고 합니다.

스트림은 단방향으로만 형성되기에 데이터를 주고받기 위해서는 두개의 스트림이 필요합니다. 따라서, 두개의 호스트가 연결되면 두개의 스트림이 형성됩니다.

즉, Half-Close는 데이터의 마지막 송신시점에 출력 스트림을 끊어 데이터의 송신이 끝남을 알리는 방법을 의미합니다.

굳이Half-Close를 써야하나요?

무조건적인 방법은 아니지만, 안전한 종료를 위해 필요하다

마지막 송신에 마지막을 의미하는 특정 데이터를 보낼수도 있지만, 스트림을 통해 데이터를 주고받는 과정에서에 바이너리 데이터에 시그널 데이터가 포함되어 문제가 발생할수 있기때문에 Half-Close가 권장된다.


ref

[네트워크] TCP/UDP와 3 -Way Handshake & 4 -Way Handshake
[Network]OSI-7-Layers
CLOSE_WAIT 문제 해결
TIME_WAIT 상태란 무엇인가
TransPort Layer(2)