Does IO::Socket::INET->new return undefined on error?

948 Views Asked by At

I have the following code (part of a larger script)

my $lsn = IO::Socket::INET->new(Listen => 1, LocalPort => 0); # just use any available port.
$port = $lsn->sockport();

I'm getting the error Can't call method "sockport" on an undefined value.

The documentation for IO::Socket::INET doesn't say much on this issue: https://perldoc.perl.org/IO/Socket/INET.html (is there a better place to look? Not too familiar with this module).

Strange thing is that I recently changed this, before it passed in a non-zero, randomly-generated port number, and that would sometimes break, when the port was in use.

I tested passing in 0 on my local windows machine(again, the documentation doesn't seem to mention how to get it to choose the port to bind), and that seemed to make it 'choose any available port', which is what I wanted, but maybe it behaves differently on Solaris (which is where this problem occurred)?

2

There are 2 best solutions below

0
On BEST ANSWER

IO::Socket::INET->new works like most Perl constructors: it returns an instance of the class on success, a false value on error. There's some side channel to get the error reason. Exactly what that false value is deliberately not documented, all that matters is it's false.

This leads to the general pattern my $obj = Class->new or die $reason;. In the case of IO::Socket, you get the error from $@ (which is pretty gross).

my $port = 999;
my $lsn = IO::Socket::INET->new(Listen => 1, LocalPort => $port)
    or die "Couldn't listen on port $port: $@";

# Couldnt listen on port 999: Permission denied at -e line 1.

I tested passing in 0 on my local windows machine(again, the documentation doesn't seem to mention how to get it to choose the port to bind), and that seemed to make it 'choose any available port', which is what I wanted, but maybe it behaves differently on Solaris (which is where this problem occurred)?

Yes, this is implementation specific. IO::Socket::INET is just a thin layer around the Socket library which uses bind. If you pass bind port 0 it will find a port for you. This is generally true for all modern implementations.

Windows bind...

For TCP/IP, if the port is specified as zero, the service provider assigns a unique port to the application from the dynamic client port range. On Windows Vista and later, the dynamic client port range is a value between 49152 and 65535. This is a change from Windows Server 2003 and earlier where the dynamic client port range was a value between 1025 and 5000.

1
On

Is it trying to bind to a privileged port (on Solaris less than 1024)? If so it may be a permissions issue and would need root access to bind.