본 내용은 “성공과 실패를 결정하는 1%의 네트워크” 를 참고하여 작성하였습니다
보통 데이터 송수신끝나면 연결을 끊게 된다.
이때 프로토콜 스택은 클라이언트나 서버 양쪽다 상관없이 끊을수 있도록 되어 있다.
서버쪽에서 먼저 끊는다고 가정할때 다음과 같은 동작을 수행하게 된다.
서버측
- Soket라이브러리에서 close를 호출
- 프로토클 스택이 TCP헤더를 생성 이때 연결 끊기 정보를 포함한다.
구체적으로는 FIN 비트에 1을 설정하고 이를 송신(IP담당부분에 넘겨줌)
- 이와 동시에 서버측 소켓에 연결 끊기 동작이 들어갔다는 제어정보를 입력함
클라이언트측
- FIN이 1로 설정된 TCP 헤더가 포함된 메세지를 수신한다.
- 클라이언트 측 프로토콜 스택은 자신의 소켓에 서버의 연결동작이 끊기가 됐다는걸 기록함
- 해당 패킷을 받앗다는(FIN 1인) ACK번호가 포함된 TCP 헤더가 포함된 메세지를 송신
- 어플리케이션이 해당 데이터를(서버에서 보낸) read를 호출하여 읽게됨.
- 데이터를 보내는것이 아닌 어플리케이션에 작업완료신호를 보내준다.
즉 단순하게 정리하자면
서버 먼저 종료시
- 서버 FIN송신
- 클라이언트 ACK송신
- 클라이언트 FIN송신
- 서버 ACK송신
클라이언트 먼저 종료시
- 클라이언트 FIN송신
- 서버 ACK송신
- 서버 FIN송신
- 클라이언트 ACK송신
- 위와같은 동작 중, 만약 FIN이 포함된 데이터가 정상적으로 수신이 되지 않았다면????
- ACK번호가 되돌아 오지 않았기 때문에 FIN을 다시 수신해줘야한다.
- 하지만 바로 FIN을 보내고 소켓을 말소하면 문제가 발생하게 된다.
- 따라서 잠시 기다렸다가. 말소하게 된다.
Uploaded by N2T