전체 목록
네트워크Medium#093

TCP 3-way handshake와 4-way handshake를 설명해주세요.

#네트워크#TCP#핸드셰이크#연결

답변 포인트

SYN, SYN-ACK, ACK, FIN 플래그의 역할을 생각해보세요.

정답 및 해설

빠른 요약

3-way handshake (연결 수립): 1. SYN: 클라이언트 → 서버 (연결 요청, seq=x) 2.

TCP(Transmission Control Protocol)는 신뢰성 있는 연결 기반 통신을 보장하는 프로토콜입니다. 연결을 수립할 때 3-way handshake를, 연결을 종료할 때 4-way handshake를 사용합니다. 이 과정을 통해 양측이 데이터 송수신 준비 완료를 상호 확인하고, 모든 데이터가 전송된 후 안전하게 연결을 종료합니다.

TCP 헤더의 제어 플래그

네트워크
TCP  6  () :

SYN (Synchronize):   , 퀀  
ACK (Acknowledge):  , ack    
FIN (Finish):        
RST (Reset):         
PSH (Push):           
URG (Urgent):        

시퀀스 번호(Sequence Number)와 확인 응답 번호(ACK Number)

네트워크
Sequence Number (seq):
-      
-  ( )

Acknowledgment Number (ack):
-     
-  seq + 1 =   ack
- "seq까지 잘 받았으니 seq+1부터 보내줘" 

3-Way Handshake (연결 수립)

전체 흐름

네트워크
                                    
   |                                            |
   |                                          LISTEN
   |                                            |
   |---------- 1. SYN ----------------------->|
   |   seq=x, SYN=1                             |
   |                                         SYN_RCVD
   |                                            |
   |<--------- 2. SYN-ACK -------------------|
   |              seq=y, ack=x+1, SYN=1, ACK=1 |
   |                                            |
   |---------- 3. ACK ----------------------->|
   |   seq=x+1, ack=y+1, ACK=1                 |
   |                                         ESTABLISHED
ESTABLISHED                                     |
   |                                            |
   |===========    =============|

1단계: SYN (클라이언트 → 서버)

네트워크
    .

TCP :
  - SYN = 1
  - seq = x (  퀀 , ISN: Initial Sequence Number)
  - ack = 0 (  seq )

 : SYN_SENT

2단계: SYN-ACK (서버 → 클라이언트)

네트워크
        .

TCP :
  - SYN = 1 (  )
  - ACK = 1 ( SYN  )
  - seq = y (  퀀 , ISN)
  - ack = x + 1 ("x까지 받았으니 x+1번부터 보내줘")

 : SYN_RCVD

3단계: ACK (클라이언트 → 서버)

네트워크
  SYN-ACK    .

TCP :
  - ACK = 1
  - seq = x + 1
  - ack = y + 1 ("y까지 받았으니 y+1번부터 보내줘")

 : ESTABLISHED
 : ESTABLISHED (ACK  )

왜 3번인가? (2번이 부족한 이유)

네트워크
2-way  :

[2-way ]
: "나 연결할 수 있어?" (SYN)
: "응, 나도 연결할 수 있어!" (SYN-ACK)

:    SYN-ACK   !
  SYN  ACK ,       

[3-way ]
1.   : "나 보낼 수 있어?" (SYN)
2.   : "응, 나도 보낼 수 있어. 너도 받을 수 있어?" (SYN-ACK)
3.   : "응, 받을 수 있어!" (ACK)
     !

4-Way Handshake (연결 종료)

전체 흐름

네트워크
                                    
   |                                            |
ESTABLISHED                               ESTABLISHED
   |                                            |
   |---------- 1. FIN ----------------------->|
   |   seq=u, FIN=1                             |
   |                                        CLOSE_WAIT
FIN_WAIT_1                                      |
   |                                            |
   |<--------- 2. ACK ------------------------|
   |              seq=v, ack=u+1, ACK=1        |
   |                                            |
