in reply to Bandwidth Testing

You have a problem. Measuring bandwidth can be extremely difficult. I'm assuming what you're wanting to do is simply see how 'fast' a DSL connection is?

This is a problem I looked at a while back. The simplest way seems to be to have a client server arrangement.

The client connects to the server, and downloads a (large ish) file. The time taken to download is your bandwidth measure.

In perl, well, refer elsewhere for code, but you could simply have a server that prints 1M bytes, and time how long it takes your client to recieve that. Alternatively, you can use FTP and upload and download a file. That's generally a reasonable measure :)

Other alternatives include using pings of various sizes. By comparing the round trip time of a ping of 1 byte payload. 10 bytes of payload, 100 bytes etc.

The theory being that there's a 'basic' round trip time for the small pings, that increases in direct proportion to the size of the data.

If your're actually looking to view/control bandwidth from another application, may I recommend trying to get a copy of "ntop" for viewing. Controlling bandwidth is difficult, requires bending RFCs and is a quite profitable business on the net.

Replies are listed 'Best First'.
Re: Re: Bandwidth Testing
by sunadmn (Curate) on Aug 26, 2003 at 20:18 UTC
    You are dead on there I just want a html web page I can direct users to in my dfferent cable markets and they can test the speed of their modem, currently we do use FTp, but I was asked to find something pretty with graphs like other MSO's use. It seems that most use a Java applet, which I know nothing about so i was thinking perl.
      In which case, I'd suggest trying something like a cgi that does:
      (No code I'm afraid, I don't have my real computer to experiment with)
      • Takes a time stamp (maybe using Time::HiRes)
      • Prints a load of data to the browser in comments (note, make sure that 'autoflush' is on)
      • Takes another timestamp and compares the two. Given your known quantity of data transmitted you should be able to figure out bandwidth.
      I'm not 100% certain that a CGI will pause if a buffer overflows. If it doesn't, then what you'd need to do is something smart with multipart mime, to refresh to another CGI.
      The trick I picked up from bigbrother (http://bb4.com) is to print multipart mime pages, and then you can stick a refresh header in it at the bottom. So you have your 'big' page, that prints out, hits the refresh 0 and then redirects to your 'finished' page. That compares the timestamps, and prints an output.
      I have an example, but not handy. If someone doesn't beat me to it, I'll try and remember to post it tomorrow.
      OK, here's an example that seems to work. Not very pretty, I know :)
      Accuracy of this test will increase with larger data sizes, since then you're reducing the percentage overhead introduced by server load, general cgi speed etc.
      Seems to work with my quick testing, but YMMV.

      (Oh and I had to retype this a couple of times, since the textbox likes to clear whenever I hit 'ESC'. Damn those 'vi' fingers)
      #!/bin/perl use warnings; use strict; use Time::HiRes qw ( gettimeofday ) ; my $data = "E"x1020; #start with using 1k blocks shall we? my %cgi_vars; foreach my $pair ( split ( "&", $ENV{'QUERY_STRING'} ) ) { my ( $var, $val ) = split ("=", $pair); $cgi_vars{$var} = $val; } #cgi headers: print "content-type: text/html\n\n"; #take time my ( $start_seconds, $start_microseconds ) = gettimeofday; print "$start_seconds $start_microseconds<BR/>\n"; #print stuff to thingy if ( $cgi_vars{"data_size"} ) { for ( my $count=0; $count < $cgi_vars{"data_size"}; $count++ ) { print "<!",$data,"->\n"; } } #take time. my ( $end_seconds, $end_microseconds ) = gettimeofday; print "$end_seconds $end_microseconds<BR/>\n"; #compare. my $time_delta = ($end_seconds - $start_seconds) + ( ( $end_microsecon +ds - $start_microseconds) / 1000000); if ( $cgi_vars{"data_size"} ) { print "your data transfer of ", $cgi_vars{"data_size"}, "k took ", $ +time_delta, " seconds<BR/>\n"; print "your bandwidth is ",$cgi_vars{"data_size"} / $time_delta ," k +ilobytes/sec<BR/>\n"; } else { print "please invoke as $ENV{'SCRIPT_NAME'}?data_size=100<BR/> \n"; }
        Thanks so much you're a life saver I will test thisout today and let you know how things go.
        Quick question for you did you have to do anything special to get this to run correctly?? I am getting a print out that says "please invoke as /cgi-bin/speed_test.cgi?data_size=100 . Does this mean anything to you?? Here is my basic HTML for testing:
        <form name="form1" method="get" action="/cgi-bin/speed_test.cgi"> <input type="submit" name="Submit" value="Start"> </form>