select() 가 return 하면, timeout 값이 남은 시간으로 변경되기 때문에 그냥 쓰다보면 언젠가는 0 이 되기 때문에 호출되는 즉시 리턴되기 때문에 timeout 값을 설정시에 while문안에넣어줘야 timeout시간이 줄어들지 않는다고 하는데??????
int socket_recv_len_timeout(int nSockFd, char *sRecvBuf,int nRecvExpectLen, int nTimeout)
{
int nRestLen = 0;
int nRecvLen = 0;
int nRecvTotalLen = 0;
int nRet = 0;
int nReturnValue = 0;
fd_set fds;
struct timeval tv;
nRestLen = nRecvExpectLen;
/*** set up the file descriptor set ***/
FD_ZERO(&fds);
FD_SET(nSockFd, &fds);
/*** set up the struct timeval for the timeout ***/
tv.tv_sec = nTimeout;
tv.tv_usec = 0;
/*** wait until timeout or data received ***/
while(1) {
/*** set up the struct timeval for the timeout ***/
// tv.tv_sec = nTimeout;
// tv.tv_usec = 0;
nRet = select(nSockFd+1,&fds,NULL,NULL,&tv);
if( nRet == 0 ) { /*** TIMEOUT ***/
fprintf(stderr, "ERROR_SELECT_TIMEOUT nRet[%d]\n", nRet );
nReturnValue = (-2);
break;
}
else if( nRet == -1 ) { /*** ERROR ***/
if( errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) {
continue;
}
else {
fprintf(stderr, "ERROR_SELECT_FAIL nRet[%d] errno[%d][%s]\n", nRet, errno, strerror(errno));
nReturnValue = (-1);
break;
}
}
else { /*** 변경사항 발생 ***/
/*** data must be here, so do a normal recv ***/
nRecvLen = recv(nSockFd, &sRecvBuf[nRecvLen], nRestLen, 0);
if( nRecvLen == 0 ) { /** 상대편의 접속 해제 ***/
fprintf(stderr, "0 returned in recv");
nReturnValue = 0;
break;
}
else if( nRecvLen == -1 ) { /** 에러 **/
if( errno == EAGAIN || errno == EINTR || errno == EWOULDBLOCK) {
continue;
}
else {
fprintf(stderr, "ERROR_RECV_FAIL nRecvLen[%d]\n", nRecvLen );
nReturnValue = (-1);
break;
}
}
else { /** 읽어들인바이트 **/
nRecvTotalLen = nRecvTotalLen + nRecvLen;
nRestLen = nRestLen - nRecvLen;
if( nRestLen == 0 ) {
nReturnValue = nRecvTotalLen;
break;
}
} /* recv > 0 일경우 end */
} /* select > 0 일경우 end */
} /* while문 end */
}