For a load test of my application (under Linux), I'm looking for a tool that outputs data on stdout at a specific rate (like 100 bytes/s), so that I can pipe the output to netcat which sends it to my application. Some option for dd would be ideal, but I didn't find anything so far. It doesn't really matter what kind of data is printed (NUL bytes are OK). Any hints?
-
A correspondent has commented to me that using a pipe to netcat could mean that the pipe could be a limiting factor. It's thus more reliable to write directly to the socket at the rate you seek. – C. K. Young Oct 28 '08 at 11:26
4 Answers
I wrote a quick program that takes one argument, how many A
characters to print to standard output per second (negative argument means no rate limiting). Hope this helps! :-) (On GNU libc, you will need to link your program with -lrt
.)
Edit: revised to print dot by default, unless a second argument is specified, in which case the first character of that is used. (And that means, if you want to print the NUL character, just specify an empty string as the second argument. :-))
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
int
sleeptill(const struct timespec *when)
{
struct timespec now, diff;
clock_gettime(CLOCK_REALTIME, &now);
diff.tv_sec = when->tv_sec - now.tv_sec;
diff.tv_nsec = when->tv_nsec - now.tv_nsec;
while (diff.tv_nsec < 0) {
diff.tv_nsec += 1000000000;
--diff.tv_sec;
}
if (diff.tv_sec < 0)
return 0;
return nanosleep(&diff, 0);
}
int
main(int argc, char **argv)
{
double rate = 0.0;
char *endp;
struct timespec start;
double offset;
if (argc >= 2) {
rate = strtod(argv[1], &endp);
if (endp == argv[1] || *endp)
rate = 0.0;
else
rate = 1 / rate;
if (!argv[2])
argv[2] = ".";
}
if (!rate) {
fprintf(stderr, "usage: %s rate [char]\n", argv[0]);
return 1;
}
clock_gettime(CLOCK_REALTIME, &start);
offset = start.tv_nsec / 1000000000.0;
while (1) {
struct timespec till = start;
double frac;
double whole;
frac = modf(offset += rate, &whole);
till.tv_sec += whole;
till.tv_nsec = frac * 1000000000.0;
sleeptill(&till);
write(STDOUT_FILENO, argv[2], 1);
}
}

- 219,335
- 46
- 382
- 435
-
1With the latest revision, you can now specify 0 as the rate. Technically, it doesn't wait "forever" (as it should, mathematically); rather, it waits until the end of time_t (January 2038, on platforms with a 32-bit time_t). That's still quite a while to wait, though. :-D – C. K. Young Oct 28 '08 at 10:58
-
Nice stuff - thanks! How about putting it up on some revision control site (github, launchpad, sourceforge...) so people can add changes? Also, I think for performance it would be useful to write() a whole block of data at once. – oliver Oct 28 '08 at 11:06
-
I deliberately used write() with no buffering so the data is guaranteed to come at a constant rate. To use buffering, change the write() call to putchar(*argv[2]). :-) I'll see what I can do about public revision control.... – C. K. Young Oct 28 '08 at 11:08
-
Also, if you're using something small for the rate like 100 (as in your original question), most of the time will be taken by the sleep, not by the write. I wrote the sleeptill() function expressly to avoid "time slippage" due to the time taken, such as by the write. – C. K. Young Oct 28 '08 at 11:11
-
Okay, this isn't github or anything like it, however it'll hopefully do the trick: http://refactormycode.com/codes/566-writing-characters-to-stdout-at-a-specified-rate – C. K. Young Oct 28 '08 at 11:36
I think that this is what you really want: Pipe Viewer
Using <fast input> | pv -qL <rate>[k|m|g|t] | <rate-limited output>
will limit the pipe to the requested rate.

- 646
- 5
- 3
If you're fine with getting all hundred bytes at a time, you could do a loop with sleep
and plain old echo
in the shell as a first attempt at least.

- 391,730
- 64
- 469
- 606
-
good idea - something like "while [ true ]; do echo -n "1234567890"; usleep 10000; done" already works. – oliver Oct 28 '08 at 10:16
Well, I'm now using nuttcp to do "real" load tests instead. It seems to have quite low overhead, so the test system is not too much disturbed.

- 6,204
- 9
- 46
- 50