|
Home > Archive > Unix Programming > April 2006 > Sending UDP packets at a specified rate
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
Sending UDP packets at a specified rate
|
|
|
| Hello,
I am trying to understand how to write a simple network program that
sends UDP packets at a specified rate.
For example, let's say I want to send 500-byte packets at 40 Mbit/s
This means I want to send one packet every 0.1 ms
In my mind, the naive way to do that would be to write:
(pseudo code...)
while (1)
{
send(500-byte UDP packet);
sleep(0.1 ms);
}
But I don't think any of the sleep functions (nanosleep?) will let me
sleep for such a short period, will they?
Maybe I could send 10 packets, then sleep 1 ms? That might solve the
sleep problem, but my traffic would be very bursty.
I suppose I could waste time in a busy loop, but I don't like that solution.
Is there a (simple?) way to send 500-byte packets every 0.1 ms without
pegging the CPU to 100%?
| |
|
| (Originally posted to comp.unix.programmer)
Spoon wrote:
> I am trying to understand how to write a simple network program that
> sends UDP packets at a specified rate.
>
> For example, let's say I want to send 500-byte packets at 40 Mbit/s
>
> This means I want to send one packet every 0.1 ms
>
> In my mind, the naive way to do that would be to write:
>
> (pseudo code...)
>
> while (1)
> {
> send(500-byte UDP packet);
> sleep(0.1 ms);
> }
>
> But I don't think any of the sleep functions (nanosleep?) will let me
> sleep for such a short period, will they?
>
> Maybe I could send 10 packets, then sleep 1 ms? That might solve the
> sleep problem, but my traffic would be very bursty.
>
> I suppose I could waste time in a busy loop, but I don't like that solution.
>
> Is there a (simple?) way to send 500-byte packets every 0.1 ms without
> pegging the CPU to 100%?
| |
| purple_stars 2006-04-27, 7:55 am |
| Spoon wrote:
> Hello,
>
> I am trying to understand how to write a simple network program that
> sends UDP packets at a specified rate.
>
> For example, let's say I want to send 500-byte packets at 40 Mbit/s
>
> This means I want to send one packet every 0.1 ms
>
> In my mind, the naive way to do that would be to write:
>
> (pseudo code...)
>
> while (1)
> {
> send(500-byte UDP packet);
> sleep(0.1 ms);
> }
>
> But I don't think any of the sleep functions (nanosleep?) will let me
> sleep for such a short period, will they?
you could use usleep() but the timing won't be exactly right on a
non-real time os unless maybe you use a hardware timer and create an
interupt every X amount of time.
> Maybe I could send 10 packets, then sleep 1 ms? That might solve the
> sleep problem, but my traffic would be very bursty.
if that's an option it doesn't even matter if it's real time, use
usleep() that's what you are looking for.
> I suppose I could waste time in a busy loop, but I don't like that solution.
sure you could do that too.
> Is there a (simple?) way to send 500-byte packets every 0.1 ms without
> pegging the CPU to 100%?
using usleep(). cheers.
| |
| Rick Jones 2006-04-27, 7:55 am |
| > you could use usleep() but the timing won't be exactly right on a
> non-real time os unless maybe you use a hardware timer and create an
> interupt every X amount of time.
and, just as with nanosleep(), not all systems that offer a usleep()
actually have that fine a granularity. To wit, from the usleep manpage
under HP-UX 11i:
Implementations may place limitations on the granularity of
timer values. For each interval timer, if the requested timer
value requires a finer granularity than the implementation
supports, the actual timer value will be rounded up to the next
supported value.
rick jones
--
oxymoron n, commuter in a gas-guzzling luxury SUV with an American flag
these opinions are mine, all mine; HP might not want them anyway... 
feel free to post, OR email to rick.jones2 in hp.com but NOT BOTH...
| |
|
| purple_stars wrote:
> Spoon wrote:
>
>
> you could use usleep() but the timing won't be exactly right on a
> non-real time os unless maybe you use a hardware timer and create an
> interupt every X amount of time.
The man page for usleep in Linux states:
This function is obsolete. Use nanosleep(2) or setitimer(2) instead.
>
> if that's an option it doesn't even matter if it's real time, use
> usleep() that's what you are looking for.
I'll give nanosleep() a try.
>
> sure you could do that too.
But I would hog the CPU even though I only need 2-3% of it on average...
Ugly.
| |
| purple_stars 2006-04-27, 7:56 am |
|
Spoon wrote:
> purple_stars wrote:
[snip]
>
> I'll give nanosleep() a try.
i learned something too, i didn't know there was such a thing as
nanosleep() 
| |
| davids@webmaster.com 2006-04-27, 7:56 am |
| The easy way to do it is just to keep track of the amount of bandwidth
you are using, and if it gets to high, sleep a bit before you send the
next bit.
If you are operating in contexts where you can't sleep, then just keep
a linked list of packets you need to send. Send them as appropriate.
For example, your send logic can go like this:
1) Is bandwidth usage high? If not, go to step 4.
2) Are there too many packets queued, if yes, return an error.
3) Queue the packet for later, return.
4) Is the bandwidth usage low and there are packets queued? If so, send
some of them and update the bandwidth estimate.
5) If we emptied the queue, send this packet (updating the bandwidth
estimate) and return. If not, queue this packet and return.
DS
| |
| William.Lindquist@lmco.com 2006-04-27, 7:56 am |
| You may find that the nanosleep function uses a 10 ms. precision, such
that the smallest delay such as 1 ms. takes at least 10 ms.
You can work around this limitation by tracking the actual sleep time
and feeding any excess sleep time into the next delay calculation.
Gettimeofday returns very accurate time information. This is how I
solved this very problem.
Bill Lindquist
| |
| Rick Jones 2006-04-27, 7:56 am |
| William.Lindquist@lmco.com wrote:
> You may find that the nanosleep function uses a 10 ms. precision,
> such that the smallest delay such as 1 ms. takes at least 10 ms.
> You can work around this limitation by tracking the actual sleep
> time and feeding any excess sleep time into the next delay
> calculation.
Don't you still end-up with bursts as the excess sleep time becomes no
sleeps for a while?
> Gettimeofday returns very accurate time information. This is how I
> solved this very problem.
Careful there - I have seen - in the past anyway - gettimeofday only
increment by "large" chunks on some platforms - old Irix comes to mind
- I think it was an issue for SPECweb96 benchmarking. And just about
any "gettimeofday" replacement under Windows may only increment in 10
ms chunks. (eg glib g_get_current_time() and its use of
GetSystemTimeAsFileTime())
When one doesn't need actual wall-clock time, going with something a
bit more platform-specific - at least for measuring "time" may be
useful/accurate/precise. gethrtime() on those platforms which have
it, or something along those lines. It doesn't solve the problem of
getting short sleep times, but it will tend to allow much finer
granularity of "time" measurement.
rick jones
I'm always confusing accuracy and precision
If one has a multiple CPU system, or even multiple systems on the
network, one could I suppose "sacrifice" one CPU to sit and spin
watching time pass and "chime" to affect the short timeouts by sending
messages to the other processes which wanted to have short timeouts
but not sit and spin. Probably still burn a lot of cycles, but
perhaps not as many as having everyone spinning
--
No need to believe in either side, or any side. There is no cause.
There's only yourself. The belief is in your own precision. - Jobert
these opinions are mine, all mine; HP might not want them anyway... 
feel free to post, OR email to rick.jones2 in hp.com but NOT BOTH...
|
|
|
|
|