Linux : 시간 초과가있는 소켓에서 읽기 또는 수신이 있습니까?
시간 초과로 소켓에서 데이터를 읽으려면 어떻게해야합니까? 나는 select, pselect, poll, timeout 필드가 있다는 것을 알고 있지만, 그것들을 사용하면 tcp reno stack에서 "tcp fast-path"가 비활성화됩니다.
내가 가진 유일한 아이디어는 루프에서 recv (fd, ..., MSG_DONTWAIT)를 사용하는 것입니다.
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에서 이전 또는 이후 에 수행 할 수 있음을 확인했습니다.
다음은 C에서 poll을 사용하여 recv 함수에 시간 초과를 추가하는 간단한 코드입니다.
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;
}
// WINDOWS에 대한 바인드 작업 후에도 작동합니다.
DWORD timeout = timeout_in_seconds * 1000;
setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeout, sizeof timeout);
에 대한 처리기를 설치 한 SIGALRM다음 일반 차단 전에 alarm()또는 사용하십시오 . 알람이 울리면은 로 설정된 오류를 반환합니다 .ualarm()recv()recv()errnoEINTR
리눅스
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()적절한 실행을 위해 함수 호출 전에이 설정을 지정했습니다.
참고 URL : https://stackoverflow.com/questions/2876024/linux-is-there-a-read-or-recv-from-socket-with-timeout
'developer tip' 카테고리의 다른 글
| RESTful 서비스-동등한 WSDL (0) | 2020.09.04 |
|---|---|
| Qt의 일반 함수 인 것처럼 emit 사용과 신호 호출 (0) | 2020.09.04 |
| PHPStorm에서 (작업 공간에서) 프로젝트를 제거하는 방법은 무엇입니까? (0) | 2020.09.03 |
| Intellij에서 카멜 케이스와 밑줄 간격 사이를 어떻게 전환합니까? (0) | 2020.09.03 |
| handler.postDelayed () 중지 (0) | 2020.09.03 |