如何从Perl确定本地计算机的IP地址?

时间:2008-12-01 10:27:38

标签: perl networking

是否有一种干净且独立于操作系统的方法来从Perl确定本地计算机的IP地址?

到目前为止,我找到了以下解决方案:

  • 解析ifconfig和ipconfig的输出(硬盘,不同的windows版本有不同的ipconfig输出)

  • 建立与知名IP的网络连接并检查套接字的本地IP地址(如果我无法建立连接并且只能确定一个IP地址,则无效)

有什么更好的建议吗?

11 个答案:

答案 0 :(得分:15)

Net::Address::IP::Local看起来很有希望。

use Net::Address::IP::Local;

# Get the local system's IP address that is "en route" to "the internet":
my $address      = Net::Address::IP::Local->public;

答案 1 :(得分:15)

就我而言,我需要一个没有任何非核心依赖关系的解决方案。在研究Net :: Address :: IP :: Local:

中的代码后,我想出了这个
#!/usr/bin/env perl

use strict;
use warnings;

use IO::Socket::INET;

my $local_ip_address = get_local_ip_address();

print "$local_ip_address\n";

# This idea was stolen from Net::Address::IP::Local::connected_to()
sub get_local_ip_address {
    my $socket = IO::Socket::INET->new(
        Proto       => 'udp',
        PeerAddr    => '198.41.0.4', # a.root-servers.net
        PeerPort    => '53', # DNS
    );

    # A side-effect of making a socket connection is that our IP address
    # is available from the 'sockhost' method
    my $local_ip_address = $socket->sockhost;

    return $local_ip_address;
}

get_local_ip_address()应返回与Net::Address::IP::Local->public_ipv4相同的字符串。

如果需要,可以将PeerAddr属性(在IO :: Socket :: INET的构造函数的参数中)更改为本地DNS服务器。

答案 2 :(得分:14)

您还有一些other options,包括“建立与知名IP的网络连接并检查套接字的本地IP地址”的解决方案。

在这种情况下(建立网络连接),该文章指出:

  

没有主持人的IP地址   网络接口具有IP地址,而不是主机,并且单个网络接口可以具有许多(虚拟)IP地址。操作系统的路由子系统决定使用哪个网络接口和IP地址连接到远程计算机。

     

如果您的机器只有一个外部网络接口,并且此接口只有一个IP地址,则此IP地址通常称为机器的地址,但这是不准确的。
  例如,如果机器通过虚拟接口连接到VPN,它将使用此接口的IP地址连接到VPN上的另一台机器,而不是外部IP地址

在其他解决方案中:使用“Sys::Hostname
(如果Sys::Hostname出现可解析的主机名,则有效)

use Sys::Hostname;
use Socket;
my($addr)=inet_ntoa((gethostbyname(hostname))[4]);
print "$addr\n";

答案 3 :(得分:6)

要检索所有接口的IP地址,请使用IO::Interface::Simple

perl -MIO::Interface::Simple '-Esay $_->address for grep { $_->is_running && defined $_->address } IO::Interface::Simple->interfaces'

如果您对127.0.0.1(环回)不感兴趣,可以对$_->is_loopback进行过滤。

答案 4 :(得分:2)

Perldoc有一个answer to this question in its FAQ(“perlfaq9”) - 使用不同的模块(它们是标准库的一部分)或甚至是内置函数。

答案 5 :(得分:1)

我在Linux和Solaris上使用IO::Interface取得了很好的成功,我认为它甚至可以在AIX上运行但我无法回想起来。在search.cpan.org,rt.cpan.org和ActiveState的各个站点上,看起来IO :: Interface可能在Windows上遇到构建问题。我想知道它是否可用的唯一方法是在PPM中搜索io-interface。

答案 6 :(得分:0)

使用WMI?

Example of extracting IP addresses(在Powershell中,但很清楚发生了什么)

Example of accessing WMI from Perl(不同的WMI功能,但过程相当清楚)

编辑:在Google代码搜索上搜索Networkadapter配置和语言“perl”后:

Example looks like pretty much what you need

EDIT2:事实上,OCS代码似乎包含大多数平台的代码来执行此操作,因此虽然可能没有一组代码可以执行此操作,但您可以重新使用他们的想法。不过这是GPL。

例如,here's the Solaris code。其他位包括BSD,Linux,MacOS ......

答案 7 :(得分:0)

答案 8 :(得分:0)

Net :: Address :: IP :: Local工作正常,但由于原始海报要求提供所有本地地址,我认为这个更好:

http://www.perlmonks.org/?node_id=166951

使用ActivePerl for Windows XP,它对我来说很好。

答案 9 :(得分:0)

对于我使用

的Windows的

foreach (split(/\r?\n/,`netstat -r`))
{
  next unless /^\s+0.0.0.0/;
  @S = split(/\s+/); 
  # $S[3] = Default Gateway
  # $S[4] = Main IP
}

从0.0.0.0开始的第一行是默认网关。可能有多个网关。 以255.255.255.255开头的行也很有用。 netstat -r和route print是一样的。

可以适用于OSX,Linux不太有用。

答案 10 :(得分:0)

我已经使用了这些Linux命令的组合,因此不依赖于任何perl模块。

{{1}}