* 상황 : 패킷을 받는 역할을 하는 쓰레드에서 recvfrom 함수 사용중, 종료 시그널을 받으면 프로그램을 종료시키기 위해 쓰레드를 종료하기 위함.
* 문제 : 이때 read, readv, recv, recvfrom, recvmsg 등의 함수는 그냥 사용시 block 된다. 따라서 block을 피하기 위한 time out 이 필요함. -> write 계열도 마찬가지.
* 해결 방법
1. SIGALRM 을 사용하여, read 계열 리턴시 errno == EINTR 인지 확인함. r
2. read 계열의 함수를 select 로 구현함. UNP v1. p.385 참고.
3. 소켓 옵션으로 타임아웃을 설정함. read계열 리턴시 errno == EWOULDBLOCK 으로 확인. UNP v1. p.210
* 아래는 3번 방법으로 구현한 예.
- 소켓 생성시 소켓 옵션을 준다.
struct timeval timeout;
timeout.tv_sec = 1;
timeout.tv_usec = 0;
int optlen = sizeof(timeout);
setsockopt(*sock, SOL_SOCKET, SO_RCVTIMEO, (void*)&timeout, (socklen_t)optlen);
if(bind(*sock, (struct sockaddr*)recv_addr, sizeof(struct sockaddr_in)) == -1) {
return 2;
}
- recv하는 쓰레드에서 errno 로 처리해 준다.
while(1) {
if(g_exit)
break;
msg_len = recvfrom(net_check_sock, msg, MAX_MSG_SIZE, 0, (struct sockaddr*)&client_addr, &client_addr_size);
if(msg_len < 0) {
if(errno == EWOULDBLOCK){
printf("EWOULDBLOCK \n");
continue;
}
else {
printf("[error] recvfrom \n");
}
}
}