J'ai besoin d'envoyer des paquets d'un hôte à un autre sur un réseau potentiellement avec perte. Afin de minimiser la latence des paquets, je ne considère pas TCP/IP. Mais, je souhaite maximiser le débit uisng UDP. Quelle devrait être la taille optimale du paquet UDP à utiliser?
Voici certaines de mes considérations:
La taille MTU des commutateurs du réseau est de 1500. Si j'utilise un gros paquet, par exemple 8192, cela provoquera une fragmentation. La perte d'un fragment entraînera la perte de l'ensemble du paquet, non?
Si j'utilise des paquets plus petits, j'encourrai la surcharge de l'en-tête UDP et IP
Si j'utilise un très gros paquet, quel est le plus gros que je puisse utiliser? J'ai lu que la plus grande taille de datagramme est 65507. Quelle est la taille de tampon que je dois utiliser pour me permettre d'envoyer de telles tailles? Cela aiderait-il à augmenter mon débit?
Quelle est la taille de datagramme maximale typique prise en charge par les systèmes d'exploitation courants (par exemple, Windows, Linux, etc.)?
Actualisé:
Certains des récepteurs des données sont des systèmes embarqués pour lesquels la pile TCP/IP n'est pas implémentée.
Je sais que cet endroit est rempli de gens qui adorent utiliser ce qui est disponible. Mais j'espère avoir de meilleures réponses que de se concentrer uniquement sur MTU.
Autre réponse: attention à ne pas réinventer la roue.
TCP est le produit de décennies d'expérience en réseau. Il y a une résonance pour tout ou presque tout ce qu'il fait. Il possède plusieurs algorithmes auxquels la plupart des gens ne pensent pas souvent (contrôle de la congestion, retransmission, gestion de la mémoire tampon, gestion des paquets réorganisés, etc.).
Si vous commencez à réimplémenter tous les algorithmes TCP, vous risquez de vous retrouver avec un (paraphasage dixième règle de Greenspun ) "ad hoc, spécifié de manière informelle, rempli de bogues, lent mise en œuvre de TCP ".
Si vous ne l'avez pas encore fait, ce pourrait être une bonne idée de regarder quelques alternatives récentes à TCP/UDP, comme SCTP ou DCCP. Ils ont été conçus pour des niches où ni TCP ni UDP ne correspondaient bien, précisément pour permettre aux gens d'utiliser un protocole déjà "débogué" au lieu de réinventer la roue pour chaque nouvelle application.
La meilleure façon de trouver la taille de datagramme idéale est de faire exactement ce que TCP lui-même fait pour trouver la taille de paquet idéale: Découverte MTU du chemin .
TCP a également une option largement utilisée où les deux parties disent à l'autre quel est leur MSS (en gros, en-têtes MTU moins).
Eh bien, j'ai une réponse non MTU pour vous. L'utilisation d'un socket UDP connecté devrait accélérer les choses pour vous. Il y a deux raisons d'appeler connect sur votre socket UDP. Le premier est l'efficacité. Lorsque vous appelez sendto sur un socket UDP non connecté, ce qui se passe est que le noyau connecte temporairement le socket, envoie les données puis les déconnecte. J'ai lu une étude indiquant que cela prend près de 30% du temps de traitement lors de l'envoi. L'autre raison d'appeler connect est pour que vous puissiez obtenir des messages d'erreur ICMP. Sur un socket UDP non connecté, le noyau ne sait pas à quelle application envoyer les erreurs ICMP et ils sont donc simplement rejetés.
Une autre chose à considérer est que certains périphériques réseau ne gèrent pas très bien la fragmentation. Nous avons vu de nombreux routeurs qui abandonnent des paquets UDP fragmentés ou des paquets trop gros. La suggestion de CesarB d'utiliser Path MTU est bonne.
Le débit maximal n'est pas déterminé uniquement par la taille du paquet (bien que cela contribue bien sûr). Minimiser la latence et maximiser le débit sont souvent incompatibles. Dans TCP vous avez l'algorithme Nagle qui est conçu (en partie) pour augmenter le débit global. Cependant, certains protocoles (par exemple, telnet) désactivent souvent Nagle (c'est-à-dire, définissez le bit No Delay) dans afin d'améliorer la latence.
Avez-vous des contraintes de temps réel pour les données? Le streaming audio est différent de la transmission de données non en temps réel (par exemple, les informations de journalisation), car le premier bénéficie davantage d'une faible latence tandis que le second bénéficie d'un débit accru et peut-être d'une fiabilité accrue. Existe-t-il des exigences de fiabilité? Si vous ne pouvez pas manquer de paquets et devez avoir un protocole pour demander la retransmission, cela réduira le débit global.
Il y a une myriade d'autres facteurs qui entrent en jeu et (comme cela a été suggéré dans une autre réponse) à un moment donné, vous obtenez une mauvaise implémentation de TCP. Cela étant dit, si vous souhaitez obtenir une faible latence et pouvez tolérer la perte en utilisant UDP avec une taille de paquet globale définie sur le PATH MTU (assurez-vous de définir la taille de la charge utile pour tenir compte des en-têtes) est probablement la solution optimale (en particulier si vous peut garantir que l'UDP peut passer d'un bout à l'autre.
La solution de contournement la plus simple pour trouver mtu en c # consiste à envoyer des paquets udp avec l'indicateur dontfragment défini sur true. s'il lève une exception, essayez de réduire la taille du paquet. faites-le jusqu'à ce qu'il n'y ait aucune exception levée. vous pouvez commencer avec une taille de paquet de 1500.
Uhh Jason, TCP ne pas utilise UDP. TCP utilise IP, c'est pourquoi vous le voyez souvent appelé TCP/IP. UDP utilise également IP, donc UDP est techniquement UDP/IP. La couche IP gère le transfert de données de bout en bout (sur différents réseaux), c'est pourquoi on l'appelle Inter-networking Protocole. TCP et UDP gèrent la segmentation des données elle-même. Les couches inférieures telles qu'Ethernet ou PPP ou tout autre élément que vous utilisez) gèrent ordinateur à ordinateur. transfert de données (c'est-à-dire au sein d'un même réseau).
L'en-tête IP est> = 20 octets mais surtout 20 et l'en-tête UDP est de 8 octets. Cela vous laisse 1500 - 28 = 1472 octets pour vos données. La découverte PATH MTU trouve le plus petit MTU possible sur le chemin de la destination. Mais cela ne signifie pas nécessairement que, lorsque vous utilisez le plus petit MTU, vous obtiendrez les meilleures performances possibles. Je pense que la meilleure façon est de faire un benchmark. Ou peut-être que vous ne devriez pas vous soucier du plus petit MTU sur le chemin. Un périphérique réseau peut très bien utiliser un petit MTU et également transférer des paquets très rapidement. Et sa valeur pourrait très bien changer à l'avenir. Donc, vous ne pouvez pas découvrir cela et l'enregistrer quelque part pour l'utiliser plus tard, vous devez le faire périodiquement. Si j'étais vous, je définirais le MTU sur quelque chose comme 1440 et comparerais l'application ...
Même si le MTU au niveau du commutateur est de 1500, vous pouvez avoir des situations (comme le tunneling via un VPN) qui enveloppent quelques en-têtes supplémentaires autour du paquet - vous pouvez faire mieux pour les réduire légèrement, et aller à 1450 environ.
Pouvez-vous simuler le réseau et tester les performances avec différentes tailles de paquets?