3 votes

Comment envoyer des paquets UDP à un débit spécifique en C++ sous Windows ?

J'écris un programme qui implémente le test réseau RFC 2544. Dans le cadre de ce test, je dois envoyer des paquets UDP à un débit déterminé.

Par exemple, je dois envoyer des paquets de 64 octets à 1Gb/s. Cela signifie que je dois envoyer un paquet UDP toutes les 0,5 microsecondes. Le pseudo-code peut ressembler à " Envoi de paquets UDP à un débit spécifié " :

while (true) {
    some_sleep (0.5);
    Send_UDP();
}

Mais j'ai peur qu'il n'y ait pas some_sleep() sous Windows, et aussi sous Linux, qui peut me donner une résolution de 0,5 microseconde.

Est-il possible d'effectuer cette tâche en C++, et si oui, quelle est la bonne façon de le faire ?

3voto

Erik Points 38942

Deux approches :

  • Implémentez votre propre veille en utilisant une minuterie à haute résolution telle que Windows QueryPerformanceCounter.

  • Permettez de légères variations de la vitesse, insérez Sleep(1) lorsque vous êtes suffisamment en avance sur la vitesse calculée. Utilisez timeBeginPeriod pour obtenir une résolution de 1ms.

Pour les deux approches, vous ne pouvez pas compter sur l'exactitude du sommeil. Vous devrez tenir des compteurs de totaux et ajuster la période de sommeil en fonction de votre avance ou de votre retard.

1voto

Michael Kjörling Points 3939

Cela pourrait être utile, mais je doute que ce soit directement portable sur autre chose que Windows. Mise en œuvre d'un fournisseur d'heure haute résolution, mis à jour en permanence, pour Windows par Johan Nilsson.

Cependant, n'oubliez pas que pour des paquets aussi petits, la surcharge IP et UDP représentera une grande partie des données réelles sur le fil. C'est peut-être ce que vous vouliez, ou pas. Un examen rapide de la RFC 2544 suggère que des paquets beaucoup plus volumineux sont autorisés ; il est peut-être préférable de suivre cette voie. Un retard constant de 0,5 microseconde seulement entre chaque paquet Send_UDP() L'appel va être difficile, au mieux.

1voto

eater Points 1324

Pour transmettre des trames Ethernet de 64 octets à un débit de ligne, vous voulez en fait envoyer toutes les 672 ns. Je pense que le seul moyen d'y parvenir est de devenir vraiment amical avec le matériel. Vous vous heurterez aux limites de la bande passante du bus PCI, etc. Les appels système pour envoyer un paquet prendront beaucoup plus de temps que 672 ns. Une fonction de veille est le dernier de vos soucis.

0voto

Default Points 4305

Vous supposez que vous devriez pouvoir le faire avec Boost Asio s timer function. Je ne l'ai pas essayé moi-même, mais je suppose que deadline_timer prendrait un boost::posix_time::nanosec ainsi que le boost::posix_time::second

Consultez un exemple aquí

0voto

MSalters Points 74024

Voici une implémentation native Windows de nanosleep . Si la GPL est acceptable, vous pouvez réutiliser le code, sinon vous devrez le réimplémenter.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X