Test d’une prise fermée

J’essaie de tester un socket fermé qui a été gracieusement fermé par l’homologue sans encourir la latence d’un double envoi pour induire un SIGPIPE .

L’une des hypothèses est que le socket, s’il est fermé, a été gracieusement fermé par l’homologue immédiatement après sa dernière écriture / envoi. Les erreurs réelles comme une fermeture prématurée sont traitées ailleurs dans le code.

Si le socket est toujours ouvert, il y aura 0 octet ou plus de données que je ne souhaite pas extraire du tampon de socket pour le moment.

Je pensais que je pourrais appeler int ret = recv(sockfd, buf, 1, MSG_DONTWAIT | MSG_PEEK); pour déterminer si le socket est toujours connecté. S’il est connecté mais qu’il n’y a pas de données dans le tampon, j’obtiendrai -1 avec errno == EAGAIN avec errno == EAGAIN et je renverrai le sockfd pour le réutiliser. Si cela a été fermé avec élégance par l’homologue, je vais obtenir ret == 0 et ouvrir une nouvelle connexion.

J’ai testé cela et cela semble fonctionner. Cependant, je soupçonne qu’il existe un petit intervalle entre le moment où je reçois le dernier bit de mes données et le moment où arrive l’hôte FIN où je pourrais obtenir un faux positif EAGAIN de mon test.

Est-ce que cela va me mordre, ou y a-t-il une meilleure façon de faire cela?

D’accord, j’ai donc fait d’autres tests et c’est ce que j’ai trouvé.

J’ai configuré mon client pour qu’il envoie la HTTP/1.1 Connection: close messages au serveur, ce qui provoque l’appel du serveur après la dernière écriture de données. Lorsque mon client a fini de lire les données d’une transaction GET, il teste le socket pour voir s’il est toujours ouvert à l’aide de la méthode ci-dessus, puis tente d’émettre un autre GET.

Ce que j’ai trouvé, c’est qu’environ 30% du temps, mon test aurait lieu avant l’arrivée du FIN du serveur, ce qui a entraîné des résultats faussement positifs et des échecs.

La seule façon de rendre cette fiabilité raisonnable, disons près de 99%, serait d’introduire des retards artificiels liés à la latence de connexion entre la dernière lecture et la tentative de réutilisation d’une socket, ce qui constituerait plutôt un assassinat.

Je dois donc en conclure que, même si cet outil est utile, il ne l’est que marginalement.

Contrôlez-vous l’autre extrémité? Le moyen le plus fiable d’effectuer une fermeture “propre” d’une socket consiste pour l’autre extrémité à envoyer un message “au revoir”.

(Un peu “hors sujet”, désolé). Peut – être que cette discussion pourrait vous être utile. Il ne répond toujours pas à votre question “FIN”, mais peut vous aider à réagir plus facilement à l’arrêt des pairs pendant l’envoi de votre programme.

Au revoir