소켓프로그래밍#3 : 핸드셰이킹 (Handshaking)

kkado·2022년 5월 6일
0
post-thumbnail

들어가기 앞서

대학교에서 네트워크 프로그래밍 과목을 수강하면서 전반적인 이해가 많이 부족하다고 느껴 공부한 것을 정리하는 차원에서 가볍게 작성한 글이므로, 내용이 부족하거나 틀린 점이 있을 수 있습니다. 그리고 모든 코드의 작성과 구현은 리눅스 운영체제에서 실행하고 있음을 미리 알려드립니다.
틀린 점 지적이나 첨언은 언제든지 환영합니다!! 잘 부탁드립니다. :D

직전 글에서는 TCP와 UDP의 개념과 차이에 대해서 알아보았다. 이번 글에서는 TCP가 사용하는 핸드셰이킹에 대해 알아보자

Handshaking

핸드셰이킹, 주고받기는 정보기술과 전기통신 및 관련 분야에서 채널에 대한 정상적인 통신이 시작되기 전에 두 개의 실체 간에 확립된 통신 채널의 변수를 동적으로 설정하는 자동화된 협상 과정이다. 채널의 물리적인 확립이 잇따르며, 정상적인 정보 전송 이전에 이루어진다. (위키피디아)

라고 한다... 한마디로 말해 사람들이 처음 만났을 때 악수하듯이, 두 호스트가 서로 연결할 때에 필요한 정보들을 주고받는 일련의 과정들이라고 할 수 있을 것이다.

TCP에서는 연결할 때에 3-way handshaking, 연결을 해제할 때에 4-way handshaking을 사용한다. 핸드셰이킹에 필요한 TCP 세그먼트 내의 플래그(Flag)는 다음과 같다.

  • SYN : Synchronize sequence number, 연결 시작 요청을 의미함
  • ACK : Acknowledgement, 응답 확인을 의미함
  • FIN : Finish, 연결 종료 요청을 의미함

3-Way Handshaking

클라이언트/서버 간의 연결을 수립할 때 사용되는 TCP 3 Way Handshaking의 순서는 다음과 같다.

  1. 클라이언트는 서버에게 접속을 요청한다. (SYN 보냄)
  2. 클라이언트로부터 SYN 요청을 받은 서버는, 클라이언트에게 요청을 수락한다는 SYN/ACK를 보낸다.
  3. 클라이언트가 서버에게 다시 ACK를 보내게 되면, 연결이 이루어진 것이며 실질적인 데이터가 오간다.

State

이 때, 서버와 클라이언트는 신호를 주고 받는 과정 속에서 '상태' 가 변하게 된다.

먼저 클라이언트의 경우 최초에 서버에게 SYN을 보낸 후, 서버로부터 다시 SYN/ACK를 받을 것인데, 받기 전까지 SYN-SENT 상태가 된다.
서버의 입장에서는, 클라이언트로부터 SYN을 받았을 때 SYN-RECEIVED 상태가 된다. 그리고 다시 클라이언트에게 SYN/ACK를 보낸다.

서버로부터 SYN/ACK를 받은 클라이언트는 ESTABLIESHED 상태가 된다. '연결이 수립되었다' 라는 뜻 정도로 받아들이면 될 것이다. 그리고 다시 서버에게 ACK를 보낸다.
그러면 ACK를 받은 서버도 ESTABLIESHED 상태가 된다.

4-Way Handshaking

클라이언트/서버 간의 연결을 해제할 때 사용되는 TCP 4 Way Handshaking의 순서는 다음과 같다.

  1. 클라이언트가 서버에게 종료 요청 FIN 을 보낸다.
  2. 서버가 클라이언트의 종료 요청을 받아들인다. 그리고 그에 대한 응답으로써 ("일단 알겠다") ACK를 보낸다.
  3. 서버는 연결을 종료할 준비가 끝나면 연결을 해제할 준비가 끝났다는 뜻으로 FIN을 클라이언트에게 보낸다.
  4. 클라이언트는 서버로부터 FIN을 받을 것이며, 연결 해제의 준비가 끝났음을 확인했다는 뜻으로 다시 ACK를 보낸다.

State

  1. FIN을 보낸 클라이언트는 FIN_WAIT 상태가 된다.
  2. FIN을 받은 서버가 ACK를 보내고 나서 자신의 통신을 끝낼 때까지 CLOSE_WAIT 상태가 된다.
  3. 연결 해제 준비가 끝난 서버가 클라이언트에게 FIN을 보내고, 이 때 서버는 LAST_ACK 상태가 된다.
  4. 서버로부터 FIN을 받은 클라이언트는 ACK를 보내는데 이 때 TIME_WAIT 상태로 바뀌고, 이 ACK를 받은 서버는 CLOSED 상태가 된다.

서버에서 전송한 패킷이 문제가 발생하여 FIN보다 늦게 도착하는 상황이 발생할 수도 있다.
이 때 FIN을 받은 클라이언트가 ACK를 보낸 직후 통신을 끊어버리면 그 데이터가 유실될 수 있다. 따라서 클라이언트는 서버로부터 FIN을 받은 후 일정 시간(Default : 240초) 동안 세션을 열어 두고, 잉여 패킷이 도착할 수 있도록 한다.

  • 즉 클라이언트는 TIME_WAIT 상태로 일정 시간 기다렸다가 CLOSED 상태로 바뀌게 되는 것이다.
profile
베이비 게임 개발자

0개의 댓글