FIN_WAIT_2                           [  ]
   |                                            |
   |<--------- 3. FIN ------------------------|
   |              seq=w, ack=u+1, FIN=1, ACK=1 |
   |                                        LAST_ACK
TIME_WAIT                                       |
   |                                            |
   |---------- 4. ACK ----------------------->|
   |   seq=u+1, ack=w+1, ACK=1                 |
   |                                          CLOSED
   |                                            |
[2MSL  ]
   |
CLOSED

1단계: FIN (클라이언트 → 서버)

네트워크
      .
"나는 데이터 전송을 다 마쳤어"

TCP :
  - FIN = 1, ACK = 1
  - seq = u

 : FIN_WAIT_1
:  FIN        (half-close)

2단계: ACK (서버 → 클라이언트)

네트워크
  FIN  .
"알겠어, 근데 나는 아직 보낼 데이터가 남아있어"

TCP :
  - ACK = 1
  - ack = u + 1

 : CLOSE_WAIT (     )
 : FIN_WAIT_2 ( FIN  )

3단계: FIN (서버 → 클라이언트)

네트워크
       .
"나도 이제 다 보냈어"

TCP :
  - FIN = 1, ACK = 1
  - seq = w

 : LAST_ACK

4단계: ACK (클라이언트 → 서버)

네트워크
  FIN .

TCP :
  - ACK = 1
  - ack = w + 1

 : TIME_WAIT  (2MSL ) CLOSED
 : CLOSED (ACK  )

TIME_WAIT 상태

네트워크
TIME_WAIT:  ACK      

 : 2MSL (Maximum Segment Lifetime,  30~4)
             60~240

TIME_WAIT가 필요한 이유

네트워크
1.  ACK  
   -    ACK    
   -  ACK   FIN 
   - TIME_WAIT   FIN   ACK  

2.   
   -       
   - TIME_WAIT  /IP        
   - 2MSL        

:
: FIN 
: ACK   TIME_WAIT 
: ACK !
: FIN 
: TIME_WAIT  FIN    ACK 

TIME_WAIT 관련 실무 문제

Bash
# 서버에 TIME_WAIT 연결이 많을 경우 확인
netstat -an | grep TIME_WAIT | wc -l

# 포트 재사용 설정 (Linux)
sysctl -w net.ipv4.tcp_tw_reuse=1

# TIME_WAIT 대기 시간 단축 (기본값: 60초)
# /etc/sysctl.conf 에서 설정
net.ipv4.tcp_fin_timeout = 30

비정상 종료: RST

네트워크
4-way handshake     RST  :
-  
-   
-  

RST  :   , TIME_WAIT 

연결 상태 다이어그램

네트워크
: LISTEN  SYN_RCVD  ESTABLISHED  CLOSE_WAIT  LAST_ACK  CLOSED
: CLOSED  SYN_SENT  ESTABLISHED  FIN_WAIT_1  FIN_WAIT_2  TIME_WAIT  CLOSED

정리

구분단계방향플래그설명
3-way (연결)1클라이언트 → 서버SYN연결 요청
3-way (연결)2서버 → 클라이언트SYN+ACK요청 수락 + 역방향 연결 요청
3-way (연결)3클라이언트 → 서버ACK역방향 연결 확인
4-way (종료)1클라이언트 → 서버FIN+ACK종료 요청
4-way (종료)2서버 → 클라이언트ACK종료 확인 (half-close)
4-way (종료)3서버 → 클라이언트FIN+ACK서버 종료 준비 완료
4-way (종료)4클라이언트 → 서버ACK최종 확인 → TIME_WAIT

핵심: 3-way handshake는 양방향 통신 가능 여부를 3단계로 확인하고, 4-way handshake에서 2,3 단계 사이에 서버가 남은 데이터를 전송할 수 있어 4단계가 필요합니다.

관련 질문

같은 카테고리/태그 기준