Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number
 
PerlMonks  

Send over/print to socket at a specific rate

by doherty (Novice)
on May 05, 2011 at 16:27 UTC ( [id://903186]=perlquestion: print w/replies, xml ) Need Help??

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

Hello,

I need to send some binary data over a socket. The data is samples taken at 11025Hz, and it needs to be sent at that speed (16bits/sample, so we can work out how many bytes to send per second easily). Is this a solved problem? If not, how should I approach solving it?

At present, I just print to a socket.

#!/usr/bin/env perl # Reads in some bytes, and stuffs them into a socket. use strict; use warnings; #use diagnostics; use IO::Handle; use autodie; use Socket; my $host = 'localhost'; my $port = 7000; my $iaddr = inet_aton($host) or die "No host: $host"; my $paddr = sockaddr_in($port, $iaddr); my $proto = getprotobyname('tcp'); socket(Server, PF_INET, SOCK_STREAM, $proto) or die "socket: $!"; setsockopt(Server, SOL_SOCKET, SO_REUSEADDR, pack("l", 1)) or die "set +sockopt: $!"; bind(Server, $paddr) or die "bind: $!"; listen(Server, SOMAXCONN) or die "listen: $!"; $SIG{CHLD} = \&REAPER; # wtf? my $data = do { open my $in, '<', '11k16bit.pcm'; local $/; <$in> }; STDOUT->autoflush(1); for ( ; $paddr = accept(Client, Server); eval{print "disconnecting\n"; + close Client}) { my($port, $iaddr) = sockaddr_in($paddr); my $name = gethostbyaddr($iaddr, AF_INET); print "Client is $name..."; print Client $data; print " done\n"; }

(I'd also welcome help writing this with IO::Socket or whatever you consider more modern. This is mostly cargo culting...)

Replies are listed 'Best First'.
Re: Send over/print to socket at a specific rate
by Eliya (Vicar) on May 05, 2011 at 17:03 UTC

    There's no way to directly set the transmission speed of a socket connection.  All you could do is to approximate the average speed by sending a 11025 x 16bits block once every second or similar (using a timer, and presuming the bandwidth of the connection is sufficient) — though I'm not really sure if this would help here...

    I think you'll have to process the data on the receiving end instead (at 11025 x 16bits per second). The data on the socket will not come in faster than you're reading it.

    What is the real problem you're trying to solve with your sending-at-a-specific-rate requirement?

      Actually, if you are on Linux, this is not true. You can set the speed; it's just very painful, and you can't do it in perl (except via system calls). You can use tc to create a rate-shaping class on the interface you are writing to, along with a filter to force the packets of your socket into that class (if your destination has a fixed addr/port it is not that hard). Look here for an overview of how tc works. That said, I agree with Eliya that more definition of why this constraint is necessary to decide if this pain is worth it.

      fnord

        I wish I were on Linux. Normally I am, but this is Windows. It's for a test setup, so it's not critical. I'll just send the data in chunks with a timer as suggested. Thanks.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (6)
As of 2024-03-28 12:12 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found