fermer () socket directement après envoyer (): dangereux?

Est-il sage / sûr de close() un socket directement après le dernier send()?

Je sais que TCP est censé essayer de fournir toutes les données restantes dans le tampon d'envoi même après la fermeture du socket, mais puis-je vraiment compter sur cela?

Je m'assure qu'il n'y a pas de données restantes dans mon tampon de réception afin qu'aucun RST ne soit envoyé après ma fermeture.


Dans mon cas, la fermeture est en fait la toute dernière instruction de code avant d'appeler exit().

La pile TCP vraiment continuer à essayer de transmettre les données même après que le processus d'envoi a pris fin? Est-ce aussi fiable que d'attendre moi-même un délai d'attente arbitraire avant d'appeler close() en définissant SO_LINGER?

C'est-à-dire que les mêmes délais TCP s'appliquent-ils ou sont-ils plus courts? Avec un grand tampon d'envoi et une connexion lente, le temps de transférer réellement toutes les données tamponnées pourrait être important, après tout.


Je ne suis pas du tout intéressé à être averti du dernier octet envoyé; je viens voulez-vous qu'ils arrivent éventuellement à l'hôte distant aussi fiable que possible.

Les accusés de réception de couche D'Application ne sont pas une option (le protocole est HTTP, et j'écris un petit serveur).

25
demandé sur lxgr 2012-01-16 02:44:42

1 réponses

J'ai beaucoup lu la page ultimate SO_LINGER . Je vous recommande de le lire aussi. Il discute des cas de bord de grands transferts de données en ce qui concerne les sockets TCP.

Je ne suis pas l'expert de SO_LINGER, mais sur mon code serveur (toujours en développement actif) je fais ce qui suit:

  1. Après l'envoi du dernier octet via send (), j'appelle " shutdown (sock, SHUT_WR)" pour déclencher une FIN à envoyer.

  2. Ensuite, attendez un appel recv() suivant sur ce socket pour return 0 (ou recv renvoie -1 et errno est autre chose que EAGAIN / EWOULDBLOCK).

  3. Ensuite, le serveur fait un close () sur le socket.

L'hypothèse est que le client fermera d'abord son socket après avoir reçu tous les octets de la réponse.

Mais j'ai un délai d'attente appliqué entre l'envoi final () et quand recv() indique EOF. Si le client ne ferme jamais sa fin de connexion, le serveur abandonnera l'attente et fermera la connexion de toute façon. Je suis à 45-90 secondes pour ce délai.

Toutes mes sockets sont non bloquantes et j'utilise poll / epoll pour être averti des événements de connexion comme indice pour voir s'il est temps d'essayer d'appeler recv() ou send() à nouveau.

22
répondu selbie 2016-05-10 13:09:54