3

すべてのツール (nslookup、curl、wget、firefox など) がアドレスを解決できる完全に機能する Linux セットアップ (Ubuntu 8.04) を (私が知る限り) 持っています。ただし、次のコードは失敗します。

$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 で検証済み
4

3 に答える 3

7

ざっと見てみると、IO::Socket::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,する回避策を提案します。

この回避策がないと、上記のコードinet_aton("hostname.com")は Socket.pm から inet_aton() を使用して呼び出そうとしているように見えます。それは 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() よりもうまく機能するようです。

于 2008-10-02T05:11:35.577 に答える
0

コードがどのように失敗するかを正確に教えていただけますか?そこにエラーチェックコードがありますが、エラーが何であるかを報告していません!

元のコードを試しました(MacOSXマシンに「useIO::Socket :: INET」を追加すると、正常に動作します。

マルチホームオプションは不要なハックであり、他の問題が問題の根本的な原因であると思われます。

于 2008-10-06T16:36:59.297 に答える
-1

ステートメントがあることを確認してください

use IO::Socket::INET;

ソース コードの先頭。これを省略すると、おそらく次のエラー メッセージが表示されます。

パッケージ「IO::Socket::INET」を介してオブジェクトメソッド「new」を見つけることができません

さらに、Net::DNS::Resoler を使用して DNS が機能していることを確認することもできます。詳細については、こちらを参照してください。

use Net::DNS;

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

# Perform a lookup, using the searchlist if appropriate.
my $answer = $res->search('example.com');
于 2008-10-02T04:44:17.530 に答える