close() 와 closesocket() 함수의 기능
- socket의 완전 소멸을 의미
- socket이 소멸되므로 더 이상 입출력이 안됨
- 더 이상 입력이 안되므로 상대방 상태에 상관없는 일방적 종료의 형태
- 일방적 종료를 할 경우 상대 host에 송수신이 완료되지 않은 데이터가 있을 때 문제
- 따라서 Half-close 기법을 사용해야 한다.
Half-close
close()나 closesocket()으로 입출력 스트림을 모두 닫는 것이 아니라, 출력 스트림만 닫는 것이다.
상대방도 보낼 데이터가 없어서 종료를 원하는지 모르기때문에 입력 스트림은 열어둔다.
이렇게 입력 스트림이나 출력 스트림 중 하나를 닫는 것을 Half-close라고 한다.
shutdown
#include <sys/socket.h>
int shutdown(int sock, int howto);
첫번째 인자로 half-close 대상 file descriptor를 전달한다.
두번째 인자로 해당 file descriptor의 어떤 stream을 닫을지 결정한다. 아래 상수가 올 수 있다.
- SUHT_RD : 입력 스트림 종료
- SUHT_WR : 출력 스트림 종료
- SUHT_RDWR : 입출력 스트림 종료
성공 시 0, 실패 시 -1을 반환한다.
이렇게 shutdown 함수가 호출되면 상대방에겐 EOF가 간다고 강의 자료에 나와있는데,
종료 요청을 보내는 것이므로, flag로 FIN이 가고 응용계층으로 EOF 데이터가 간다는 의미인듯.
TCP Half-close Example
//server.c
while (1) {
read_cnt = fread((void*)buf, 1, BUF_SIZE, fp);
if (read_cnt < BUF_SIZE) {
write(clnt_sd, buf, read_cnt);
break;
}
write(clnt_sd, buf, BUF_SIZE);
}
shutdown(clnt_sd, SHUT_WR); //출력 스트림만 close
read(clnt_sd, buf, BUF_SIZE);
printf("Message from client: %s\n", buf);
fclose(fp);
clsoe(clnt_sd); //소켓 완전히 종료
close(serv_sd);
//client.c
while((read_cnt = read(sd, buf, BUF_SIZE)) != 0)
fwrite((void*)buf, 1, read_cnt, fp);
puts("Received file data");
write(sd, "Thank you", 10);//server에서 연결 종료 요청 후 client에서 보내는 추가 데이터
fclose(fp);
close(sd);
교수님께 말씀하시길...
내가 안 보낼거라면 상대방이 보낼 데이터가 손실되든 말든 받을 필요도 없는 경우가 많아서,
최근 나온 protocol들은 이런 기능이 없다고 한다.
'수업 > Network Programming' 카테고리의 다른 글
[Network Programming] Socket의 옵션들 (0) | 2023.05.28 |
---|---|
[Network Programming] Domain Name System(DNS) (0) | 2023.05.28 |
[Network Programming] UDP socket 통신 (0) | 2023.05.27 |
[Network Programming] TCP socket 통신 (0) | 2023.05.26 |
[Network Programming] Network Socket Programming 개요/기초 (0) | 2023.05.25 |