Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

Limit Socket (throttle) to send specific ammount of packets every second

by Lucas Rey (Sexton)
on Sep 22, 2016 at 05:58 UTC ( [id://1172344]=perlquestion: print w/replies, xml ) Need Help??

Lucas Rey has asked for the wisdom of the Perl Monks concerning the following question:

Dear Community, I'm programming a simple script in perl that do the following:
1) Open a socket to a specific server 2) Reads data line by line from a big file using a while loop 3) Send data using the open socket
I don't report the whole code since it works perfect and could be too long. What I need to accomplish is send an ammount of packets every seconds. For example I would like to limit (throttle) to send 100 packets per second. What I need, is understand how (and if) I can implement this kind of mechanism, or simply an idea. The actual code looks like:
Open Socket Open file containing data to send while # Read file line by line { Send data to Server }
Thank you, Lucas.

Replies are listed 'Best First'.
Re: Limit Socket (throttle) to send specific ammount of packets every second
by kcott (Archbishop) on Sep 22, 2016 at 08:10 UTC

    G'day Lucas,

    Welcome to the Monastery.

    Firstly, you can put long tracts of code within <readmore>...</readmore> or <spoiler>...</spoiler> tags: see "Writeup Formatting Tips" for details.

    Unfortunately, without seeing the surrounding code, it's difficult to tell what additional code will be appropriate. There may well be better solutions!

    The following demonstrates how you might achieve what you ask using an alarm (actually, it uses Time::HiRes's ualarm for finer granularity).

    #!/usr/bin/env perl -l use strict; use warnings; use Time::HiRes qw{ualarm time}; my $timeout = 1_000_000; #microseconds my $limit = 3; my @packets = (0 .. 11); print time; { my $local_limit = $limit; local $SIG{ALRM} = sub { print time; $local_limit = $limit; ualarm $timeout; }; ualarm $timeout; while (1) { next unless $local_limit-- > 0; last unless @packets; my $line = shift @packets; ualarm 1 if $line == 6; print $line; } }

    Here's a sample run:

    1474530606.74812 0 1 2 1474530607.75322 3 4 5 1474530608.75744 6 1474530608.75752 7 8 9 1474530609.75927 10 11

    Notes:

    • I've set $limit to 3; you'll want 100 here.
    • I've used an array (@packets) instead of a file. Where I have:
      last unless @packets; my $line = shift @packets;
      You'll want something like:
      last if eof $fh; my $line = <$fh>;
      See eof.
    • The line
      ualarm 1 if $line == 6;
      is a bit of a kludge. It's intended to show what happens if you read less than $limit packets in the allotted time.

    See also: "perlipc -- Perl interprocess communication".

    Update: s/last unless eof/last if eof/

    — Ken

      Thank you kcott, this is a very interesting approch. I'll try asap!!!
Re: Limit Socket (throttle) to send specific ammount of packets every second
by Corion (Patriarch) on Sep 22, 2016 at 06:57 UTC

    Without getting cozy with the operating system, you can't specify the amount of (TCP) packets that get sent.

    If you want to rate limit a proxy for the number of packets, for example, the number of bytes sent, you can use Algorithm::TokenBucket to limit the number of bytes sent per second.

      Thank you, reading the page you link me, seem the Algorithm::TokenBucket is what I need. Unfortunately this is my first application in Perl, so I'm not able to add module, and adding use Algorithm::TokenBucket; Will result in: Can't locate Algorithm/TokenBucket.pm in @INC (@INC contains: /usr/lib64/perl5/site_perl/5.8.8/x86_64-linux-thread-multi /usr/lib/perl5/site_perl/5.8.8 /usr/lib/perl5/site_perl /usr/lib64/perl5/vendor_perl/5.8.8/x86_64-linux-thread-multi /usr/lib/perl5/vendor_perl/5.8.8 /usr/lib/perl5/vendor_perl /usr/lib64/perl5/5.8.8/x86_64-linux-thread-multi /usr/lib/perl5/5.8.8 .) at ./test.sh line 4. Could you please help me? Thank you, Lucas
        installing Perl modules is normally as easy as cpan Module::Name but see specific tutorials here at PM

        L*

        PS as side note: perl 5.8.8 is the version used by my grand grand mother.. if you are new to Perl jump directly to 5.22 or more. ModernPerl is very good book and is free!

        If perl 5.8.8 is your system Perl read RFC: (Do Not) Modify the System Perl first; some monks here around use Perlbrew to deal with multiple Perl installation.

        There are no rules, there are no thumbs..
        Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.

        Because you didn't use formatting, your original follow-up post here looks like this to most of us:

        Thank you, reading the page you link me, seem the Algorithm::TokenBucket is what I need. Unfortunately this is my first application in Perl, so I'm not able to add module, and adding use Algorithm::TokenBucket; Will result in: Can't locate Algorithm/TokenBucket.pm in @INC (@INC contains: /usr/lib64/perl5/site_perl/5.8.8/x86_64-linux-thread-multi /usr/lib/perl5/site_perl/5.8.8 /usr/lib/perl5/site_perl /usr/lib64/perl5/vendor_perl/5.8.8/x86_64-linux-thread-multi /usr/lib/perl5/vendor_perl/5.8.8 /usr/lib/perl5/vendor_perl /usr/lib64/perl5/5.8.8/x86_64-linux-thread-multi /usr/lib/perl5/5.8.8 .) at ./test.sh line 4. Could you please help me? Thank you, Lucas

        If you add formatting using advice from Writeup Formatting Tips, like this:

        <p> Thank you, reading the page you link me, seem the [mod://Algorithm::To +kenBucket] is what I need. Unfortunately this is my first application + in Perl, so I'm not able to add module, and adding <code>use Algorit +hm::TokenBucket;</code> Will result in: </p> <code> Can't locate Algorithm/TokenBucket.pm in @INC (@INC contains: /usr/lib +64/perl5/site_perl/5.8.8/x86_64-linux-thread-multi /usr/lib/perl5/sit +e_perl/5.8.8 /usr/lib/perl5/site_perl /usr/lib64/perl5/vendor_perl/5. +8.8/x86_64-linux-thread-multi /usr/lib/perl5/vendor_perl/5.8.8 /usr/l +ib/perl5/vendor_perl /usr/lib64/perl5/5.8.8/x86_64-linux-thread-multi + /usr/lib/perl5/5.8.8 .) at ./test.sh line 4. </code> <p>Could you please help me?</p> <p>Thank you,<br />Lucas</p>

        ...then the rendering in peoples' browsers will look more like this:

        Thank you, reading the page you link me, seem the Algorithm::TokenBucket is what I need. Unfortunately this is my first application in Perl, so I'm not able to add module, and adding use Algorithm::TokenBucket; Will result in:

        Can't locate Algorithm/TokenBucket.pm in @INC (@INC contains: /usr/lib64/perl5/site_perl/5.8.8/x86_64-linux-thread-multi /usr/lib/perl5/site_perl/5.8.8 /usr/lib/perl5/site_perl /usr/lib64/perl5/vendor_perl/5.8.8/x86_64-linux-thread-multi /usr/lib/perl5/vendor_perl/5.8.8 /usr/lib/perl5/vendor_perl /usr/lib64/perl5/5.8.8/x86_64-linux-thread-multi /usr/lib/perl5/5.8.8 .) at ./test.sh line 4.

        Could you please help me?

        Thank you,
        Lucas

        Better, right? Making the post legible encourages people to read it, which improves the odds of getting an answer. Legibility also promotes goodwill here, which improves the odds of getting a thoughtful answer. Writeup Formatting Tips


        Dave

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1172344]
Approved by Erez
Front-paged by kcott
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others admiring the Monastery: (5)
As of 2024-04-19 09:41 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found