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

Hey, I have a listener program running on my server, hooked into 16 ports:

12345/tcp 12346/tcp 22345/tcp 22346/tcp 22347/tcp 22348/tcp 22349/tcp 22350/tcp 22351/tcp 22352/tcp 22353/tcp 22354/tcp 22355/tcp 22356/tcp 22357/tcp 22358/tcp
The Listener program gets executed when an IO::SOCKET::INET request comes in from a Perl script. What I would like to do is the following:
~Check If a port is available ~~If available, use it ~~If not, try another one of the predefined port ( ~~If that fails, then return message
If anyone can point me in the right direction it would be greatly appreciated. UPDATE:: This should be a client side script that checks if any of the above ports are available. If so, use that port to send a request. If the port is not available, loop to the next port.

Replies are listed 'Best First'.
Re: IO:: SOCKET Check Port, Please Help!
by ikegami (Patriarch) on Sep 22, 2011 at 17:50 UTC

    Why 16 ports? Do you realise you can have 16 processes listening to the same port?

    If there are processes blocked on accept, one of them (and only one) will receive the request. If there are no processes blocked on accept, the first one to call accept will receive the request.

    You do this by creating the socket in one process, and passing the handle to the other processes. This is usually done using inheritance at process creation time, but other means of passing file handles should work too.

Re: IO:: SOCKET Check Port, Please Help!
by Perlbotics (Archbishop) on Sep 22, 2011 at 12:51 UTC

    If you only want to find the first free port, you could just connect and see if that fails or use a combination with a timeout (see alarm) for the more complicated cases, e.g. where the server does connect but not respond.

    use strict; use warnings; use IO::Socket::INET; sub get_sock_to_free_port { my ( $rpt_host, @rpt_ports ) = @_; foreach my $rpt_port ( @rpt_ports ) { my $sock = new IO::Socket::INET ( PeerAddr => $rpt_host, PeerPort => $rpt_port, Proto => 'tcp' ); return $sock if $sock; warn "failed check: $rpt_port - $!"; } die "No active port in list: @rpt_ports"; } my @rpt_ports = qw(12345 12346 22345 22346 22347 22348 22349 22350 22351 22352 22353 22354 22355 22356 22357 22358); my $sock = get_sock_to_free_port( '127.0.0.1', @rpt_ports ); ...

    Update: (in response to AM feedback below): Premature end of script headers is a problem that can occur after a valid $sock has been found (protocol problem (\r\n?) / server problem / config problem). So it is not directly related to the solution given above. Perhaps checking the HTTPD server logs or the server-script helps?

      This kinda looks like what I am looking for but it keeps failing. Premature end of script headers... any suggestion?
Re: IO:: SOCKET Check Port, Please Help!
by abubacker (Pilgrim) on Sep 22, 2011 at 10:21 UTC

    Use bind() function , hope it solves your requirement

      This is a client side script, not server... here is the code I currently have:

      ## # Connect to report host ### my $sock = new IO::Socket::INET ( PeerAddr => $rpt_host, PeerPort => $rpt_port, Proto => 'tcp' )|| die &printError($!,"NULL"); $sock->autoflush(1); # # Send data to host # print $sock $rpt_params || die &printError($!,"Sending: ".$rpt_params) +; # # Get response from host. First 4 bytes returned in header tells leng +th of rest of message. # $msg = <$sock> || die &printError($!,"Recv: ".<$sock>); close($sock);
      How would your suggestion help?