// fonctionne également après l'opération de liaison pour WINDOWS
DWORD timeout = timeout_in_seconds * 1000;
setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeout, sizeof timeout);
Vous pouvez utiliser la fonction setsockopt pour définir un délai d'attente pour les opérations de réception :
SO_RCVTIMEO
Définit la valeur du délai d'expiration qui spécifie la durée maximale d'attente d'une fonction d'entrée jusqu'à ce qu'elle se termine. Il accepte une structure timeval avec le nombre de secondes et de microsecondes spécifiant la durée maximale d'attente pour qu'une opération d'entrée se termine. Si une opération de réception s'est bloquée pendant ce laps de temps sans recevoir de données supplémentaires, elle doit revenir avec un décompte partiel ou une erreur définie sur [EAGAIN] ou [EWOULDBLOCK] si aucune donnée n'est reçue. La valeur par défaut pour cette option est zéro, ce qui indique qu'une opération de réception ne doit pas expirer. Cette option prend une structure de valeur temporelle. Notez que toutes les implémentations ne permettent pas de définir cette option.
// 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);
Apparemment, sous Windows, cela devrait être fait avant d'appeler bind
. J'ai vérifié par expérience que cela peut être fait avant ou après bind
sous Linux et OS X.
Installer un gestionnaire pour SIGALRM
, puis utilisez alarm()
ou ualarm()
avant un blocage régulier recv()
. Si l'alarme se déclenche, le recv()
renverra une erreur avec errno
mis à EINTR
.
Voici un code simple pour ajouter un délai d'attente à votre recv
fonction utilisant poll
en 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;
}