2017년 6월 6일 화요일

TCP 3 Way-Handshake & 4 Way-Handshake

[ 출처 ]

TCP 3-way Handshake ?

TCP는 장치들 사이에 논리적인 접속을 성립(establish)하기 위하여 three-way handshake를 사용한다.

TCP 3 way Handshake는 TCP/IP 프로토콜을 이용해서 통신을 하는 응용프로그램이 데이터를 전송하기 전에 먼저 정확한 전송을 보장하기 위해 상대방 컴퓨터와 사전에 세션을 수립하는 과정을 의미

 Client > Server : TCP SYN
 Server > Client : TCP SYN ACK
 Client > Server : TCP ACK

SYN = 'synchronize sequence numbers' 일련번호 동기화
ACK = 'acknowledgment' 승인


TCP의 3-way Handshaking 역할
 양쪽 모두 데이타를 전송할 준비가 되었다는것을 보장하고, 실제로 데이타 전달이 시작하기전에 한쪽은 다른쪽이 준비되었다는 것을 알 수 있도록 한다.
 양쪽 모두 상대편에 대한 초기 순차일련번호를 얻을 수 있도록 한다.

TCP의 3-way Handshaking 과정


#1. A클라이언트는 B서버에 접속을 요청하는 SYN패킷을 보낸다. 이때 A클라이언트는 SYN을 보내고 SYN/ACK 응답을 기다리는 SYN_SENT 상태가 된다.
#2. B서버는 SYN요청을 받고 A클라이언트에게 요청을 수락한다는 ACK와 SYN flag가 설정된 패킷을 발송하고 A가 다시 ACK으로 응답하기를 기다린다. 이때 B서버는 SYN_RECEIVED상태가 된다.
#3. A클라이언트는 B서버에게 ACK를 보내고 이후로부터는 연결이 이루어지고 데이터가 오가게 되며, 이때 B서버의 상태가 ESTABLISHED이다.


4-way Handshaking
세션을 종료하기 위해 수행되는 절차
[ 참고용 ]

TCP의 4-way Handshaking 과정


#1. 클라이언트가 연결을 종료하겠다는 FIN플래그를 전송한다.
#2. 서버는 일단 확인메시지를 보내고 자신의 통신이 끝날때까지 기다리는데 이 상태가
 TIME_WAIT상태이다.
#3. 서버가 통신이 끝났으면 연결이 종료되었다고 클라이언트에게 FIN플래그를 전송한다.
#4. 클라이언트는 확인했다는 메시지를 보낸다.

 ※ 만약 server에서 FIN을 전송하기 전에 전송한 패킷이 Routing 지연이나 패킷 유실로 인한 재전송 등으로 인해 FIN패킷 보다 늦게 도착하는 상황이 발생될수도 있다. 이러한 현상에 대비하여 Client는 Server로부터 FIN을 수신하였다 하더라도 일정시간(default 240sec) 동안 세션을 남겨놓고 잉여패킷을 기다리는 과정을 거치게 되는데 이 과정을 TIME_WAIT 라고 한다.


TCP상태 전이 다이어그램 [출처]


  1. 먼저 close()를 실행한 클라이언트가 FIN을 보내고 FIN_WAIT1 상태로 대기한다.
  2. 서버는 CLOSE_WAIT으로 바꾸고 응답 ACK를 전달한다. 그와 동시에 해당 포트에 연결되어 있는 어플리케이션에게 close()를 요청한다.
  3. ACK를 받은 클라이언트는 상태를 FIN_WAIT2로 변경한다.
  4. close() 요청을 받은 서버 어플리케이션은 종료 프로세스를 진행하고 FIN을 클라이언트에 보내 LAST_ACK상태로 바꾼다.
  5. FIN을 받은 클라이언트는 ACK를 서버에 다시 전송하고 TIME_WAIT으로 상태를 바꾼다. TIME_WAIT에서 일정 시간이 지나면 CLOSED된다. ACK를 받은 서버도 포트를 CLOSED로 닫는다.
한 가지 주의할 점은 클라이언트와 서버 대신 Active Close와 Passive Close라는 표현을 사용한 것인데, 반드시 서버만 CLOSE_WAIT 상태를 갖는 것은 아니기 때문입니다. 서버가 먼저 종료하겠다고 FIN을 보낼 수 있고, 이런 경우 서버가 FIN_WAIT1 상태가 됩니다. 따라서, 클라이언트와 서버가 아닌 Active Close(또는 Initiator, 기존 클라이언트)와 Passive Close(또는 Receiver, 기존 서버)정도로 표현하는 것이 정확합니다.



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

netstat 상태

상태 
내용 
 LISTEN
요청을 받을 수 있도록 연결 요구를 기다리는 상태
즉, 포트가 열려있음 
WINDOWS에는  LISTENING으로 나타남 
 ESTABLISHED
서로 연결되어있는 상태  ( SYN -> SYN/ACK -> ACK ) 가 완료된 상태 
SVN_SENT
클라이언트가 서버에게 SYN패킷을 보낸 후 연결을 요청한 상태
 SVN_RECV
서버가 클라이언트의 SYN패킷으로 서비스를 요청 받은 후에 이에대한 응답으로 SYN/ACK패킷을 보내고 클라이언트에게 ACK를 받기를 기다리는 상태 
 TIME_WAIT
 연결은 종료되었으나 원격의 우신보장을 위해 기다리고 있는 상태
 CLOSE_WAIT
원격의 연결 요청을 받고 연결이 종료되길 기다리는 상태 
 LAST_ACK
연결이 종료되었고 승인을 기다리는 상태 
 CLOSED
완전히 연결이 종료된 상태  



추가 : 곧바로 close 되는 것이 아니라 time wait 상태를 거치고 일정 시간(1분~4분)동안 유지한다. 
그 이유는 TCP는 신뢰성을 보장해 주기위한 프로토콜로서 연결시에도 종료시에도 복잡한 과정을 거쳐 서로가 CLOSE된 것을 확인하고자 그렇게 만들엇다.  

만일 시스템에 설정된 양보다 많은 CLOSE 요청이 들어온다면 TIME_WAIT하는 세션들이 필요이상으로 많아진다. 
그럴때는 

1. tcp_timewait 수치를 확인하고 변경해준다. 
일반적으로 대량 요청이 발생한다면 10초 정도로 맞춰주는 것이 권장값이다. 


재부팅시에도 이 값을 유지하고 싶다면

/etc/sysctl.conf 에

net.ipv4.tcp_fin_timeout = 10 
을 적어주면 재부팅시에도 timewait 수치 값을 유지할 수 있다. 

2. 재부팅해준다. (강제로 연결을 다 끈어버리는 듯)

찾아본 바에 의하면 2가지 방법이 있는 듯하다. 

댓글 없음:

댓글 쓰기

JavaScript_함수의 역할

◎ 자바스크립트 함수의 역할 ■ 자바스크립트 함수와 메서드는 전혀 다른 개념이다. - 자바스크립트 함수는 메서드 역할을 할 수 있지만, 객체지향 프로그래밍의 메서드는 자바스크립트의 함수 역할을 할 수 없다. - 메서드와는 다르게 ...