<?xml version="1.0" encoding="windows-1252"?>
<node id="490609" title="Building a simple service scanner with POE" created="2005-09-09 11:39:15" updated="2005-09-09 07:39:15">
<type id="115">
perlquestion</type>
<author id="29008">
grinder</author>
<data>
<field name="doctext">
&lt;p&gt;I've been trying to wrap my head around POE. I have a lengthy script that sees whether it can
open a socket on various ports on various machines (over 100 connecctions all told). Actually the
script is short, it just takes a long time to run, since everything is done serially.&lt;/p&gt;

&lt;p&gt;It's just &lt;i&gt;too&lt;/i&gt; slow... so I finally found some time to investigate POE, and I have the
following code:&lt;/p&gt;

&lt;code&gt;
use strict;
use POE;
use POE::Component::Client::TCP;

my $task = [
    { name =&gt; 'www.example.com',  proto =&gt; 'tcp', port =&gt; 80 },
    { name =&gt; 'smtp.example.com', proto =&gt; 'tcp', port =&gt; 25 },
    { name =&gt; 'ns.example.com',   proto =&gt; 'udp', port =&gt; 53 },

];

for my $t( @$task ) {
    next if $t-&gt;{proto} ne 'tcp';
    POE::Component::Client::TCP-&gt;new(
        RemoteAddress  =&gt; $t-&gt;{host},
        RemotePort     =&gt; $t-&gt;{port},
        Connected      =&gt; sub {
            print "$t-&gt;{host}:$t-&gt;{proto}:$t-&gt;{port} up\n";
            $poe_kernel-&gt;yield( 'shutdown' );
        },
        ConnectError   =&gt; sub { print "$t-&gt;{host}:$t-&gt;{proto}:$t-&gt;{port} down\n" },
        ConnectTimeout =&gt; 2,
        ServerInput    =&gt; sub { },
    );
}

$poe_kernel-&gt;run();
&lt;/code&gt;

&lt;p&gt;This actually works quite well. It takes less than a second to run if all services are up, and a smidgen
more than two seconds if a service is down. Much better than the 13 seconds the old script takes.&lt;/p&gt;

&lt;p&gt;It does, however, have a major flaw, in that it doesn't know how to deal with UDP. I use the
[cpan://POE::Component::Client::TCP] module to deal with TCP protocols, but there's no such thing as
POE::Component::Client::UDP, and I don't know how to go about using the POE building blocks to make
something that would work. All I need is a true/false result to the question "could I open a socket".&lt;/p&gt;

&lt;p&gt;The other flaw that I don't like is the klugey empty ServerInput callback. It's
never called, but the object cannot be constructed if this key/value pair is missing. This may mean
that I'm using POE::Component::Client::TCP for a purpose for which it was not designed. Which in turn
may mean that I'm paying for a lot of startup overhead that may be avoided by using some other
technique. Again, just like for UDP, I'm only interested in a yes/no answer.&lt;/p&gt;

&lt;p&gt;I also suspect that both of these flaws are probably solved by one simple(r)? solution. Can
someone set me straight?&lt;/p&gt;

&lt;div class="pmsig"&gt;&lt;div class="pmsig-29008"&gt;
&lt;p align="right"&gt;&lt;font size="-2"&gt;- another intruder with the mooring in the heart of the Perl&lt;/font&gt;&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;</field>
</data>
</node>
