Perl:如何移植保留TCP端口(因此会有一个不可用的URL)

时间:2011-10-09 14:34:24

标签: windows perl unix networking tcp

我是XML-LibXSLT模块的维护者,其中一个测试需要访问不存在的URL。问题是有人报告说他们的系统上存在URL,所以我决定在localhost上分配一个随机端口,我确信不会有网络服务。它是这样做的:

# We reserve a random port to make sure the localhost address is not
# valid. See:
#
# https://rt.cpan.org/Ticket/Display.html?id=52422

my $sock = IO::Socket::INET->new(
    Proto => 'tcp',
);

my $port = $sock->sockport();

$file = "http://localhost:${port}/allow.xml";

现在,问题是Linux上的$ port已定义且有效(对于保留端口的值),但它似乎无法在Windows上运行 - 请参阅此错误报告 - https://rt.cpan.org/Ticket/Display.html?id=71456。我的问题是:如何在Perl 5中的UNIX,Mac OS X和Windows上预留一个新的,随机的,尚未占用的端口?

此致

Shlomi Fish

4 个答案:

答案 0 :(得分:5)

您应该能够使用端口0 bind到环回地址(以便为您分配端口)。对于奖励积分,你可能想尝试connect套接字本身(可能不需要任何地方,但应该保证它有一个地址)

答案 1 :(得分:4)

您希望bind套接字到地址+端口。如果您指定LocalAddr(或LocalHost),就会发生这种情况。如果您未指定端口(或指定端口0),将为您选择一个空闲端口。

use strict;
use warnings;
use 5.010;

use IO::Socket::INET qw( INADDR_ANY );

my $sock = IO::Socket::INET->new(
    Proto     => 'tcp',
    LocalAddr => INADDR_ANY,
);

my $port = $sock->sockport();

say $port;  # 60110

我认为您只想接受来自环回适配器的连接。如果是,请使用INADDR_LOOPBACK代替INADDR_ANY

答案 2 :(得分:1)

试试这个小工具https://github.com/yegor256/random-tcp-port(我是开发人员)。应该在Windows中工作,因为它是ANSI C。

答案 3 :(得分:0)

我怀疑(但不能从这里证明)在Windows上,在套接字实际开始监听之前,端口号实际上并未分配。

然而,实际监听该套接字会阻止测试尽快失败,因为初始TCP连接实际上会成功。

您是否考虑过仅将网址指向test.example.com,但保证不存在?