1

我有以下代码(较大脚本的一部分)

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

我得到了错误Can't call method "sockport" on an undefined value

的文档IO::Socket::INET在这个问题上没有说太多:https ://perldoc.perl.org/IO/Socket/INET.html (有更好的地方看吗?对这个模块不太熟悉)。

奇怪的是,我最近更改了这个,在它传入一个非零、随机生成的端口号之前,当端口正在使用时,有时会中断。

我在本地 Windows 机器上测试了传入0(同样,文档似乎没有提到如何让它选择要绑定的端口),这似乎使它“选择任何可用端口”,这就是我想要的,但它在 Solaris 上的行为可能有所不同(这是发生此问题的地方)?

4

2 回答 2

5

IO::Socket::INET->new像大多数 Perl 构造函数一样工作:成功时返回类的实例,出错时返回假值。有一些旁道可以获取错误原因。故意没有记录该错误值的确切含义,重要的是它是错误的。

这导致了一般模式my $obj = Class->new or die $reason;。在 IO::Socket 的情况下,您会得到错误$@(这很严重)。

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.

我在本地 Windows 机器上测试了传入 0(同样,文档似乎没有提到如何让它选择要绑定的端口),这似乎使它“选择任何可用端口”,这就是我想要,但也许它在 Solaris 上的行为不同(这是发生此问题的地方)?

是的,这是特定于实现的。IO::Socket::INET 只是 Socket 库周围的一个薄层,它使用bind. 如果您通过bind端口 0,它将为您找到一个端口。这对于所有现代实现通常都是正确的。

窗户bind...

对于 TCP/IP,如果端口指定为零,则服务提供者会从动态客户端端口范围为应用程序分配一个唯一端口。在 Windows Vista 和更高版本上,动态客户端端口范围是介于 49152 和 65535 之间的值。这是与 Windows Server 2003 和更早版本的变化,其中动态客户端端口范围是介于 1025 和 5000 之间的值。

于 2018-06-14T19:51:30.270 回答
0

它是否试图绑定到特权端口(在 Solaris 上小于 1024)?如果是这样,则可能是权限问题,并且需要 root 访问权限才能绑定。

于 2018-06-14T23:01:41.437 回答