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

im trying to bind multiple sockets, and whenever someone connects to any of the ports, it displays it. I know i should use IO::Socket and IO::Select, but im not sure the best way to go abouts doing it. the ports to bind to are defined in a config file that the script uses, so its nothing hardcoded. Thanks for the help! 2bit4

Replies are listed 'Best First'.
Re: multiple socket binding
by chromatic (Archbishop) on Feb 23, 2003 at 21:54 UTC

    It sounds like you've already solved the problem. Use IO::Socket and IO::Select. Read the config file. Open the sockets you need based on the values in the config file. Loop over a select call until you get a connection. Display "it", whatever "it" is.

    The Synopsis section at the start of the documentation for both IO::Socket and IO::Select has the code you need. Parsing a config file depends on the nature of the file, but there are lots of modules for lots of types of files, and they all have Synopsis sections as well.

      Yeah, "it" would be the clients ip address, the config file is easy to load. My question is this:
      for my $fh ($sel->can_read()) { if ($fh == $SERVER) { print "client connected\n"; } ... }
      the $SERVER would be the bound socket, how do i test this if their are multiple sockets? I created a hash table that held all the descriptors for the bound ports, but not sure how to get it to match, i did the same as above but instead of the $fh == $SERVER, i did:
      for (keys(%hash)) { if ($fh == $_) { ... } }
      Thanks, 2bit4

      Edit: Added <code> tags. larsen

        If you are adding your client sockets to the IO::Select object, then when you call can_read, it will return an array of all the socket filehandles that are ready for reading, so when you call for my $fh ($sel->can_read()) { ... }, each time through the loop, $fh will contain the filehandle for a different client connection. The hash you created with all the descriptors is unnecessarry, the IO::Select object holds them for you.

Re: multiple socket binding
by castaway (Parson) on Feb 24, 2003 at 12:20 UTC
    Untested code ahead:
    use IO::Socket; use IO::Select; my $port1 = 80; my $port2 = 81; my $sock1 = new IO::Socket::INET(Port => $port1, Proto => 'tcp', Listen => 1, Reuse => 1, Timeout => 60); die "can't open $port1 ($!)" unless $sock1; my $sock2 = new IO::Socket::INET(Port => $port2, Proto => 'tcp', Listen => 1, Reuse => 1, Timeout => 60); die "can't open $port2 ($!)" unless $sock1; my $sel = new IO::Select; $sel->add($sock1); $sel->add($sock2); while(1) { my @handles = $sel->can_read(10); # timeout after 10 secs foreach my $h (@handles) { if($h == $sock1) { # do something with port 80 data } elsif($h == $sock2) { # do something with port 81 data } } }
    How's that?

    C.