// funziona anche dopo l'operazione di bind per WINDOWS
DWORD timeout = timeout_in_seconds * 1000;
setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeout, sizeof timeout);
Puoi utilizzare la funzione setsockopt per impostare un timeout sulle operazioni di ricezione:
SO_RCVTIMEO
Imposta il valore di timeout che specifica il tempo massimo di attesa di una funzione di input fino al completamento. Accetta una struttura timeval con il numero di secondi e microsecondi specificando il limite di tempo di attesa per il completamento di un'operazione di input. Se un'operazione di ricezione si è bloccata per così tanto tempo senza ricevere dati aggiuntivi, ritornerà con un conteggio parziale o un errore impostato su [EAGAIN] o [EWOULDBLOCK] se non vengono ricevuti dati. Il valore predefinito per questa opzione è zero, il che indica che un'operazione di ricezione non deve scadere. Questa opzione accetta una struttura timeval. Nota che non tutte le implementazioni consentono l'impostazione di questa opzione.
// 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);
Secondo quanto riferito su Windows, questo dovrebbe essere fatto prima di chiamare bind
. Ho verificato sperimentalmente che può essere fatto prima o dopo bind
su Linux e OS X.
Installa un gestore per SIGALRM
, quindi utilizza alarm()
o ualarm()
prima di un normale blocco recv()
. Se suona l'allarme, il recv()
restituirà un errore con errno
impostato su EINTR
.
Ecco un semplice codice per aggiungere un timeout al tuo recv
funzione usando poll
in Do:
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;
}