programing

Linux: 소켓에서 타임아웃이 발생한 읽기 또는 recv가 있습니까?

goodsources 2022. 8. 8. 20:08
반응형

Linux: 소켓에서 타임아웃이 발생한 읽기 또는 recv가 있습니까?

타임아웃이 있는 소켓에서 데이터를 읽으려면 어떻게 해야 합니까?알고 있습니다. select, pselect, poll에는 타임아웃필드가 있는데, 이 필드를 사용하면 tcp reno 스택의 "tcp fast-path"가 비활성화됩니다.

루프에서 recv(fd, ..., MSG_DONTWAIT)를 사용하는 방법밖에 없습니다.

setsockopt 함수를 사용하여 수신 조작의 타임 아웃을 설정할 수 있습니다.

소_RCVTIMEO

입력 기능이 완료될 때까지 대기하는 최대 시간을 지정하는 타임아웃 값을 설정합니다.입력 조작의 완료를 대기하는 시간의 제한을 지정하는 초수 및 마이크로초의 타임밸 구조를 받아들입니다.수신 조작이 추가 데이터를 수신하지 않고 이 시간 동안 차단되었을 경우, 데이터가 수신되지 않을 경우 부분 카운트 또는 에러 없음으로 반환됩니다.이 옵션의 기본값은 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·전후 어느쪽이든 할 수 있는 것을 실험으로 확인했습니다.bindLinux 및 OS X의 경우.

여기 타임아웃을 추가할 수 있는 간단한 코드가 있습니다.recv을 사용하여 기능하다pollC:

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()에러가 반환됩니다.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));

창문들

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

반응형