La taille de paquet udp la plus fiable et la plus efficace?
enverrait beaucoup de petits paquets par UDP avec plus de ressources (cpu, compression par zlib, etc...). J'ai lu ici que l'envoi d'un gros paquet de ~65kBYTEs par UDP échouerait probablement donc j'ai pensé que l'envoi de beaucoup de plus petits paquets réussirait plus souvent, mais vient ensuite la surcharge de calcul de l'utilisation de plus de puissance de traitement (ou du moins thats ce que je suppose). La question est essentiellement ceci; quel est le meilleur scénario pour envoyer le maximum de des paquets réussis et des calculs réduits au minimum? Est-il une taille spécifique qui fonctionne, la plupart du temps? J'utilise Erlang pour un serveur et Enet pour le client (écrit en c++). En utilisant la compression Zlib aussi et j'envoie les mêmes paquets à chaque client (la diffusion est le terme que je suppose).
4 réponses
la taille maximale de UDP payload
qui, la plupart du temps, ne provoquera pas de fragmentation ip est
MTU size of the host handling the PDU (most of the case it will be 1500) -
size of the IP header (20 bytes) -
size of UDP header (8 bytes)
1500 MTU - 20 IP hdr - 8 UDP hdr = 1472 bytes
@EJP parlait de 534
octets mais je le fixerais à 508
. C'est le nombre d'octets que pour sûr ne causera pas de fragmentation, parce que la taille minimale MTU qu'un hôte peut définir est 576 et IP header max size
peut être 60 bytes
(508 = 576 MTU-60 IP-8 UDP)
d'ailleurs, j'essaierais d'utiliser 1472
octets parce que 1500
est une valeur assez standard.
utilisez 1492
au lieu de 1500
pour le calcul si vous passez par une connexion PPPoE
.
l'envoi par lots de petits paquets par UDP nécessiterait-il plus de ressources ?
Oui, il serait, sans aucun doute! J'ai juste fait une expérience avec une application de streaming. L'application envoie 2000 images de données à chaque seconde, précisément chronométrées. La charge utile de données pour chaque trame est de 24 octets. J'ai utilisé UDP avec sendto() pour envoyer ces données à une application d'écoute sur un autre noeud.
ce que j'ai trouvé était intéressant. Ce niveau d'activité pris mon envoi de l'UC à ses genoux! Je suis passé d'avoir environ 64% de temps CPU libre, à avoir environ 5%! C'était désastreux pour ma candidature, donc j'ai dû arranger ça. J'ai décidé d'expérimenter avec des variations.
tout d'abord, j'ai simplement commenté l'appel sendto() , pour voir à quoi ressemblait l'assemblage de paquets au-dessus. Environ 1% de succès sur le temps CPU. C'est pas mal. OK... doit être l'appel sendto () !
alors, j'ai fait un test fakeout rapide... J'ai appelé L'API sendto () une seule fois toutes les 10 itérations, mais j'ai ajouté 10 fois la longueur de l'enregistrement de données, pour simuler l'effet d'assembler un ensemble de petits enregistrements en un plus grand, envoyé moins souvent. Les résultats ont été assez satisfaisants: 7% de CPU ont été touchés, contre 59% auparavant. Il semblerait que, du moins sur mon système * NIX-like, l'opération d'envoi d'un paquet est coûteuse juste au-dessus de l'appel.
juste au cas où quelqu'un doute si le test fonctionnait correctement, j'ai vérifié tous les résultats avec L'observation de Wireshark des transmissions UDP réelles pour confirmer que tout fonctionnait comme il se doit.
Conclusion: Il utilise beaucoup moins de temps CPU pour envoyer des paquets plus grands moins souvent, puis la même quantité de données sous la forme de paquets plus petits envoyés plus fréquemment. Certes, je ne sais pas ce qui se passe si UDP commence à frauger votre trop grand datagramme UDP... Je veux dire, Je ne sais pas combien de CPU cela ajoute. Je vais essayer de trouver (j'aimerais bien le savoir moi-même) et mise à jour de cette réponse.
534 octets. Qui doit être transmis, sans fragmentation. Il peut encore être perdu tout à fait bien sûr. Les frais généraux dus à la retransmission des paquets perdus et les frais généraux du réseau eux-mêmes sont plusieurs ordres de grandeur plus importants que n'importe quel coût CPU.
vous utilisez probablement le mauvais protocole. UDP est presque toujours un mauvais choix pour les données que vous vous souciez de transmettre. Vous finissez par superposer séquençage, réessayage, et logique d'intégrité au sommet, et puis vous avez TCP.