대학교에서 네트워크 프로그래밍 과목을 수강하면서 전반적인 이해가 많이 부족하다고 느껴 공부한 것을 정리하는 차원에서 가볍게 작성한 글이므로, 내용이 부족하거나 틀린 점이 있을 수 있습니다. 그리고 모든 코드의 작성과 구현은 리눅스 운영체제에서 실행하고 있음을 미리 알려드립니다.
틀린 점 지적이나 첨언은 언제든지 환영합니다!! 잘 부탁드립니다. :D
직전 글에서는 TCP와 UDP의 개념과 차이에 대해서 알아보았다. 이번 글에서는 TCP가 사용하는 핸드셰이킹에 대해 알아보자
핸드셰이킹, 주고받기는 정보기술과 전기통신 및 관련 분야에서 채널에 대한 정상적인 통신이 시작되기 전에 두 개의 실체 간에 확립된 통신 채널의 변수를 동적으로 설정하는 자동화된 협상 과정이다. 채널의 물리적인 확립이 잇따르며, 정상적인 정보 전송 이전에 이루어진다. (위키피디아)
라고 한다... 한마디로 말해 사람들이 처음 만났을 때 악수하듯이, 두 호스트가 서로 연결할 때에 필요한 정보들을 주고받는 일련의 과정들이라고 할 수 있을 것이다.
TCP에서는 연결할 때에 3-way handshaking, 연결을 해제할 때에 4-way handshaking을 사용한다. 핸드셰이킹에 필요한 TCP 세그먼트 내의 플래그(Flag)는 다음과 같다.
SYN
: Synchronize sequence number, 연결 시작 요청을 의미함ACK
: Acknowledgement, 응답 확인을 의미함FIN
: Finish, 연결 종료 요청을 의미함클라이언트/서버 간의 연결을 수립할 때 사용되는 TCP 3 Way Handshaking의 순서는 다음과 같다.
SYN
요청을 받은 서버는, 클라이언트에게 요청을 수락한다는 SYN/ACK
를 보낸다.ACK
를 보내게 되면, 연결이 이루어진 것이며 실질적인 데이터가 오간다.이 때, 서버와 클라이언트는 신호를 주고 받는 과정 속에서 '상태' 가 변하게 된다.
먼저 클라이언트의 경우 최초에 서버에게 SYN
을 보낸 후, 서버로부터 다시 SYN/ACK
를 받을 것인데, 받기 전까지 SYN-SENT
상태가 된다.
서버의 입장에서는, 클라이언트로부터 SYN
을 받았을 때 SYN-RECEIVED
상태가 된다. 그리고 다시 클라이언트에게 SYN/ACK
를 보낸다.
서버로부터 SYN/ACK
를 받은 클라이언트는 ESTABLIESHED
상태가 된다. '연결이 수립되었다' 라는 뜻 정도로 받아들이면 될 것이다. 그리고 다시 서버에게 ACK
를 보낸다.
그러면 ACK
를 받은 서버도 ESTABLIESHED
상태가 된다.
클라이언트/서버 간의 연결을 해제할 때 사용되는 TCP 4 Way Handshaking의 순서는 다음과 같다.
FIN
을 보낸다.ACK
를 보낸다.FIN
을 클라이언트에게 보낸다.FIN
을 받을 것이며, 연결 해제의 준비가 끝났음을 확인했다는 뜻으로 다시 ACK
를 보낸다.FIN
을 보낸 클라이언트는 FIN_WAIT
상태가 된다.FIN
을 받은 서버가 ACK
를 보내고 나서 자신의 통신을 끝낼 때까지 CLOSE_WAIT
상태가 된다.FIN
을 보내고, 이 때 서버는 LAST_ACK
상태가 된다. FIN
을 받은 클라이언트는 ACK
를 보내는데 이 때 TIME_WAIT
상태로 바뀌고, 이 ACK
를 받은 서버는 CLOSED
상태가 된다.서버에서 전송한 패킷이 문제가 발생하여 FIN보다 늦게 도착하는 상황이 발생할 수도 있다.
이 때FIN
을 받은 클라이언트가ACK
를 보낸 직후 통신을 끊어버리면 그 데이터가 유실될 수 있다. 따라서 클라이언트는 서버로부터FIN
을 받은 후 일정 시간(Default : 240초) 동안 세션을 열어 두고, 잉여 패킷이 도착할 수 있도록 한다.
- 즉 클라이언트는
TIME_WAIT
상태로 일정 시간 기다렸다가CLOSED
상태로 바뀌게 되는 것이다.