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

I'm trying to have a program handle multiple sockets in the same process. So for my convenience I use IO::Select, which is a beaut little module that handles sockets for me. I add sockets to be watched with $s->add($socket_handle). Then I wait and call  @ready = $s->can_read(0); which returns only the socket handles that have data waiting (so I don't block on reads - very important when I'm handling multiple sockets).

But of course I want to do different things with the data based on what socket it came from. I can't use a reference as a hash key unless I use Tie::RefHash, which is not a standard module. So far I have managed to only use standard modules, and just to prove a point I would like to continue (and because my program is more portable if I stick to core modules). What's the best way to deal with it. I could create a hash and then check every key value to see if it has been returned, but that's kludgy and I'm not even sure it works:

{ 1 => $connection_handle_1, 2 => $connection_handle_2, 3 => $connection_handle_3 }

when I would rather have:

{ $connection_handle_1 => 1, $connection_handle_2 => 2, $connection_handle_3 => 3, }

The other option is to create an object for each socket (or rather, have the object create the socket) and then poll each object like $_->do_connection foreach @object. This doesn't sit very well with me because I'm wasting some of the power of IO::Select, but it's the solution I'm running with right now. Could someone set me straight please?

____________________
Jeremy
I didn't believe in evil until I dated it.

Replies are listed 'Best First'.
Re: Non blocking multiple socket handles as hash keys
by bikeNomad (Priest) on Jun 25, 2001 at 18:30 UTC
    At least on 5.6.0 and later, Tie::RefHash seems to be in the standard distribution.

    But you can use the stringized version of the handle as an index pretty easily. Since IO::Select->select returns your original handles, you end up with a hash index that looks like 'IO::Socket::INET=GLOB(0x83cfae0)'. That's perfectly usable, no?

    You could also use the IO::Select::handles method to find the index of the handle of interest (returned by select). Or you could use the fileno of the handles as your hash key. Lots of ways to do it (this is Perl, after all...)

Re: Non blocking multiple socket handles as hash keys
by repson (Chaplain) on Jun 25, 2001 at 18:27 UTC
    Firstly you possibly could just use a normal hash, since the same socket should (maybe?) always stringify to the same thing (since the object will be in same memory location until destroyed), thus allowing you to do it the simple obvious way.

    Otherwise you could create a subclass of IO::Socket which allows extra data to be stored in the object, or just use the syntax on a normal IO::Socket:

    my $sock = IO::Socket->new(...); ${*$sock}{my_connection_data} = 3; ... print ${*$sock}{my_connection_data};
    I found that syntax in the IO::Socket code a while ago when I was trying to do much the same thing, however I can't remember how well it worked when using IO::Select and everything. Of course it may not be the `right' to play with the reference like this. And this method will likely be broken with Perl 6.