※ 연결에 대한 내용이므로 TCP/IP 프로토콜에 대한 이야기.
※ 우아한 종료 = graceful close. (MSDN 참고)
7-1 소켓 연결 종료의 문제점
2개의 가상의 통로가 생성 (각 통로는 단방향)
스트림 : 연결된 상태 (데이터를 주고 받을 수 있도록 연결된 시스템의 내부적인 상황)
입력 스트림 : 데이터 수신을 위한 스트림
출력 스트림 : 데이터 전송을 위한 스트림
※ TCP 소켓은 데이터를 전송하면서 동시에 수신도 가능하다.
소켓 연결 종료의 문제점
1. close, closesocket 함수 호출 : 입력, 출력 스트림 완전 종료
=> 데이터를 송수신 할 수 없다. 데이터가 소멸된다.
2. 일방적인 방식의 완전 종료는 경우에 따라서 문제가 될 수 있다.
7-2 우아한 소켓의 연결 종료
half close : 입력 혹은 출력 스트림 중 하나의 스트림만 종료하는 행위
예시) A 호스트의 출력 스트림만 종료
#include <sys/socket.h>
int shutdown(int s, int how);
리턴 : 성공시 0, 실패시 -1
s : 종료하고자 하는 소켓의 파일 디스크립터
how : 종료 모드를 인자로 전달한다.
상수값 | 모드 | 정의 |
0 | SHUT_RD | 입력 스트림 종료 |
1 | SHUT_WR | 출력 스트림 종료 |
2 | SHUT_RDWR | 입출력 스트림 종료 |
출력 스트림의 종료의 필요성
※ Thank you를 받기 위해 shutdown함수를 사용한다.
1. 출력 스트림을 종료하게 되면, 연결되어 있던 호스트로 EOF 메세지 전달.
※ 출력 스트림을 종료하는 방법 : close(closesocket), shutdown 함수.
2. EOF 전송으로 데이터 전송의 끝을 알려 줄 수 있다.
3. EOF 전송 시, 상대 호스트의 데이터 수신 함수(read, recv)는 0을 리턴.
※ EOF를 생략하고 보내면 서버도 read() 무한 대기, 클라이언트도 파일의 끝을 모르므로 read() 무한대기.
※ EOF의 값 : -1 (int type) -> 1바이트를 4바이트로 casting하면 -1이 아닐 수 있다.
7-3. 윈도우즈 기반으로 구현하기
※ 윈도우즈 기반에서는 파일 열기를 위해 표준 라이브러리를 사용하였다.
#include <winsock2.h>
int shutdown(SOCKET s, int how);
리턴 : 성공시 0, 실패시 SOCKET_ERROR
s : 종료하고자 하는 소켓의 파일 디스크립터
how : 종료 모드를 인자로 전달한다.
상수값 | 모드 | 정의 |
0 | SD_RECEIVE | 입력 스트림 종료 |
1 | SD_SEND | 출력 스트림 종료 |
2 | SD_BOTH | 입출력 스트림 종료 |