티스토리 뷰

TCP 통신과정

 

TIME_WAIT소켓에 대해 이야기하기 전에 먼저 TCP의 통신 과정을 살펴봅니다.

위의 그림을 보면 통신을 시작하기 전에 최초의 연결을 맺게 되는 과정을 3-way handshake라고 합니다. 1.클라이언트는 서버로 통신을 시작하겠다는 SYN을 보내고, 2.서버는 그에 대한 응답으로 SYN+ACK를 보냅니다. 3.마지막으로 클라이언트는 서버로부터 받은 패킷에 대한 응답으로 ACK를 보냅니다. 이렇게 3-way-handshake를 정상적으로 마친 다음 클라이언트는 서버에 데이터를 요청합니다. 그림을 보면 HTTP통신일 경우 GET /index.html과 같이 요청하고, 통신을 모두 마친 후에는 연결을 종료합니다. 이 과정을 4-way handshake라고 합니다.

 

연결을 맺을 때는 연결을 맺고자 하는 쪽에서 먼저 SYN를 보내며, 연결을 끊을 때는 연결을 끊으려는 쪽에서 먼저 FIN을 보냅니다. 그림에서 보시는것과 같이 client가 먼저 연결을 끊습니다. server는 ACK를 보내고 사용한 소켓을 정리한 다음 마지막 FIN을 보냅니다. client는 server가 보낸 마지막 ACK를 전송하고 소켓을 정리합니다.

 

그림에서 본 과정이 실제로 어떻게 일어나는 지 tcpdump를 통해서 확인해봅니다.

위의 명령어를 실행시켜 서버끼리 통신하는 패킷을 받습니다.

통신이 완료된 후 와이어샤크를 이용해서 생성된 pcap파일을 엽니다. 위의 그림을 설명하자면, 첫줄: 클라이언트는 목적지 포트 80인 SYN 패킷을 서버로 보냅니다. 두번째줄: 서버는 클라이언트의 패킷에 대한 응답으로 SYN+ACK 패킷을 보냅니다. 셋째줄: 클라이언트는 서버의 패킷에 대한 응답으로 ACK패킷을 보냅니다. 이 과정까지 끝나면 3-way handshake가 끝나고 클라이언트와 서버는 데이터를 주고받을 준비를 끝냅니다. 넷째줄: 클라이언트가 서버로 HTTP GET 요청을 보냅니다.

 

밑에서 다섯번째 줄: 서버는 응답을 주고 연결을 끊기 위해 FIN패킷을 보냅니다. 밑에서 세번째줄: 클라이언트는 서버에서 보낸 패킷에 대한 응답으로 ACK 패킷을 보냅니다. 밑에서 두번재 줄: 클라이언트는 자신이 사용한 소켓을 정리하며 통신을 완전히 끝내도 된다는 의미로 FIN 패킷을 보냅니다. 마지막줄: 서버는 클라이언트 패킷에 대한 응답으로 ACK패킷을 보냅니다.

 

여기까지가 HTTP GET 요청에 대한 실제 덤프 내용입니다. 이제 TIME_WAIT 소켓을 살펴봅니다.

 


 

TIME_WAIT 소켓의 문제점

 

연결을 끊는 과정을 조금 더 자세히 살펴봅니다. 

그림을 보면 active closer와 passive closer가 있는데 단어 그대로 먼저 연결을 끊는 쪽을 active closer라고 하고 그 반대를 passive closer라고 합니다. 누가 먼저 연결을 끊느냐가 중요한 이유는 active closer 쪽에 TIME_WAIT 소켓이 생성되기 때문입니다. 주의해야 할 부분은 TIME_WAIT소켓은 서버에서 생기는 것이 아니고 먼저 연결을 끊는 쪽에서 생성된다는 점입니다. 클라이언트에서도 TIME_WAIT 소켓이 생길 수 있고, 서버에서도 TIME_WAIT소켓이 생길 수 있습니다.

 

 

 

 

반응형