2008-12-01 160 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.]+' 
相關問題