2008-12-01 147 views
8

是否有一个干净的和操作系统无关的方式来确定从Perl本地计算机的IP地址?如何从Perl中确定本地计算机的IP地址?

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

  • 解析使用ifconfig和ipconfig(硬,Windows版本的不同有不同的IPCONFIG输出)

  • 的输出建立网络连接到井已知的IP并检查插座的本地IP地址(如果我无法建立连接并仅确定一个IP地址,则无法工作)

有什么更好的建议?

+0

神奇的数字是127.0.0.1 – 2008-12-01 10:29:11

+2

这不是我所需要的。我只想以自定义的形式打印机器的IP地址,我不想使用这些地址。 – Zizzencs 2008-12-01 10:32:17

回答

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; 
0

使用WMI?

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

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

编辑:在谷歌于codesearch为Networkadapterconfiguration搜索后和语言“的Perl”:

Example looks like pretty much what you need

EDIT2:其实在OCS代码似乎包含代码为大多数平台来做到这一点,所以虽然可能没有任何一组代码可以做到这一点,但您可以重新使用自己的想法。不过,它是GPL的。例如,here's the Solaris code。其他位包括BSD,Linux,MacOS ......

+0

看起来很有希望,但afaik WMI在大多数Linux系统上都不可用。当然你可以使用OpenPegasus,但这对于这个问题会有点太大。 – Zizzencs 2008-12-01 10:46:18

+0

不,WMI不会。看起来你可能需要打开操作系统类型并使用不同的代码。 – 2008-12-01 10:50:10

+0

如果没有其他帮助,我会这样做。谢谢您的回答。 – Zizzencs 2008-12-01 11:04:25

13

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

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

有没有这样的事,作为一个主机的IP地址。
网络接口有IP地址,而不是主机,单个网络接口可以有很多(虚拟)IP地址。操作系统的路由子系统决定使用哪个网络接口和IP地址连接到远程机器。

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

当中的其他解决方案连接到VPN:用途“Sys::Hostname
(工程如果Sys::Hostname来了一个解析的主机名)

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

我有很好的成功与IO::Interface在Linux和Solaris,我认为它甚至在AIX上的工作,但我不记得是肯定的。在search.cpan.org,rt.cpan.org和ActiveState的各个站点上浏览,看起来IO :: Interface可能在Windows上遇到构建问题。我想知道它是否可用的唯一方法是在PPM中搜索io-interface。

13

在我的情况下,我需要一个没有任何非核心依赖关系的解决方案。我想出了这个中的Net ::地址:: IP ::本地就读的代码之后:

#!/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服务器。

5

要检索的所有接口的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过滤。

0

窗户我用

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没那么有用。

0

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

hostname -i 
hostname -I 
ls /sys/class/net 
ip -f inet addr show eth0| grep -Po 'inet \K[\d.]+' 
相关问题