// funguje také po operaci vazby pro WINDOWS
DWORD timeout = timeout_in_seconds * 1000;
setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeout, sizeof timeout);
Pomocí funkce setsockopt můžete nastavit časový limit pro operace příjmu:
SO_RCVTIMEO
Nastavuje hodnotu časového limitu, která určuje maximální dobu, po kterou vstupní funkce čeká na dokončení. Přijímá časovou strukturu s počtem sekund a mikrosekund, které určují limit, jak dlouho se čeká na dokončení vstupní operace. Pokud byla operace příjmu na tuto dobu zablokována bez přijetí dalších dat, vrátí se s částečným počtem nebo chybným nastavením na [EAGAIN] nebo [EWOULDBLOCK], pokud nejsou přijata žádná data. Výchozí hodnota pro tuto možnost je nula, což znamená, že operace příjmu nevyprší. Tato možnost má časovou strukturu. Všimněte si, že ne všechny implementace umožňují tuto možnost nastavit.
// 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);
V systému Windows by to mělo být údajně provedeno před voláním bind
. Experimentem jsem ověřil, že to lze provést před nebo po bind
v systémech Linux a OS X.
Nainstalujte obslužnou rutinu pro SIGALRM
a poté použijte alarm()
nebo ualarm()
před pravidelným blokováním recv()
. Pokud se spustí alarm, recv()
vrátí chybu s errno
nastavte na EINTR
.
Zde je jednoduchý kód pro přidání časového limitu do recv
pomocí poll
v 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;
}