2008-10-02 27 views
3

我有一個(從我可以告訴)完美工作的Linux安裝程序(Ubuntu 8.04),其中所有工具(nslookup,curl,wget,firefox等)都能夠解析地址。然而,下面的代碼失敗:Perl套接字在Linux下如何解析主機名?

$s = new IO::Socket::INET(
    PeerAddr => 'stackoverflow.com', 
    PeerPort => 80, 
    Proto => 'tcp', 
); 

die "Error: $!\n" unless $s; 

我覈實了以下幾件事:

  • Perl是能夠與gethostbyname將地址(即低於作品的代碼):

    my $ret = gethostbyname('stackoverflow.com'); print inet_ntoa($ret);

  • 原始源代碼在Windows下運行

  • 這是它應該如何工作(即。它應該解析主機名),因爲LWP試圖使用這種行爲(實際上,我試圖調試LWP爲什麼不能爲我工作),但我試圖調試這個問題
  • 運行腳本不會發出DNS請求(所以它不會甚至不試圖解決名稱)。使用Wireshark
  • 驗證

回答

7

從快看,從IO ::插座:: INET下面的代碼

sub _get_addr { 
    my($sock,$addr_str, $multi) = @_; 
    my @addr; 
    if ($multi && $addr_str !~ /^\d+(?:\.\d+){3}$/) { 
     (undef, undef, undef, undef, @addr) = gethostbyname($addr_str); 
    } else { 
     my $h = inet_aton($addr_str); 
     push(@addr, $h) if defined $h; 
    } 
    @addr; 
} 

建議(如果你看一下這個代碼的調用者)加入到MultiHomed => 1,的變通你的代碼。

沒有這種解決方法,上面的代碼似乎嘗試使用Socket.pm中的inet_aton()調用inet_aton("hostname.com")。這在Win32和Unix中都適合我,所以我想這就是破解對你來說的地方。

爲INET_ATON的源代碼見Socket.xs

void 
inet_aton(host) 
    char * host 
    CODE: 
    { 
     struct in_addr ip_address; 
     struct hostent * phe; 

     if (phe = gethostbyname(host)) { 
      Copy(phe->h_addr, &ip_address, phe->h_length, char); 
     } else { 
      ip_address.s_addr = inet_addr(host); 
     } 

     ST(0) = sv_newmortal(); 
     if(ip_address.s_addr != INADDR_NONE) { 
      sv_setpvn(ST(0), (char *)&ip_address, sizeof ip_address); 
     } 
    } 

看來,Perl中的gethostbyname()的作品比C的gethostbyname()爲您做得更好。

+0

是的!是!是! :-)這是問題所在。非常感謝你的解決方案。現在我要弄清楚的是如何說服LWP創建一個特殊的socked(啓用multihomed選項)。 – 2008-10-02 05:26:30

-1

請確保您有說法

use IO::Socket::INET; 

在您的源代碼開頭。如果你離開了這一點,你可能收到錯誤消息:

通過 包「IO ::插座:: INET」

除了無法找到對象的方法「新」,你可能使用Net :: DNS :: Resoler驗證DNS是否正在工作,請參閱更多信息here

use Net::DNS; 

my $res = Net::DNS::Resolver->new; 

# Perform a lookup, using the searchlist if appropriate. 
my $answer = $res->search('example.com'); 
+0

我在腳本的開頭有use語句。此外,我已經嘗試了第二個測試腳本,它的工作原理(就像預期的那樣,考慮到gethostbyname的作用),但我仍然有原始問題。 – 2008-10-02 05:02:52

0

請問您是否可以告訴我們您的代碼如何失敗?你有錯誤檢查代碼,但你沒有報告錯誤是什麼!

我剛剛嘗試了原始代碼(在我的Mac OS X機器上增加了「使用IO :: Socket :: INET」,它工作正常。

我懷疑Multihomed選項是一個不必要的黑客攻擊,其他問題是您的問題的根源。