7. half-close() 함수 기능/특징, 소켓 연결 종료 ːː tcp / ip ːː

7. half-close() 함수 기능/특징, 소켓 연결 종료


half-close() 함수를 알기 전에 알아야 할 이야기.

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
소켓과 스트림(socket and stream)

소켓을 통해 두 호스트가 연결되면 서로간에 데이터를 송/수신 할 수 있게 된다. 이 상태를 스트림이 생성되었다고 한다.
즉 연결된 상태를 일종의 스트림으로 보고 있는 것이다.

경우에 따라서는 파일 디스크립터나 파일 포인터를 가리켜 스트림이라고 표현하기도 하는데,
스트림이라는 표현은 데이터를 주고받을 수 있도록 연결된 시스템의 내부적 상황을 표현하는 경우에만 사용하기로 하자.

본론으로 돌아와서, 소켓을 통해 연결이 되면 스트림이 생성된다고 볼 수 있고, 소켓은 전 이중 모드 (full-duplex mode)이다.
무슨말인가 하면, 전화라고 생각하면 편하겠다. 전화로 통화할때 두 사람이 한마디씩 주고받을 수 있지만. 하고싶은말만 할 수도 있다.

즉, 동시에 데이터를 전달할 수도, 수신할 수도 있다는것이고.. 이러한 상황이 가능하려면 두 호스트간에 스트림이 하나가 아니라 두개가 있어야 한다. 하나만 있다면 한마디씩 주고 받아야 할것이므로..

이런 식,
따라서, 소켓을 통해 두 호스트가 연결되면, 각 호스트들은 입력스트림과 출력스트림이 생성된다.
물론 한쪽의 출력스트림은 다른쪽의 입력스트림에 연결될 것이고. 필요한 경우에는 하나의 스트림만 종료할 수 있다.

리눅스의 close() 함수나 윈도우즈의 closesocket() 함수는 두가지 스트림을 한번에 종료시킨다.

close() 의 이미지(아래 나오는 half-close 이미지와 구분해서 보자)
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


1] 스트림 half-close() 함수
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include<sys/socket.h>

int shutdown(int s, int how);
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
s : 종료하고자 하는 소켓의 파일 디스크립터를 인자로 전달.
how : 종료 모드를 인자로 전달.
shutdown 함수의 how인자 매크로
상수값 모두 정의
0 SHUT_RD 입력 스트림 종료
1 SHUT_WR 출력 스트림 종료
2 SHUT_RDWR 입/출력 스트림 종료
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

SHUT_RD 모드로 shutdown() 함수를 호출하게 되면, 데이터 전송만 가능한 상태가 되고(입력스트림 종료),
SHUT_WF 모드로 shutdown() 함수를 호출하게 되면, 데이터 수신만 가능한 상태가 된다(출력스트림 종료),
이러한 상태를 half-close 상태라 한다.

half-close 상태의 이미지(위에 나온 half-close 이미지와 구분해서 보자)



half-close 의 필요성
소켓을 반만 닫는다는 것이 무엇인지 이젠 이해를 했다. 
근데 이게 도대체 왜 필요하다는거?? 왜지?? 데이터를 송수신하기에 충분한시간동안 기다렸다 종료하면 되는데 꼭 이래야 하나?

이런 경우를 생각해 보자. 크기가 큰 파일을 하나 전송하는 경우인데,
서버는 계속해서 데이터를 전송하고, 클라이언트는 계속해서 수신해야 한다. 언제까지? ㅋ파일을 전부 다 전송할 때까지 해야 한다.
전송하는 서버입장에서는  파일을 읽다가 파일의 끝에 도달하면 EOF 메시지가 리턴되므로 그때까지만 읽어서 전송하면 된다.
그런데 수신하는 호스트입장에서는 언제까지 수신해야 하는지 막연하다. 무턱대고 데이터수신함수(ex. read())를 호출하면 블로킹 상태에 빠질 수도 있으니께..

이러한 문제를 해결하기 위해 파일을 전송하는 서버는 전송이 끝날때 완료했다는 의미로 EOF 메시지를 마지막으로 전송해야 한다.
이렇게 해주면 수신하는 호스트도 EOF 를 수신할때까지만 데이터 수신함수를 호출하면 된다.

이제 남은 문제는 EOF 를 어떻게 전달할 것인가? 생각보다 간단간단하다. 데이터를 출력하는 출력스트림을 종료해 주면, 상태 호스트로 EOF 가 전송된다. 따라서 출력 스트림을 종료해야만 하는 상황은 자주 발생하게 된다.

물론 close() 함수를 통해 입/출력 스트림을 한꺼번에 종료해줘도 EOF 는 전송되지만, 이럴경우 상대방이 전송해 주는 데이터를 더이상 수신하지 못한다는 거.





공유하기 버튼

싸이월드 공감트위터페이스북
 

1 2 3 4 5 6 7 8 9 10 다음