연결 끊기

Violet_Evgadn·2023년 4월 26일
0

네트워크

목록 보기
13/37

연결 끊기

커넥션 끊기

데이터 송/수신이 완료되었으니 소켓 사이를 연결하고 있던 커넥션을 끊는 단계로 넘어간다.

데이터 송신을 전부 완료했다고 판단한 측에서 먼저 연결 끊기 단계로 들어간다.

예를 들어 웹의 경우 웹 서버에서 클라이언트에게 응답 메시지를 반송 완료하면 데이터 보내기가 완료된다. 즉, 웹 서버에서 메시지가 모두 송신되었음을 먼저 파악하므로 서버 측이 연결 끊기를 시도한다.

(이는 데이터 통신 한 번당 연결 과정을 수행하는 HTTP 1.0일 때 상황이다. HTTP 1.1에서는 Keep-Alive라는 상태가 존재하여 응답 메시지를 반송한 후에도 클라이언트는 계속해서 리퀘스트 메시지를 보낼 수 있으므로 클라이언트 측이 먼저 연결 끊기 단계에 들어갈 수도 있다)

아래 상황에선 웹 서버에서 먼저 연결 끊기 단계에 들어간다고 가정하자.

먼저 서버측의 애플리케이션이 Socket 라이브러리의 close 함수를 호출한다.

서버 측의 프로토콜 스택은 연결 끊기를 나타내기 위하여 컨트롤 비트의 FIN 비트를 1로 설정한 TCP 헤더를 만들어 패킷으로 만든 뒤 클라이언트 측에 송신한다.

동시에 서버 측 소켓에 연결 끊기 동작에 들어갔다는 정보를 기록한다.

클라이언트 측에 FIN 비트가 1로 설정된 패킷이 도착하면 ACK 번호를 서버 측에 반송한다.

이후 애플리케이션이 read 함수를 통해 데이터를 가지러 올 때까지 기다린다.

애플리케이션 측이 read를 호출하면 먼저 수신 버퍼에 남아 있는 데이터를 애플리케이션에 건네준다.

이후 서버에서 보낸 데이터를 전부 수신 완료했다는 동작을 클라이언트측의 애플리케이션(브라우저)에게 알린다.

HTTP 1.0에선 서버에서 보낸 응답 메시지를 수신 완료할 경우 데이터 송/수신이 종료되어야 하므로 브라우저 또한 연결 끊기 동작에 들어가야 한다.

클라이언트 측 애플리케이션도 close를 호출한 뒤 프로토콜 스택에서 컨트롤 비트의 FIN 비트를 1로 설정한 TCP 헤더를 만들어 패킷으로 만든 뒤 서버 측에 송신한다.

이후 서버 측에서 ACK 번호가 돌아오면 서버와의 커넥션이 끊긴다.

소켓 말소

서버와의 대화가 끝나면 소켓은 필요 없어진다.

하지만 연결 끊기를 수행하자마자 소켓을 말소하는 것은 아니고 잠시 기다린 후 소켓을 말소한다.

이는 오동작을 막기 위해서이다.

바로 소켓을 말소할 때 발생하는 오동작의 종류는 많지만 가장 쉬운 경우로 예를 들어보자.

연결 끊기 단계에서 클라이언트가 서버에게 FIN 비트가 1인 패킷을 보냈는데 ACK가 돌아오지 않았다고 가정해 보자.

이때 클라이언트는 패킷이 정상적으로 도착하지 않았다고 판단하여 다시 FIN 비트가 1인 패킷을 서버 측에 보낼 것이다.

하지만 만약 소켓이 필요 없다 판단하여 바로 말소시키면 어떤 일이 벌어질까?

패킷을 다시 보낼 목적지(서버) IP주소와 포트 번호를 알 수 없게 된다.

이는 서버 측에서 FIN 비트가 1인 패킷을 다시 보내야 할 때 더 큰 문제로 다가온다.

클라이언트는 URL과 미리 정해져 있는 포트 번호를 통해 파악하려면 파악할 수는 있지만 서버 측은 소켓을 말소시킬 경우 기존 클라이언트 측 정보를 파악할 길이 없다.

그렇다면 클라이언트 측의 소켓은 만약의 경우에도 정보를 파악할 수 있으니 말소되어도 괜찮을까?

정답은 "아니다"이다.

클라이언트 측의 포트 번호는 미사용 되고 있는 포트 번호 중 프로토콜 스택이 적당히 골라 할당한 값이다.

즉, 새롭게 만들어진 소켓이 말소된 소켓이 활용했던 포트 번호를 사용할 수 있다는 것이다.

이 경우 서버에서는 FIN을 말소되기 전 소켓에 다시 보낼 것이고 해당 포트 번호를 차지하고 있는 소켓은 다른 애플리케이션과 통신하고 있음에도 불구하고 FIN 비트가 도착하였기 때문에 연결 끊기 동작에 들어가 버릴 수 있다.

이런 경우를 방지하기 위하여 소켓을 즉시 말소하지 않고 잠시 기다리는 것이다.

그렇다면 어느 정도의 시간을 기다릴까?

명확한 규정으로 정해져 있지는 않지만 보통 몇 분 정도 기다린 후 소켓을 말소한다.

이 시간은 패킷을 다시 보내는 동작과 관계가 있다.

패킷이 중간에 누락되었을 경우 다시 보내는 동작은 몇 분쯤 계속되며 정해 놓은 시간이 경과되어도 정상적인 응답이 오지 않는다면 회복 전망이 없다 판단하여 다시 보내기 동작을 멈춘다.

반대로 말하자면 이 시간 동안은 회복 가능성이 존재한다는 의미이므로 이 시간 동안 소켓 말소를 기다리는 것이다.

profile
혹시 틀린 내용이 있다면 언제든 말씀해주세요!

0개의 댓글