[네트워크] 3way handshake & 4way handshake

할거면제대로·2023년 5월 12일
0

네트워크

목록 보기
1/2
post-thumbnail

TCP 통신 과정

TCP의 통신과정은 3단계의 과정을 거치셔 이루어집니다.

  1. Connection setup (tcp 연결 초기화) - 3way handshake
  2. Data transfer (데이터 전송)
  3. Connection termination (tcp 연결 종료) - 4way handshake

3way handshake


각 단계는 아래와 같은 과정을 의미합니다.

#1 : 제 말 들려요?
#2 : 네 들려요! 제 말도 들리시나요?
#3 : 네 들려요~!

여기서 SYN은 "제 말들려요?"를 의미하고 ACK는 "네 들려요"를 의미합니다.
SYN은 동기화를 나타내는 SYNchronization의 약자이고, ACK는 확인을 나타내는 ACKnowledgement의 약자입니다.

CLOSED (클라이언트, 서버) : 아직 서로 연결을 시도하지 않은 상태, 즉 3way handshake를 하기 전 상태입니다.
LISTEN (서버) : 서버측에서 포트를 열어 연결이 가능한 상태입니다.
SYN-SENT (클라이언트) : SYN을 요청한 상태, 즉 말이 들리는지 물어본 상태입니다.
SYN-RECEIVED (서버) : SYN요청을 받고 SYN+ACK을 보낸 후 상대의 응답을 기다리는 상태, 즉 들린다고 대답한 후 서버의 말도 들리는지 물어본 상태입니다.
ESTABLISHED(클라이언트, 서버) : 연결이 성립된 상태입니다.

이제 더 자세하게 설명해보겠습니다.

1단계 : SYN 전송(제 말 들려요?)
클라이언트는 서버에게 SYN을 보낼 때, 임의의 랜덤숫자와 함께 전송합니다.

2단계 : SYN + ACK 전송(네 들려요(ACK) 제 말은 들리세요?(SYN))
서버는 클라이언트의 SYN을 수신하고 수신했다는 메세지와 함께 클라이언트에게 들리냐는 메시지를 전송합니다. 그 메시지는 ACK를 포함하고 있으며 ACK는 클라이언트에게 받은 SYN보다 1큰 숫자입니다. 이 번호를 전송함으로써 잘들린다는 것을 알려줍니다.

3단계 : ACK 전송(네 저도 들려요)
클라이언트는 서버에게 받은 시퀀스 넘버에 1을 더한 값을 ACK에 담아 다시 서버에게 전송하게 됩니다.

ISN이 0부터 시작하는 것이 아니라 랜덤한 값으로 설정되는 이유?

연결을 맺을 때 사용하는 포트는 유한 범위내에서 사용하고 시간이 지남에 따라 재사용됩니다. 따라서 두 통신(클라이언트/서버)이과거에 사용된 포트 번호 쌍을 사용하는 가능성이 존재합니다. 서버 측에서는 패킷의 SYN을 보고 패킷을 구분하게 되는데 랜덤값이 아닌 순차적인 수가 전송된다면 이전의 연결로부터 오는 패킷으로 인식할 수도 있습니다. 이러한 문제가 발생할 가능성을 줄이기 위해 ISN을 난수로 설정하는 것입니다.

2단계가 아니라 3단계로 이루어져야 하는 이유?

tcp는 양방향성 연결입니다. 그렇기 때문에 양쪽에서 서로 존재를 알리고 패킷을 받을 수 있다는 것을 증명해야합니다.
만약 2단계로 이루어진다면 클라이언트 측에서 "내 말 들려?"라고 신호를 보내고 서버 측에서 "응 너 말 들려, 내말은 들리니?"로 끝나게 돼서 서버측에서는 서버의 목소리가 클라이언트에게 들리는지 확인을 할 수 없습니다. 그래서 클라이언트는 다시 "응 너 목소리 들린다!" 라고 신호를 보내는 것입니다.

4way handshake


각 단계는 아래와 같은 과정을 의미합니다.

1단계(클라이언트) : 연결 이제 끊을래요
2단계(서버) : 네 알겠습니다. 그래도 보내던 건 마저 다 보낼게요
3단계(서버) : 이제 다 전송했어요 연결 끊을게요
4단계(클라이언트) : 네 알겠습니다. 보내주신건 다받고 저도 끊겠습니다.

ESTABLISHED (클라이언트, 서버) : 연결 수립이 완료된 상태로 서로 데이터를 교환할 수 있습니다.
FIN_WAIT_1 (클라이언트) : 자신이 보낸 FIN에 대한 ACK를 기다리는 상태입니다.
CLOSE_WAIT (서버) : 상대방의 FIN(종료 요청)을 받은 상태. FIN에 대한 ACK를 보내고 클라이언트의 종료를 알립니다.
FIN_WAIT_2 (클라이언트) : 자신이 보낸 FIN에 대한 ACK를 받았고 상대방의 FIN을 기다리는 상태입니다.
LAST_ACK (서버) : CLOSE-WAIT 상태를 처리 후 자신의 FIN 요청을 보낸 후 FIN에 대한 ACK를 기다리는 상태입니다.
TIME_WAIT (클라이언트) : 클라이언트는 아직 서버로부터 받지 못한 데이터가 있을 것을 대비하여 일정 시간 세션을 남겨 놓고 기다리는 상태입니다.
CLOSED (클라이언트, 서버) : 연결 종료

이제 더 자세히 설명해보겠습니다.
1단계 : FIN 전송(연결 이제 끊을래요)
클라이언트가 연결을 종료하겠다는 FIN플래그를 전송합니다. 전송 후에 FIN_WAIT_1 상태가 됩니다.
2단계 : FIN 플래그를 받은 서버는 확인메세지인 ACK를 클라이언트에게 전해줍니다. 그 후 CLOSE_WAIT 상태가 되고, 클라이언트도 서버에서 종료될 준비가 됐다는 FIN을 받기 위해 FIN_WAIT_2 상태가 됩니다.
3단계 : 보낼 데이터를 마저 다 보내고 서버는 CLOSE준비를 한 후 FIN 플래그를 클라이언트에게 전송합니다.
4단계 : 클라이언트 TIME_WAIT 상태에서 받아야 하는 데이터를 마저 받고 연결 해지 준비가 완료되었다는 응답으로 ACK를 서버에 보내주고 연결을 종료합니다.

TCP 연결 수립 과정과 연결 종료 과정의 단계가 차이가 나는 이유?

연결 종료 과정이 한 단계 더 많은 이유는 클라이언트가 데이터 전송을 모두 마쳤다고 하더라도 서버에서 아직 보낼 데이터가 남아 있을 수 있기 때문에 연결 끊겠다는 메세지를 확인만 하고, 남은 데이터 전송을 끝마친 후에 서버도 FIN 메세지를 보내기 때문입니다.

TIME_WAIT가 왜 필요할까?

서버에서 FIN 플래그를 전송하기 전에 전송한 패킷이 라우팅 지연이나 패킷 유실로 인한 재전송 등으로 FIN 패킷보다 늦게 도착하는 상황을 막기 위해서 필요합니다.

참고

https://hyemsinabro.tistory.com/157
https://blog.naver.com/PostView.nhn?isHttpsRedirect=true&blogId=luexr&logNo=221948546623&categoryNo=0&parentCategoryNo=0
https://unordinarydays.tistory.com/172
https://hyemsinabro.tistory.com/158
https://jeongkyun-it.tistory.com/180

0개의 댓글