Est-il un moyen de vider les POSIX socket?
Est-il un standard d'appel pour le rinçage de la transmettre côté d'une POSIX socket jusqu'à l'extrémité distante ou ce besoin d'être mis en œuvre dans le cadre de l'utilisateur de protocole de niveau? J'ai regardé autour de l'habitude, en-têtes, mais ne pouvais pas trouver quoi que ce soit.
Vous devez vous connecter pour publier un commentaire.
Pour les sockets de domaine Unix, vous pouvez utiliser
fflush()
, mais je pense que vous avez sans doute dire les sockets réseau. Il n'est pas vraiment un concept de rinçage de ceux-ci. Les plus proches choses sont:À la fin de votre session, appelant
shutdown(sock, SHUT_WR)
de fermer écrit sur le socket.Sur les sockets TCP, la désactivation de l'algorithme Nagle avec sockopt
TCP_NODELAY
, qui est généralement une mauvaise idée qui ne sera pas fiable de faire ce que vous voulez, même si elle semble à prendre soin d'elle sur l'enquête initiale.Il est très probable que la manipulation de tout problème, appelle à une "chasse" à l'utilisateur de niveau de protocole va être la bonne chose.
#include <linux/tcp.h>
ou que ce soit d'inclure le fichier fournitTCP_NODELAY
sur votre système (essayezfgrep -r 'define TCP_NODELAY' /usr/include
).fflush
n'a rien à voir avec la question, même pour les sockets de domaine unix. Il est utile que si vous avez emballé votre support avec unFILE
viafdopen
...Que sur la définition de TCP_NODELAY et de réinitialisation de il de retour?
Probablement, il pourrait être fait juste avant l'envoi des données importantes, ou lorsque nous avons terminé avec l'envoi d'un message.
Que linux pages de man dit
De sorte qu'il serait probablement préférable de la définir après le message, mais je ne suis pas sûr de savoir comment il fonctionne sur d'autres systèmes
send()
appel! C'est parce que même avec Nagle, le premier paquet est envoyé immédiatement. Seulement pour les suivants sont en retard, et ils sont en retard seulement jusqu'à ce que le serveur reconnaît ou de réponses. Donc juste un pack "tout" dans la premièresend()
.Il n'y a aucun moyen que je connaisse dans le standard de socket TCP/IP de l'interface de vider les données "tout le chemin jusqu'à l'extrémité distante" et de s'assurer qu'il a été effectivement reconnu.
En règle générale, si votre protocole a un besoin de "temps réel" de transfert de données, la meilleure chose à faire est de définir le
setsockopt()
deTCP_NODELAY
. Cela désactive l'algorithme Nagle dans la pile de protocole et write() ou send() sur le support le plus directement les cartes à l'envoie sur le réseau....au lieu de la mise en œuvre envoyer maintenez-offs d'attente pour plus d'octets à devenir disponibles et en utilisant tous les TCP niveau des minuteries pour décider du moment de l'envoi. REMARQUE: la désactivation des Nagle ne pas désactiver le protocole TCP fenêtre coulissante ou quoi que ce soit, de sorte qu'il est toujours plus sûr de le faire....mais si vous n'avez pas besoin du "temps réel" propriétés", paquet de surcharge peuvent aller jusqu'à un peu.Au-delà, si la socket TCP mécanismes ne correspondent pas à votre application, puis généralement, vous avez besoin de revenir à l'utilisation d'UDP et de la construction de votre propre fonctionnalités du protocole sur la base, d'envoyer/recevoir des propriétés de l'UDP. C'est très fréquent lors de votre protocole a des besoins spéciaux, mais ne pas sous-estimer la complexité de le faire et de le faire tous stable et fonctionnellement correct dans l'ensemble mais relativement simples applications. En tant que point de départ, une étude approfondie de TCP caractéristiques de conception permettra de faire la lumière sur de nombreux aspects doivent être pris en considération.
Dans la RFC 1122 le nom de la chose que vous cherchez est "PUSH".
Mais je ne connais pas tout le protocole TCP API qui implémente "PUSH".
Des réponses et des commentaires traitent de l'algorithme Nagle. La plupart d'entre eux semblent partir du principe que l'algorithme Nagle retards tous les envoyer. Cette hypothèse n'est pas correcte. Nagle retards d'envoi uniquement lorsqu'un paquet précédent n'a pas encore été reconnu (http://www.unixguide.net/network/socketfaq/2.11.shtml).
Pour simplifier un peu: TCP essaie d'envoyer le première paquet (d'une rangée de paquets) immédiatement mais les retards les paquets suivants jusqu'à ce que ce soit un time-out est atteint ou le premier paquet est reconnu, selon la première éventualité.
Une solution pour éviter ces "les paquets suivants". Si votre application appelle send() plus d'une fois à transmettre un composé simple demande, essayez de réécrire votre application. Assembler la demande dans l'espace utilisateur, puis d'appeler
send()
. Une fois que.En outre, lorsque la mémoire tampon d'envoi contient suffisamment de données pour remplir la taille maximale d'un paquet de réseau, Nagle ne tarde pas non plus. Cela signifie, Nagle n'est pas (vraiment) de retard en vrac, envoyer, même si vous
send()
la majeure partie des données en petits morceaux.Je pense qu'il serait extrêmement difficile, voire impossible, de mettre en œuvre correctement. Quelle est la signification de "flush" dans ce contexte? Octets transmis au réseau? Octets reconnu par le récepteur de la pile TCP? Octets transmis à un récepteur est en mode utilisateur de l'app? Octets complètement transformés par l'utilisateur en mode app?
Ressemble vous devez le faire au niveau application...
TCP donne seulement meilleur effort de livraison, de sorte que l'acte d'avoir tous les octets de laisser Une Machine asynchrone avec leur ayant tous été reçus à la Machine B. Le protocole TCP/IP stack sait, bien sûr, mais je ne sais pas de toute façon à s'interroger sur la pile TCP pour savoir si tout envoyé a été reconnu.
De loin le moyen le plus facile pour gérer la question est au niveau de l'application. Ouvrir un deuxième socket TCP pour agir comme un canal et ont le partenaire distant de vous envoyer un accusé de réception qu'il a reçu l'info que vous voulez. Il vous en coûtera le double, mais sera totalement portable et va vous épargner des heures de temps de programmation.
Vous pouvez définir l'option tcp SO_LINGER définir un certain délai d'attente, puis fermer le socket afin de s'assurer que toutes les données ont été envoyées (ou de détecter le défaut de le faire) sur le closeing d'une connexion. Autre que cela, le protocole TCP est un "best-effort" protocole, et il ne propose pas de réel garantit que les données seront jamais atteindre la destination (contrairement à ce que semble croire), il essaie juste mieux pour obtenir livré dans le bon ordre et dès que possible.
Utilisation fsync():
sock_fd est entier descripteur de fichier de socket (..., ...), appelez
fsync(sock_fd);