본문 바로가기
카테고리 없음

3WAY HANDSKAKE / 3.전송 계층

by 정리1023 2023. 10. 8.

서버가 클라이언트의 연결 요청을 기다리고 있는 상태
클라이언트가 연결요청을 할때 까지 계속 LISTEN상태를 유지

적극적으로 상대방에게 대시하지 않는다는 것인데, 그래서 이 상태를 수동 개방(Passive Open)이라 하고, 수신자를 Passive Opener라고도 한다.


클라이언트가 서버에 연결을 요청하는 단계입니다
클라이언트는 랜덤한 숫자인 시퀀스 번호를 생성해서 SYN 패킷에 담아 보냅니다

예를 들어 시퀀스 넘버를 10이라고 가정하겠습니다

그리고 SYN 패킷을 수신한 클라이언트를 SYN_RECV상태가 됩니다

이때 클라이언트가 통신을 요청하는 상황이므로 이 상태를 능동 개방(Active Open)이라고 하고, 클라이언트를 Active Opener라고도 한다


 

이후 서버는 제대로 된 시퀀스 번호를 받았다는 확인의 의미인 승인 번호(Acknowledgement) 값을 만들어서 다시 요청자에게 돌려줘야한다

이때 승인 번호는 처음 클라이언트가 보낸 시퀀스 번호 + 1이 되고 보내는 시퀀스 번호는 다시 랜덤으로 생성됩니다


클라이언트는 처음 자신이 보낸 시퀀스 번호 10과 서버로 받은 승인번호 11을 확인하여 연결이 제대로 되었음을 확인합니다,

클라이언트는 연결이 잘되었다고 판단하고 ESTABLISHED 상태가 되면서 다시 서버에게 ACK패킷을 전송합니다

이때 서버가 보낸 시퀀스번호에 1을 더해서 승인번호를 보내고 서버로 부터 받은 승인번호를 그대로 시퀀스 번호로 씁니다

클라이언트로 ACK를 받은 서버는 보낸시퀀스 번호와 받은 승인번호가 1만큼 차이나는 것을 확인하고 ESTABLISHED 상태로 들어갑니다

이렇게 3WAY HANDSHAKE 단계가 완료되면 신뢰성있는 연결이 생성되었다고 판단하고 본격적인 통신을 시작할 수 있습니다


TCP는 신뢰성 있는 전송을 보장하기 위한 다양한 기능을 제공합니다. 그 중 하나가 TCP의 재전송 기능입니다.

패킷 전송 중에 오류가 발생했거나, 수신 측에서 ACK패킷을 전송하지 않은 경우 등에 사용됩니다.

이런 상황에서 TCP는 무한정 기다릴 수 없기 때문에 기다릴 시간을 정합니다

그래서 상대방의 응답을 언제까지 기다릴지 제한시간을 두는데 이것을 타임아웃이라고 합니다.

●RTO: Retransmission Timeout 응답이 오지 않을 때 재전송을 하기까지 기다릴 시간
●RTT: RoundTrip Time 요청을 보낸 직후, 응답을 수신하기까지의 시간
●RTT가 RTO보다 크다면 재전송이 일어난다. 기다리는 시간보다 응답 시간이 더 길면 재전송을 하는 것이다. 그러므로 항상 RTT는 RTO보다 작아야 한다.

4Way Handshake는 연결을 해제하는 과정입니다.
여러 단계를 거쳐 연결을 해제하는 이유는 한 쪽에서 일방적으로 연결을 끊어버리면 다른 한 쪽은 연결이 끊어졌는지 알수 있는 방법이 없기 때문입니다
또한 연결을 종료하기 전에 아직 다 처리하지 못한 데이터가 있을 수도 있기 때문입니다먼저 연결을 종료하고자 하는 클라이언트가 FIN 패킷을 상대방에게 보내면서 FIN_WAIT1 상태로 들어서게 된다.
마지막으로 서버에 전송했던 ACK같은 번호



FIN패킷을 받은 서버는 받은 시퀀스번호에 1을 더해 승인번호로 만들어서 다시 클라이언트에 보내고 CLOSE_WAIT 상태가 됩니다.
클라이언트는 승인번호를 받고 자신이 보낸 시퀀스 번호가 1이 차이나는지 확인 후 FIN_WAIT2 상태로 들어갑니다
FIN_WAIT2 단계 에서는 서버가 연결종료를 허락하는 FIN 패킷을 보낼때 까지 대기를 합니다.


CLOSE_WAIT 상태의 서버는 전송할 데이터가 있으면 계속 전송을 하고 모든 전송이 끝났다면 close()나 shutdown()과 같은 함수를 호출하여 다음단계로 넘어 갑니다.
(연결 종료 함수가 명시적으로 호출되지 않으면 다음 상태로 넘어갈 수 없기 때문에 데드락이 발생할 가능성이 있다.)


서버는 클라이언트가 처음에 보낸 종료신호인 FIN패킷에 동의한다는 의미로 클라이언트에세 FIN패킷을 보냅니다.
이때 수신자가 보내는 FIN 패킷에 담기는 시퀀스 넘버는 자신이 이번에 전송해야 하는 데이터의 시퀀스 번호를 그대로 사용하며, 승인 번호는 마지막으로 자신이 응답했던 승인 번호를 그대로 사용한다.
이후 수신자는 LAST_ACK 상태가 되고 클라이언트의 응답을 기다립니다



FIN패킷을 받은 클라이언트는 받은 승인번호에 1을 더해 시퀀스 번호를 생성하여 서버에 ACK패킷으로 응답합니다.
이후 클라이언트는 TIME_WAIT 상태로 들어가며, 실질적인 연결종료 과정이 됩니다. 


TIME_WAIT의 역할은 의도하지 않은 에러로 인해 연결이 데드락에 빠지는 것을 방지하는 것이다.
TIME_WAIT에서 대기하는 시간은 정해져 있는데 이를 2 MSL(Maximum Segement Lifetime)으로 정의
MSL의 시간 값은 커널 파라미터로 정의되어있다.


2MLS가 지난 후 클라이언트는 자동으로 CLOSED상태가 됩니다.
ACK패킷을 받은 서버도 CLOSED 상태로 들어가며 연결을 완전히 종료한다