'성공과 실패를 결정하는 1%의 네트워크 원리' 책을 바탕으로 정리한 내용입니다.
04. 서버에서 연결을 끊어 소켓을 말소한다
데이터 보내기를 완료했을 때 연결을 끊는다
데이터 송·수신을 종료하는 것은 어플리케이션이 송신해야하는 데이터를 전부 송신 완료했다고 판단했을 때이다.
웹에서 송신을 완료한 측(웹 브라우저)에서 리퀘스트 메시지를 보내고 서버측이 연결 끊기 단계에 들어간다.
프로토콜 스택은 어느 쪽에서 먼저 연결 끊기 단계에 들어가도 좋게 만들어져 있다.
연결을 끊는 단계
서버→클라이언트
- 데이터 보내기를 완료한 쪽(서버)에서 먼저 Socket 라이브러리의 close를 호출
- 서버측의 프로토콜 스택이 TCP 헤더를 만들고 연결끊기를 나타내는 정보를 설정
- IP 담당 부분에 의뢰해 클라이언트에 송신해 달라고 요청
클라이언트→서버
- 서버에서 FIN에 1을 설정한 TCP 헤더가 도착하면 클라이언트 측의 프로토콜 스택은 자신의 소켓에 서버측이 연결 끊기 동작에 들어갔다는 것을 기록
- FIN을 1로 받았다는 것을 알리기 위해 ACK 번호를 서버측에 반송
- 데이터가 올 때까지 기다렸다가 어플리케이션이 read를 호출해 데이터를 가져옴
- 데이터를 건네지 않고 서버에서 보낸 데이터를 전부 수신 완료했다는 사실을 어플리케이션에 알림
- 서버에 보낸 데이터를 전부 수신 완료하면 클라이언트도 종료
- 클라이언트 어플리케이션도 close를 호출해 작업을 끝낸다.
- 클라이언트 측 프로토콜 스택은 FIN 비트에 1을 설정한 TCP 헤더를 만들고 IP 담당 부분에 의뢰해 서버에 송신 후 ACK 번호가 들어오면 서버와의 대화를 끝낸다.
소켓을 말소한다
서버와의 대화가 끝나면 소켓을 사용해 서버와 대화할 수 없게 된다.
바로 말소 하지 않고 오작동을 막기 위해 잠시 기다린다.
데이터 송·수신 동작을 정리한다
접속 동장
- 소켓을 작성하는 단계
: 서버측에서 애플리케이션이 동작하기 시작했을 때 소켓을 만들고 이것을 접속 대기 상태로 만든다.
- 클라이언트 측은 서버에 엑세스 하는 동작을 시작할 때 패킷을 작성
: 패킷을 주고받지는 않는다.
- 접속 동작 실행
: 클라이언트가 SYN을 1로 만든 TCP 헤더를 만들어 서버에 보냄
- TCP 헤더에는 시퀀스 번호의 초기값도 기록
- 데이터 송신에 사용하는 윈도우 값도 기록
- 서버에서 SYN을 1로 만든 헤더를 받음
- 서버에서 다시 ACK 번호와 시퀀스 번호의 초기값, 윈도우, SYN을 1로 한 값을 기록해 클라이언트로 보냄
- 클라이언트는 받은 정보를 ACK 번호를 기록한 TCP 헤더를 서버로 보낸다.
데이터 송·수신 단계
- 클라이언트에서 서버에 리퀘스트 메세지 전송
- TCP는 적당한 크기 조각으로 분할
- TCP 헤더를 앞에 부가해 서버에 전송
- 송신 데이터가 몇 번째 바이트부터 시작되는지 나타내는 시퀀스 번호 기록
- 서버는 ACK 번호를 클라이언트에 반송
- 최초 데이터는 받기만 하지만, 데이터 송·수신 중 애플리케이션에 데이터를 건네 수신 버퍼에 빈 영역이 생기면 윈도우 값도 기록해 클라이언트에 통지
- 서버에서 응답 메세지 반송
연결 끊기 동작
- 서버에서 응답 메세지 보내기를 완료하면 FIN을 1로 만든 TCP 헤더가 흐른다.
- 이것을 받았음을 나타내는 ACK번호의 TCP 헤더가 돌아온다.
- 역방향으로 한번 더 진행 후 소켓이 말소 된다.