에몽이

TCP 3 핸드 쉐이킹 본문

Backend/protocol

TCP 3 핸드 쉐이킹

ian_hodge 2017. 4. 14. 14:16

====================================================================================================== 

[TCP (Transmission Control Protocol) ]

요즈음 네트워크를 사용하는 대부분의 프로그램은 TCP를 사용한다. 많은 응용프로그램들이 TCP를 사용하는 이유는 에러나 손실 없이 데이터를 전송할 수 있기 때문이다. 과연 TCP가 어떻게 데이터를 교환하기에 신뢰할 수 있는 데이터 전송을 보장하는지 알아 보자.

TCP는 데이터를 보내기 전에 세션을 먼저 만든다. 그래서 TCP를 연결지향적인 데이터 교환방식이라고 한다.

 

세션을 맺을 때 필요한 것은 IP 주소와 포트 번호이다. 이 두가지를 가지고 두 대의 컴퓨터는 가상적인 라인을 만들고 데이터를 전송할 때 이 라인을 통해서 데이터를 주고 받게 된다.

 

세션을 맺을 때 데이터를 받는 쪽은 요청을 기다리는 대기(Listen) 상태에 들어가고 보내는 쪽은 특정 컴퓨터의 포트에 연결을 요청하면 비로소 두 대의 컴퓨터의 세션이 만들어진다. 여기서 TCP 3단계 핸드쉐이크(Three Phases Handshake)라는 용어가 등장한다. 다음은 클라이언트의 웹 브라우저가 서버의 웹 서버에서 파일을 요청할 때 세션을 맺는 과정을 보여주는 그림이다.

 


 


 

클라이언트가 서버와 연결을 맺기 위해서 SYN(SYNchronization) 메시지를 보낸다. 서버는 이 메시지에 ACK(SYN ACKnowledgement)로써 응답을 한다. 이와 동시에 서버는 전송 라인을 하나 연다.

서버의 응답에 대해서 클라이언트는 다시 서버가 연결을 하겠다는 메시지를 받았다는 확인 메시지를 보내고 전송 라인을 연다


 


 

위와 같은 방법으로 TCP 프로토콜을 사용해서 연결을 맺게 된다. 아직까지는 TCP 프로토콜이 신뢰할 만한 방법으로 데이터를 보낸다는 것에 대한 내용은 없다.

 

TCP는 데이터를 보낼 때에는 MTU(Maxium Transmission Unit)의 크기에 맞추어서 세그먼트로 데이터를 나눈 다음에 각 세그먼트에 대해서 일련 번호(Sequence Number)를 지정하게 된다. 이 일련 번호는 양자간에 데이터를 주고받을 때마다 받은 데이터 길이만큼 계속 늘어나게 된다.

 

각각의 세그먼트에 일련 번호가 있기 때문에 중간에 하나의 세그먼트가 전달되지 않아도 받는 쪽에서는 중간에 어떤 세그먼트가 누실되었는지 알 수 있다.

각각의 세그먼트를 정상적으로 데이터를 받았을 경우에는 긍정의 응답인 ACK(ACKnowlegements)를 보내고 만약에 ACK를 받지 못했을 경우에는 데이터가 전송되는 전송되는 가운데 데이터가 손상되었다는 것을 의미하며 보내는 쪽에서는 다시 데이터를 전송하게 된다. 

이런 데이터의 신뢰성 때문에 요즈음의 대부분의 어플리케이션은 IP를 기반으로 한 TCP 프로토콜(IP-encapsulated TCP)을 사용한다.

다음은 세션이 만들어진 다음에 클라이언트에서 a.html 파일을 요청하면 서버는 파일을 보내달라는 요청을 받았다는 ACK 메시지를 보낸다.

 

그리고 나서 서버는 파일을 전송하게 되고 클라이언트가 파일을 정확히 받았다면 다시 ACK 메시지를 보내서 파일을 전송받았다고 서버에 알리게 된다.

 

 

TCP 프로토콜은 각 세그먼트를 일련 번호로 해서 데이터를 보내기 때문에 세그먼트가 분실될 위험은 없어졌다. 그러면 세그먼트의 데이터가 정확하다는 것은 어떻게 보장할까?

 

바로 TCP 세그먼트에 대한 체크섬(Checksum)을 가지고 세그먼트가 정상적인 세그먼트라는 것을 확인할 수가 있다. 체크섬은 한 세그먼트에 대한 일종의 요약 정보이다. 클라이언트는 데이터를 전송받았다면 체크섬을 보고 전체 데이터가 확실히 전달되었는지 확인할 수 있게 된다.

 

마지막으로 연결 종료에 대해서 알아보자. 연결 종료는 세션을 연결할 때와 거의 유사한 방법으로 작동하지만 SYN 메시지 대신에 FIN 메시지를 주고 받고, 연결 종료는 어느 쪽이든지 연결을 종료할 수 있다.

