답변:
setsockopt 함수를 사용하여 수신 작업에 대한 시간 제한을 설정할 수 있습니다.
SO_RCVTIMEO
입력 함수가 완료 될 때까지 대기하는 최대 시간을 지정하는 제한 시간 값을 설정합니다. 입력 작업이 완료 될 때까지 대기하는 시간에 대한 제한을 지정하는 초 및 마이크로 초 수로 timeval 구조를 허용합니다. 추가 데이터를받지 않고이 시간 동안 수신 작업이 차단 된 경우 데이터가 수신되지 않으면 [EAGAIN] 또는 [EWOULDBLOCK]으로 설정된 부분 카운트 또는 errno와 함께 반환됩니다. 이 옵션의 기본값은 0이며 수신 작업이 시간 초과되지 않음을 나타냅니다. 이 옵션은 timeval 구조를 취합니다. 모든 구현에서이 옵션을 설정할 수있는 것은 아닙니다.
// LINUX
struct timeval tv;
tv.tv_sec = timeout_in_seconds;
tv.tv_usec = 0;
setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&tv, sizeof tv);
// WINDOWS
DWORD timeout = timeout_in_seconds * 1000;
setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeout, sizeof timeout);
// MAC OS X (identical to Linux)
struct timeval tv;
tv.tv_sec = timeout_in_seconds;
tv.tv_usec = 0;
setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&tv, sizeof tv);
보도에 따르면 Windows에서이 호출하기 전에 수행해야합니다 bind
. 나는 실험을 bind
통해 Linux 및 OS X에서 이전 또는 이후 에 수행 할 수 있음을 확인했습니다.
struct timeval tv;
select ()도 작동하지 않음을 의미합니까? 내 select () 코드를 창으로 포팅하려고 시도했지만 timeval에서 설정하는 값을 무시하는 것처럼 즉시 시간 초과가 발생합니다.
다음 은 C에서 recv
사용 하여 함수에 시간 초과를 추가하는 간단한 코드입니다 poll
.
struct pollfd fd;
int ret;
fd.fd = mySocket; // your socket handler
fd.events = POLLIN;
ret = poll(&fd, 1, 1000); // 1 second for timeout
switch (ret) {
case -1:
// Error
break;
case 0:
// Timeout
break;
default:
recv(mySocket,buf,sizeof(buf), 0); // get your data
break;
}
poll
적어도 한 바이트 또는 타임 아웃을 받기 위해 대기하는 반면, recv
함수를 호출 할 때 sizeof(buf)
바이트 를 기다릴 것입니다. 이 카운트가 아직 도착하지 않은 경우 다시 차단되지만 이번에는 타임 아웃이 없습니다.
에 대한 처리기를 설치 한 SIGALRM
다음 일반 차단 전에 alarm()
또는 사용하십시오 . 알람이 울리면은 로 설정된 오류를 반환합니다 .ualarm()
recv()
recv()
errno
EINTR
리눅스
struct timeval tv;
tv.tv_sec = 30; // 30 Secs Timeout
tv.tv_usec = 0; // Not init'ing this can cause strange errors
setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&tv,sizeof(struct timeval));
WINDOWS
DWORD timeout = SOCKET_READ_TIMEOUT_SEC * 1000;
setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeout, sizeof(timeout));
참고 : bind()
적절한 실행을 위해 함수 호출 전에이 설정을 지정했습니다.