web-dev-qa-db-fra.com

Quand dois-je utiliser TCP_NODELAY et quand TCP_CORK?

J'ai compris que les deux désactivaient l'algorithme de Nagle.

Quand dois-je/ne dois-je pas utiliser chacun d'eux?

57
user360455

Tout d'abord, les deux ne désactivent pas l'algorithme de Nagle.

L'algorithme de Nagle permet de réduire le nombre de petits paquets réseau dans le fil. L'algorithme est le suivant: si les données sont inférieures à une limite (généralement MSS), attendez de recevoir l'ACK pour les paquets envoyés précédemment et, en attendant, accumulez les données de l'utilisateur. Envoyez ensuite les données accumulées.

if [ data > MSS ]
    send(data)
else
    wait until ACK for previously sent data and accumulate data in send buffer (data)
    And after receiving the ACK send(data)

Cela vous aidera dans des applications comme telnet. Cependant, l'attente de l'ACK peut augmenter la latence lors de l'envoi de données en streaming. En outre, si le récepteur implémente la "stratégie ACK retardée", cela entraînera une situation de blocage temporaire. Dans de tels cas, la désactivation de l'algorithme de Nagle est une meilleure option.

TCP_NODELAY est donc utilisé pour désactiver l'algorithme de Nagle.

TCP_CORK accumule de manière agressive des données. Si TCP_CORK est activé dans un socket, il n'enverra pas de données jusqu'à ce que le tampon se remplisse à une limite fixe. Semblable à l'algorithme de Nagle, il accumule également des données de l'utilisateur, mais jusqu'à ce que le tampon se remplisse jusqu'à une limite fixe, jusqu'à ce qu'il reçoive ACK. Cela sera utile lors de l'envoi de plusieurs blocs de données. Mais vous devez être plus prudent lorsque vous utilisez TCP_CORK.

Jusqu'au noyau 2.6, ces deux options s'excluent mutuellement. Mais dans le noyau ultérieur, les deux peuvent exister ensemble. Dans ce cas, TCP_CORK aura plus de préférence.

Réf:

70
theB

TCP_NODELAY

Utilisé pour désactiver l'algorithme de Nagle pour améliorer les réseaux TCP/IP et diminuer le nombre de paquets en attendant qu'un accusé de réception des données précédemment envoyées soit reçu pour envoyer les paquets accumulés.

// Depuis le manuel tcp (7):

TCP_CORK (ou TCP_NOPUSH dans FreeBSD)

S'il est défini, n'envoyez pas de trames partielles. Toutes les trames partielles en file d'attente sont envoyées lorsque l'option est à nouveau désactivée. Ceci est utile pour ajouter des en-têtes avant d'appeler sendfile(2), ou pour l'optimisation du débit. Tel qu'il est actuellement mis en œuvre, il existe un ** plafond de 200 millisecondes ** sur la durée pendant laquelle la sortie est bouchée par TCP_CORK. Si ce plafond est atteint, les données en file d'attente sont automatiquement transmises. Cette option peut être combinée avec TCP_NODELAY Uniquement depuis Linux 2.5.71. Cette option ne doit pas être utilisée dans du code destiné à être portable.

21
Hussein Galal

C'est une optimisation, donc comme toute optimisation:

  1. Ne l'utilise pas
  2. Attendez que les performances deviennent un problème, puis avoir déterminé que la latence du socket en est certainement la cause, et les tests prouvent que cela va définitivement le réparer, ET c'est la façon la plus simple de le réparer, faites-le.

Fondamentalement, l'objectif est d'éviter d'avoir à envoyer plusieurs images où une seule image peut être utilisée, avec sendfile () et ses amis.

Ainsi par exemple, dans un serveur web, vous envoyez les en-têtes suivis du contenu du fichier, les en-têtes seront assemblés en mémoire, le fichier sera alors envoyé directement par le noyau. TCP_CORK vous permet d'envoyer les en-têtes et le début du fichier dans une seule trame, même avec TCP_NODELAY, ce qui entraînerait autrement l'envoi immédiat du premier bloc.

7
MarkR

TCP_CORK est l'opposé de TCP_NODELAY. Le premier force le retard d'accumulation de paquets; ce dernier le désactive.

0
fche