Frage

Ich habe ein (von dem, was ich sagen kann) perfekt funktionierende Linux-Setup (Ubuntu 8.04), in der alle Werkzeuge (nslookup, Locke, wget, firefox, usw.) sind in der Lage Adressen aufzulösen. Doch der folgende Code nicht:

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

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

Ich überprüft die folgenden Dinge:

  • Perl ist in der Lage Adressen mit gethostbyname (dh der Code unten Werke) zu beheben:

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

  • Der ursprüngliche Quellcode arbeitet unter Windows

  • Dies ist, wie es funktionieren soll (dh. Es sollte Hostnamen auflösen), da LWP versucht, dieses Verhalten zu verwenden (in der Tat ich uppon das Problem stolperte durch zu debuggen versuchen, warum LWP nicht für mich arbeitet)
  • Sie das Skript ausführen nicht DNS-Anfragen emittieren (so ist es nicht einmal versuchen, den Namen aufzulösen). Verifizierte mit Wireshark
War es hilfreich?

Lösung

Von einem kurzen Blick, der folgende Code von 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;
}

schlägt vor, (wenn Sie an dem Aufrufer dieses Code aussehen) die Work-around MultiHomed => 1,, um Ihren Code hinzuzufügen.

Ohne dass Behelfslösung, der obige Code erscheint die INET_ATON () von Socket.pm zu rufen, um zu versuchen inet_aton("hostname.com") verwenden. Das funktioniert für mich in Win32 und Unix, so dass ich denke, das ist, wo der Bruch für Dich liegt.

Siehe Socket.xs für den Quellcode von INET_ATON :

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 );
        }
    }

Es scheint, dass die Perl gethostbyname () funktioniert besser als die C gethostbyname () für Sie.

Andere Tipps

Könnten Sie vielleicht sagen uns genau wie Ihr Code fehlschlägt? Du hast Fehlercode in dort überprüft, aber sie haben nicht berichtet, was der Fehler ist!

Ich habe gerade versucht, den ursprünglichen Code (mit dem Zusatz der „verwenden IO :: Socket :: INET“ auf meinem Mac OS X-Rechner und es funktioniert gut.

Ich vermute, dass die Multihomed Option ist eine unnötige Hack und einige andere Probleme sind die Ursache des Problems.

Stellen Sie sicher, dass Sie die Anweisung haben

use IO::Socket::INET;

Zu Beginn des Quellcodes. Wenn Sie diese aus verlassen, werden Sie wahrscheinlich die Fehlermeldung bekommen:

  

kann nicht gefunden werden Objektmethode „neu“ über   Paket "IO :: Socket :: INET"

Darüber hinaus, dass Sie das DNS überprüfen könnten arbeitet mit Net :: DNS :: Resoler, weitere Informationen finden Sie unter hier .

use Net::DNS;

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

# Perform a lookup, using the searchlist if appropriate.
my $answer = $res->search('example.com');
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top