Quelle est la taille optimale d'un paquet UDP pour un débit maximum?
j'ai besoin d'envoyer des paquets d'un hôte à l'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 quelques-unes de mes considérations:
-
la taille MTU des commutateurs du réseau est 1500. Si j'utilise un gros paquet, par exemple 8192, cela provoquera une fragmentation. La perte d'un fragment de la perte de l'ensemble du paquet, non?
-
si j'utilise des paquets plus petits, je vais encourir les frais généraux de L'UDP et l'en-tête IP
-
si j'utilise un 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 devrais utiliser pour me permettre d'envoyer de telles tailles? Serait-ce de l'aide à bump mon débit?
-
Quelle est la taille maximale typique d'un datagramme pris en charge par l'OSS commun (par ex. Windows, Linux,etc.)?
mise à Jour:
certains récepteurs de 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 sont très adonnés à l'utilisation de ce qui est disponible. Mais j'espère avoir de meilleures réponses que de se concentrer uniquement sur le MTU.
9 réponses
Alternative 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éson pour chaque ou presque chaque chose qu'il fait. Il comporte plusieurs algorithmes auxquels la plupart des gens ne pensent pas souvent (contrôle de la congestion, retransmission, gestion des tampons, traitement des paquets réorganisés, etc.).
si vous commencez à réimplémenter tous les algorithmes TCP, vous risquez de vous retrouver avec un (paraphasant Greenspun Dixième Règle ) "ad hoc, de manière informelle-spécifié, de bogues, de la lenteur de mise en œuvre de TCP".
si vous ne l'avez pas encore fait, ce serait une bonne idée d'examiner quelques alternatives récentes au TCP/UDP, comme le SCTP ou le DCCP. Ils ont été conçus pour des niches où ni TCP ni UDP ne correspondaient, 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 idéale du datagramme est de faire exactement ce que TCP lui-même fait pour trouver la taille idéale du paquet: Path MTU discovery .
TCP a également une option largement utilisée où les deux côtés disent à l'autre ce que leur MSS (essentiellement, MTU moins headers) est.
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 laissent tomber des paquets UDP fragmentés ou des paquets qui sont trop gros. La suggestion de CesarB d'utiliser le chemin MTU est bonne.
Le débit Maximum den'est pas uniquement déterminé par la taille du paquet (bien que cela contribue bien sûr). La réduction de la latence et la maximisation du débit sont souvent en contradiction les unes avec les autres. En TCP vous avez le L'algorithme de Nagle est conçu (en partie) pour augmenter le débit global. Cependant, certains protocoles (telnet, par exemple) désactivent souvent Nagle (c'est-à-dire le bit No Delay) afin d'améliorer la latence.
avez-vous des contraintes du temps réel pour les données? La diffusion audio en continu diffère de la diffusion de données non en temps réel (p. ex., informations de journalisation), car la première profite davantage d'une faible latence, tandis que la seconde bénéficie d'un débit accru et peut-être d'une plus grande fiabilité. Sont là exigences en matière de fiabilité? Si vous ne pouvez pas manquer les paquets et que vous 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 ligne de compte et (comme cela a été suggéré dans une autre réponse) à un moment donné, vous obtenez une mauvaise mise en œuvre de TCP. Ceci étant dit, si vous voulez obtenir une faible latence et que vous pouvez tolérer une perte en utilisant UDP avec une taille de paquet globale définie sur le chemin MTU (assurez-vous de définir la taille de la charge utile pour tenir compte headers) est probablement la solution optimale(en particulier: si vous pouvez vous assurer que UDP peut aller d'un bout à l'autre.
Eh bien, j'ai une réponse non-MTU pour vous. L'utilisation d'une prise UDP connectée 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 une socket UDP non connectée, ce qui se passe, c'est que le noyau connecte temporairement la socket, envoie les données et ensuite 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 de sorte que vous pouvez obtenir des messages D'erreur ICMP. Sur une socket UDP non connectée, le noyau ne sait pas à quelle application délivrer les erreurs ICMP et ils sont donc simplement rejetés.
la solution la plus simple pour trouver mtu dans c# est d'envoyer des paquets udp avec le drapeau dontfragment mis à true. s'il y a une exception, essayez de réduire la taille du paquet. faites ceci jusqu'à ce qu'il n'y ait pas d'exception lancée. vous pouvez commencer avec 1500 paquets.
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. Chemin MTU discovery trouve le plus petit MTU possible sur le chemin de la destination. Mais cela ne signifie pas nécessairement que, lorsque vous utilisez la plus petite MTU, vous obtiendrez la meilleure performance possible. Je pense que le meilleur moyen est de faire un test. Ou peut-être que tu ne devrais pas te soucier du plus petit MTU sur le chemin. Un périphérique réseau peut très bien utiliser un petit MTU et aussi transfert de paquets très rapide. Et sa valeur peut très bien changer à l'avenir. Donc vous ne pouvez pas le découvrir et le sauvegarder quelque part pour l'utiliser plus tard, vous devez le faire périodiquement. Si j'étais vous, je mettrais le MTU à quelque chose comme 1440 et benchmark l'application...
Heu Jason, TCP n'est pas utiliser 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 traite le transfert de données d'une extrémité à l'autre (à travers différents réseaux), c'est pourquoi elle est appelée le protocole Inter-networking . TCP et UDP gèrent la segmentation des données elle-même. Les couches inférieures comme Ethernet ou PPP ou n'importe quoi d'autre que vous utilisez d'ordinateur à ordinateur transfert de données (qui est, au sein d'un seul réseau).
même si le MTU au commutateur est 1500, Vous pouvez avoir des situations (comme un tunnel à travers un VPN) qui enveloppent quelques headers supplémentaires autour du paquet - vous pouvez faire mieux de les réduire légèrement, et aller à 1450 ou plus.
pouvez-vous simuler le réseau et tester les performances avec différentes tailles de paquets?
la "pile" est (utilisations TCP(utilisations UDP(utilisations IPv4 (ETHERNET))))... ou La "pile" est (TCP uses(UDP uses(IPv6 uses (ETHERNET))))...
tous ces en-têtes sont ajoutés dans TCP. IPv6 est juste stupide. Chaque ordinateur n'a pas besoin de sa propre IP. IPv6 n'est qu'un bouquet indésirable. Vous avez plus de 65 000 ports, vous ne les utiliserez pas tous, jamais... Ajoutez cela à l'adresse MAC de la machine individuelle dans L'en-tête ETHERNET, et vous avez des millions d'adresses.
Concentrez-vous sur les en-têtes (UDP uses(IPv4 uses(ETHERNET))), et tout ira bien. Votre programme devrait être capable de "vérifier" la taille du paquet, en recevant un tampon de 65 000 octets sur UDP, défini comme tout nul CHR(0), et en envoyant un paquet de 65 000 octets de CHR(255). Vous pouvez voir si vos données UDP ont été perdues, parce que vous ne l'obtiendrez jamais. Il sera coupé court. UDP ne transmet pas de paquets multiples. Vous envoyer, vous obtenez un. Tu en auras moins si ça ne rentre pas. Ou vous n'obtenez rien, si il est perdu.
TCP retiendra vos connexions au purgatoire jusqu'à ce que toutes les données soient reçues. Il utilise des paquets UDP, et dit à l'autre ordinateur de renvoyer ces paquets manquants. Cela vient avec des frais généraux supplémentaires, et provoque un décalage si un paquet est abandonné, perdu, court ou hors service.
UDP vous donne le contrôle total. Utilisez UDP si vous envoyez des données "critiques" et "Non critiques", et que vous voulez utiliser un système de numéro de commande de paquets réduit, qui ne dépend pas de l'arrivée séquentielle. Seulement utilisez TCP pour les données Web ou sécurisées solides, ce qui exige de la persistance et une exhaustivité à 100%. Dans le cas contraire, vous gaspillez simplement notre bande passante web, et vous ajoutez du désordre gonflé au réseau. Plus votre flux de données est petit, moins vous perdrez en cours de route. Utilisez TCP, et vous garantissez un délai supplémentaire lié à tous les en-têtes de revente et gonflés qui sont ajoutés sur L'en-tête TCP, pour "Flow control".
sérieusement, le contrôle du débit n'est pas si difficile à gérer, ni prioritaire, et détection de données manquantes. TCP n'offre rien d'autre. C'est pourquoi il est donné gratuitement. Il n'est pas assaisonné, il est simplement aveuglément stupide et facile. C'est une vieille paire de tongs. Vous avez besoin d'une bonne paire de chaussures de sport. TCP était, et est toujours, un piratage.