Half-Close - shutdown()

b4failrise ㅣ 2018. 10. 5. 14:25

일방적인 연결 종료-close() 의 문제점

close  호출 후

- read buffer는 close와 동시에 모두 없어짐

- write buffer는 안의 내용을 모두 내보낸 다음에 파일의 마지막을 의미하는 'EOF'를 전송 후 스트림이 종료된다. 

※ EOF가 스트림 종료가 아닌 정확히는 파일의 마지막을 의미한다. 데이터를 전송하고, close하게 되면 언젠가 출력스트림의 내용이 모두 빠져나가고 파일의 마지막을 의미하는 'EOF'가 보내지게 된다.

BUF_SIZE만큼 (지속적으로) 전송하고 마지막 write은 BUF_SIZE을 못 채울 수도 있지만 마지막 BUF_SIZE에 대한 read의 block은 해제된다.

또한 EOF가 온 경우에도 read는 해제된다. 따라서 이 둘을 구분하기 위해 read의 return 값이 0일때와 0이 아닐 때를 구분하여 EOF(이때 read의 return값은 0, error일 경우 -1 반환)가 올 때, 모든 write(전송)을 마쳤음을 인식하도록 한다.


- close를 호출한 측에서 buffer를 닫게되고, EOF를 통해 상대에게 출력 스트림을 닫았음을 알리게 된다. 

- close는 소켓의 완전 소멸을 의미한다.

- close를 통해 read / write buffer를 모두 닫게 되면  외부로부터의 데이터는 차단되게 된다. <-- 문제점

메시지를 지속적으로 받거나 두 개의 패킷으로 나눠서 오는 경우는 다른 문제 --> read를 while로 구현


cf) 일반 file descriptor 와 socket file descriptor 는 구분하지 않는다.







half-close

- 이러한 일방적인 연결 종료의 문제점으로 인해 하나의 스트림을 유지시켜놓을 필요성이 있다.

- 종료를 원하다는 것은, 더이상 전송할 데이터가 존재하지 않는 상황

- 다만 송신측에서 상대방도 종료를 원하는 지 확인되지 않은 상황이므로, 입력 스트림은 종료시키지 않을 필요가 있다.

- 때문에 일반적으로 Half-close라 하면, 입력 스트림을 유지한 채, 출력 스트림만 종료하는 것을 의미한다.

- 이 때 shutdown()을 사용한다.

- 데이터를 모두 보내고, 출력스트림(shutdown())을 종료할 경우, 파일 출력 마지막에 EOF를 전송하여 출력스트림을 닫았음을 의도적으로 알릴 수 있다. 

※EOF가 반드시 스트림 종료를 의미하는 것이 아니다. 송신측이 close()나 shutdown()을 호출하지 않으면 어느 스트림도 닫히지 않는다.

- 수신측에선 어차피 상대가 출력스트림을 닫았으므로 출력스트림과 입력스트림 모두 닫기위해 close를 호출한다.

- 송신측에서 EOF를 받게되면 나머지 입력스트림에 대한 half-close를 해준다. * close 또는 shutdown(sd,SHUT_RDWR)해도 무방




shutdown(sock fd, int howto)

성공 시 0, 실패 시 -1반환




close는 아예 연결을 끊는 것

close 호출되면 상대방에게 EOF가 날라감.

EOF가 데이터 전송이 끝났다는 의미.

shutdown에서도 똑같이 EOF를 날려서 한쪽 스트림을 닫을 수 있다.


EOF를 보내고 잘 받았는지 확인하기 위해 상대는 Thank you 메시지를 보내준다.


이번 실습은 서버와 클라이언트 다른 디렉토리 상황에서 실시해보기 175 176

성공하면 receive.dat가 클라이언트 디렉토리에 생성됨

-thank you 확인

-close 로 바꾸고 에러확인


'CS & IT실무' 카테고리의 다른 글

IO 멀티플렉싱  (0) 2018.11.13
네트워크 바이트 순서와 인터넷 주소 변환  (0) 2018.10.04
소켓에 할당되는 IP주소와 PORT번호  (0) 2018.10.04