> Tech > Traitement d’erreurs avec des timeouts

Traitement d’erreurs avec des timeouts

Tech - Par Renaud ROSSET - Publié le 24 juin 2010
email

Pour ce qui est des erreurs logicielles, presque toutes sont signalisées dans errno. Si vous essayez de vous connecter à un port non associé à une application, le système d’exploitation de cet ordinateur détecte l’anomalie et peut envoyer un message d’erreur à votre ordinateur pour l’en informer. Mais, que se

passe-t-il si le câble du réseau est sectionné ou si le courant est coupé ? Si l’alimentation Internet présente un problème ? Ce genre de défaillances matérielles empêche de recevoir des messages d’erreur explicatifs.

Par conséquent, je vous incite vivement à limiter le temps pendant lequel vous êtes disposé à attendre une réponse d’un autre programme. Ecrivez le code de telle sorte que si aucune donnée ne vient par le socket pendant une longue période, votre logiciel déclenche un timeout et récupère en bon ordre.

Les temporisations peuvent être traitées de deux manières dans la programmation par sockets. La première consiste à demander au système d’exploitation qu’il envoie un signal après un certain laps de temps et la seconde consiste à utiliser l’API select() pour attendre que les données arrivent sur un socket. La méthode du signal me paraît plus simple, donc je la décris dans cet article. L’autre méthode est décrite dans l’article « La temporisation appliquée aux sockets » (iSeries News octobre 2004 ou www.itpro.fr Club abonnés).

Un signal est un message qui peut être envoyé pour interrompre votre programme au milieu de son traitement. Pour utiliser des signaux, définissez une sous-procédure appelée « gestionnaire de signal ». Quand le signal est délivré, votre programme s’arrête et le gestionnaire de signal est exécuté. Quand le gestionnaire a terminé, votre programme reprend son exécution au point d’interruption.

Comme le gestionnaire de signal est une sous-procédure que vous pouvez coder vous-mêmes, vous pouvez écrire le traitement qu’entraînera la réception d’un signal. Mais ce n’est pas utile pour les besoins de cet exemple. L’une des propriétés utiles des API sockets est qu’elles sont interrompues chaque fois qu’un signal est reçu. Par conséquent, tout ce qui est nécessaire pour mettre une API en timeout est d’envoyer un signal au moment opportun.

La figure 9 montre une sous-procédure appelée init_signals() qui configure une sous-procédure appelée got_ alarm() comme gestionnaire de signal pour le signal appelé SIGALRM. Pour cela, elle crée d’abord une structure de données appelée act, de même format que la structure de données sigaction_t que j’ai définie dans le membre SIGNAL_H /copy. Dans cette structure de données, elle définit la sousprocédure got_alarm() comme le gestionnaire de signal et ordonne au système de bloquer tous les signaux pendant que got_alarm() s’exécute (en A, figure 9). Elle appelle ensuite l’API sigaction() et transmet cette structure de données comme un paramètre, ainsi que la constante SIGALRM qui indique quel signal devrait être traité (en B).

Une fois que cette sous-procédure init_signals() a été appelée, tout signal SIGALRM reçu par le job a pour effet de stopper l’action du programme, d’appeler la sous-procédure got_alarm(), puis de continuer là où il s’est interrompu.

Tout cela étant en place, je peux maintenant utiliser le signal SIGALRM pour appliquer le timeout à mes API sockets. La figure 10 montre une sous-procédure appelée tconnect() qui connecte un socket avec un timeout. J’ai donné à tconnect() presque les mêmes paramètres qu’à l’API connect(), donc quand vous serez familiarisés avec l’API connect(), il sera très facile d’appeler tconnect(). Le seul paramètre supplémentaire de tconnect() spécifie le nombre de secondes pendant lequel on essaie de se connecter avant d’abandonner.

L’API alarm() ordonne au système d’exploitation d’envoyer le signal SIGALRM à ce programme après un certain nombre de secondes. Par exemple, si la variable timeout est mise à 10, l’OS envoie un signal SIGALRM après 10 secondes. J’appelle cette API juste avant d’appeler l’API connect (A en figure 10). Si, après le délai de 10 secondes, le programme est encore en train d’attendre que l’API connect() se termine, le signal est reçu et l’API connect() renvoie -1. Quand vous consultez errno, il est à 3407, qui signifie « interrompu par signal ». J’ai aussi une constante nommée dans le copy book ERRNO_H appelée EINTR qui est mise à 3407. Donc, si connect() échoue et si errno=EINTR, cela indique que le timeout a été appliqué à la connexion.

Après avoir appelé connect(), j’appelle l’API alarm() avec un paramètre de 0 (B en figure 10). Si connect() n’a pas eu de time out et s’est terminé avant que SIGALRM soit envoyé au programme, cela l’annule afin que le signal ne soit jamais délivré. De sorte que je ne risque par d’annuler par mégarde une API différente.

Téléchargez cette ressource

Guide de technologie 5G pour l’entreprise

Guide de technologie 5G pour l’entreprise

Pourquoi la 5G est-elle faite pour votre entreprise ? La 5G peut améliorer la vitesse, la fiabilité et la capacité de votre réseau, permettant ainsi une meilleure collaboration, une productivité accrue et une prise de décision plus rapide. Notre livre blanc " The Big Book of Enterprise 5G" vous fournit les informations stratégiques dont vous avez besoin pour prendre des décisions éclairées et préparer votre entreprise à prospérer dans l'ère de la 5G. Cradlepoint, part of Ericsson est le leader mondial des solutions de réseau sans fil 4G LTE et 5G fournies via le cloud. Connectez vos employés, lieux et objets avec la 4G LTE et la 5G pour un WAN sans fil d'entreprise.

Tech - Par Renaud ROSSET - Publié le 24 juin 2010