Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

Re^2: IO::Socket::INET -- Jettero verses non-blocking in windows

by Forsaken (Friar)
on Jul 31, 2004 at 07:36 UTC ( [id://378886]=note: print w/replies, xml ) Need Help??


in reply to Re: IO::Socket::INET -- Jettero verses non-blocking in windows
in thread IO::Socket::INET -- jettero verses non-blocking in windows

I spent a lot of time dealing with pretty much the same problem when trying to write a module that would be able to handle multiple irc connections simultaneously. A number of suggestions were made on how to do this here. I personally found the threading method easier to work with and "cleaner" from a coding point of view than using a select loop. Even though ithreads have a number of flaws, one of them being the amount of memory they guzzle up, it still gets the job done quite well. Threads take a while to get used to, but when used properly allow for a style of coding you never might have thought possible.

Edit: a little more info.

Perhaps it would be wise to actually elaborate on WHY I prefer threading over a select loop....silly me

With a select loop, from my experience, you have to carefully decide just how often you do the check. The last parameter for select() is a timeout, and if you don't set it to a value you'll be back at square 1, since then select itself will block when no data is available. However, if you're going to check for data every millisecond you'll be spending lots and lots of cpu time, which is something I try to avoid like the plague. Another downside i ran across(there might be solutions to this, in which case I just didn't happen to find one) was that in order to effectively use the select loop, I had to read from the socket 1 byte at a time, glue these bytes to a string until I ran across a "\n", after which I sent the whole line out for processing. Using threading, you can simply have the thread do it's own little thing, reading in data using <> or readline(), and if for some reason the socket dies, be it by accident or intentionally, you can take appropriate action within the actual thread without disturbing the functionality of the main thread where the actual action happens. At some point during testing I had 10 irc connections up and running, all being fed regular data and CPU usage was, well, negligible. Memory use was a different story, but there are certain modules to bring this down a little on CPAN. Take a look at some of the modules starting with Thread:: if you feel you're willing to take a shot at it :)

  • Comment on Re^2: IO::Socket::INET -- Jettero verses non-blocking in windows

Replies are listed 'Best First'.
Re^3: IO::Socket::INET -- Jettero verses non-blocking in windows
by jettero (Monsignor) on Aug 02, 2004 at 12:10 UTC

    I did end up using threads actually.

    In the case that I can't open a non-blocking listener, I make a thread and share the messages in an array. It worked great and I can get the IP from the recv().

    Really, the best part is, this is the first time I've every needed to use a thread and now that I know how, it's like there's a whole new world out there.

    And for posterity, here is my original non-blocking loop along with my new magical threaded version.

    sub listen { my $this = shift; if( $this->{blocking} ) { if( not $this->{blocking_thread} ) { $this->{blocking_thread} = new threads( \&_blocking_listen +, $this ); } my @msgs = map([ split /^G^G/, $_ ], @global_shared_messages); @global_shared_messages = (); return @msgs; } my @msgs = (); my $msg = ""; while( my $portaddr = recv($this->{in}, $msg, 1024*1024, 0) ) { my ($portno, $ipaddr) = sockaddr_in($portaddr); my $ip = inet_ntoa($ipaddr); push @msgs, [$ip, $this->_transform($msg)]; } return @msgs; } sub _blocking_listen { my $this = shift; { my $msg = ""; while( my $portaddr = recv($this->{in}, $msg, 1024*1024, 0) ) +{ my ($portno, $ipaddr) = sockaddr_in($portaddr); my $ip = inet_ntoa($ipaddr); push @global_shared_messages, "$ip^G^G" . $this->_transfor +m($msg); } redo; # we stay in here forever, btw. } }

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://378886]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others avoiding work at the Monastery: (4)
As of 2024-04-25 13:33 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found