TCP 연결은 양방향 통신(Full Duplex)이다. 따라서 연결 종료도 한쪽에서 연결을 종료했다고 해서 연결이 종료된 것이 아니라 양방향 모두 연결을 종료해야 비로소 연결이 종료되었다고 할 수 있다. 

두 개의 종료 중 첫 번째 FIN-ACK를 능동 종료(Active Close)라고 하고, 두 번째 FIN-ACK를 수동 종료(Passive Close)라고 한다. 

두 개의 연결 종료는 항상 동시에 일어나지 않는다. 즉 능동 종료가 일어났다고 바로 수동 종료가 일어나지 않는다는 의미이다. 따라서 TCP 연결은 절반의 종료(Half Close) 상태가 일어날 수 있다.

 

아래 그림을 보면 서버가 먼저 종료 요청 메시지를 보낸다. 이에 대한 응답으로 클라이언트는 종료 메시지에 대한 확인 메시지를 보내고 종료 요청을 서버에 다시 보낸다. 서버가 다시 확인 메시지를 보내면 두 시스템간의 연결을 끊어진다.


 


 

이론에 대해서만 이야기를 하다 보니 약간은 따분했을지도 모르겠다.

 

이제 ethereal를 가지고 실제 패킷을 분석해가면서 '아~ 그런거였구나'라고 느껴 보도록 하자.

 

다음 그림은 웹 브라우저가 서버의 a.html 파일을 요청하고 파일을 받은 후 최종적으로 연결을 끊는 모든 패킷을 ethereal을 통해서 수집한 예이다.

 

먼저 SYN 메시지가 오고 간 후에 세션이 만들어진다. 웹 브라우저는 a.html 파일을 요청하고 서버는 응답을 받았다는 ACK 메시지를 보낸 후 파일을 클라이언트에게 보내준다.

 

이에 클라이언트는 파일을 받았다는 메시지를 서버에게 보낸다. 이후 클라이언트가 연결 종료를 선언하면 서버도 연결 종료를 선언하고 접속은 끊어진다.

 

 


 

다음 그림은 클라이언트가 서버에 접속을 요청하는 첫 번째 패킷을 자세히 본 그림이다.

 

수집된 패킷을 자세히 보면 TCP 프로토콜이 어떻게 데이터를 전송하는지 알 수 있을 것이다. Ethereal로 패킷을 캡쳐할 때의 필터링 옵션은 'tcp port 80 and host 210.219.231.2'로 설정하고 패킷을 캡쳐하였다.

 

일단 보내는 쪽의 주소와 포트는 210.126.11.88:3017이고 받는 쪽은 210.219.231.2:80임을 알 수 있다.

두 번째로 유심히 보아야 할 것은 일련 번호인 3811895347로 설정해서 보내는 것은 앞으로 데이터를 보내면 이 일련 번호로 시작을 해서 데이터를 보내 줄 것을 서버에게 요청을 하는 것이다. 다음으로 SYN 플래그는 Set으로 설정해서 세션 요청에 관련된 메시지라는 것을 알린다.


 


 

80 포트에 귀를 기울이고 있던 서버는 클라이언트의 요청에 ACK 메시지를 클라이언트에 돌려주되 SYN 필드를 Set해서 보내준다.

아래 그림에서 일련 번호가 두 개 보이는 데 첫 번째는 3693590752이고 두 번째는 한번쯤 본 적 있는 3811895348이다.

 

첫 번째는 서버가 앞으로 이 번호 다음에 일련 번호 메시지를 받을 것이니 클라이언트는 3693590752번으로 메시지를 보내달라는 의미이고,

 

두 번째는 3811895348 이전 번호는 받았으나 앞으로 일련 번호 3811895348로 메시지를 보내달라는 의미이다.

 

그러나 일련 번호는 항상 1씩 증가하는 것이 아니라 데이터의 양에 따라서 증가하는 번호수가 달라진다. 데이터 전송이 이루어진 패킷을 보면 일련 번호가 갑자기 커진 것을 알 수 있을 것이다.

 

 


 

클라이언트는 서버의 SYN 메시지에 대해서 다시 알았다는 ACK 플래그를 설정해서 메시지를 돌려 준다.

 

이번에는 일련 번호가 3811895348로 보냈고 서버의 3693590753번 이전 메시지는 다 받았고 이 번호부터 메시지를 받을 준비가 다 되었다고 알려 준다.


출처:http://m.blog.naver.com/dlwocjs1618/90036352490

 

 


 

지금까지 연결에 대한 패킷을 분석해 보았다. 지면 관계상 종료 패킷을 분석하지 못하니 독자 여러분은 반드시 종료 패킷도 분석해 보기 바란다.

 


'Backend > protocol' 카테고리의 다른 글

미디어 파일 포맷의 종류  (0) 2017.04.14
스트리밍(Streaming) 용어 – HLS(Http Live Streaming)  (0) 2017.04.14
tcp/ip,http,웹소켓  (0) 2017.04.14
TCP / UDP 설명  (0) 2017.04.14
스트리밍-HLS 프로토콜  (0) 2017.02.17
Comments