Linux: czy jest odczyt lub recv z socket z timeoutem?

Jak mogę spróbować odczytać dane z gniazda z timeoutem? Wiem, select, pselect, poll, ma pole timeout, ale ich użycie wyłącza "TCP fast-path" w stosie TCP reno.

Jedyny pomysł jaki mam to użycie recv (fd, ..., MSG_DONTWAIT) w pętli

Author: nivk, 2010-05-20

5 answers

Możesz użyć funkcji setsockopt , aby ustawić limit czasu na odbieranie operacji:

SO_RCVTIMEO

Ustawia wartość timeout, która określa maksymalny czas wejścia funkcja czeka aż się zakończy. Informatyka przyjmuje strukturę timeval z liczba sekund i mikrosekund określanie limitu czasu do poczekaj na operację wejścia do kompletna. Jeśli operacja odbioru ma zablokowany przez tyle czasu bez otrzymując dodatkowe dane, musi return with a partial count or errno Ustaw na [EAGAIN] lub [EWOULDBLOCK] jeśli nie dane są odbierane. Domyślne dla tego opcja jest zerowa, co oznacza, że operacja odbioru nie może zostać przerwana. Ta opcja przyjmuje strukturę timeval. Zauważ, że nie wszystkie implementacje Zezwól na ustawienie tej opcji.

// 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);

Podobno w systemie Windows należy to zrobić przed wywołaniem bind. Eksperymentem zweryfikowałem, że można to zrobić przed lub po bind na Linuksie i OS X.

 160
Author: Robert S. Barnes,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-22 19:29:26

Oto prosty kod do dodania time out do funkcji recv za pomocą poll w C:

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;
}
 15
Author: Abdessamad Doughri,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-15 06:24:09

Zainstaluj obsługę dla SIGALRM, a następnie użyj alarm() lub ualarm() przed zwykłym blokowaniem recv(). Jeśli alarm się włączy, recv() zwróci błąd z errno ustawionym na EINTR.

 0
Author: caf,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-05-21 01:11:51

// działa również po operacji bind dla WINDOWS

DWORD timeout = timeout_in_seconds * 1000;
setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeout, sizeof timeout);
 0
Author: cahit beyaz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-12 11:28:16

LINUX

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));

Uwaga : ustawiono to ustawienie przed wywołaniem funkcji bind() dla prawidłowego uruchomienia

 -4
Author: vivek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-31 05:09:12