728x90

일방적인 연결 종료의 문제점

- 소켓도 운영체제가 관리하는 리소스이므로 반환시켜야 함

- 이 소켓을 반환(해제)를 해주는 것이 close(리눅스), closesocket(윈도우)

- 위 함수를 사용하면 소켓이 완전 소멸되어 데이터를 송수신할 수 없음

- 아래 그림처럼 단절이 되는데 상대방의 상태와 상관없이 일방적인 종료의 형태를 보임

- 그럴 경우 다른쪽 호스트의 데이터가 아직 송수신이 완료되지 않은 상태라면 문제가 발생할 수 있음

- 이러한 문제를 방지하기 위해 Half-Close 기법이 존재함

 

Half Close

- 호스트가 상대 호스트에게 더 이상 데이터를 전송하지 않겠다고 알려주는 방법

- 호스트A가 close를 호출하면 호스트 B에게 EOF를 전송

- 호스트A는 데이터를 다 보냈지만 호스트 B는 보낼 데이터가 더 있을 수 있기 때문에 호스트 A에서 B로 보내는 전송 스트림만 끊음

- Half Close를 우아한 종료라고 함

- Half Close를 위해서는 Shutdown 함수를 호출

    -> shutdown 함수를 호출하면 EOF를 전달

    -> sock : 종료할 소켓의 fd, Handle

    -> howto : 종료할 스트림 (SHUT_RD : 입력 스트림, SHUT_WR : 출력 스트림, SHUT_RDWR : 입출력 스트림)

#include <sys/socket.h>

int shutdown(int sock, int howto);
int main(int argc, char *argv[])
{
    ...
    shutdown(clnt_sd, SHUT_WR);			// 출력 스트림 종료
    read(clnt_sd, buf, BUF_SIZE);		// 남은 데이터 read
    printf("Message from client: %s \n", buf);
    
    close(clnt_sd); close(serv_sd);		// 소켓 close
    return 0;
}
int main(int argc, char *argv[])
{
    ...;
    while((read_cnt=read(sd, buf, BUF_SIZE ))!=0) {
        ...;
    } // EOF를 받기전까지 계속 read
    
    puts("Received file data");
    close(sd);
    return 0;
}

 

728x90

+ Recent posts