Πληροφορίες δικτύου

gethostbyname#

Αναζητά μια εγγραφή host με βάση το όνομα DNS.

Η gethostbyname επιλύει ένα όνομα host στις διευθύνσεις IP του και στην κανονική εγγραφή καλώντας τη ρουτίνα C gethostbyname(3) του συστήματος. Η τυπική περίπτωση χρήσης - «δώσε μου την πακεταρισμένη IP αυτού του host» - θέλει τη μορφή βαθμωτού περιβάλλοντος και τίποτε άλλο. Η μορφή περιβάλλοντος λίστας εκθέτει την πλήρη εγγραφή host: κανονικό όνομα, ψευδώνυμα, οικογένεια διευθύνσεων, μήκος διεύθυνσης και κάθε καταχωρισμένη διεύθυνση.

Σύνοψη#

my $packed_ip = gethostbyname $name;
my ($name, $aliases, $addrtype, $length, @addrs) = gethostbyname $name;

Τι επιστρέφεται#

Βαθμωτό περιβάλλον - την πρώτη διεύθυνση IP ως πακεταρισμένη δυαδική συμβολοσειρά (τέσσερα bytes για IPv4, δεκαέξι για IPv6), ή undef αν αποτύχει η αναζήτηση. Μετατρέψτε σε τετράδα με τελείες με Socket::inet_ntoa:

use Socket;
my $packed = gethostbyname("www.perl.org");
my $dotted = inet_ntoa($packed) if defined $packed;

Περιβάλλον λίστας - λίστα πέντε στοιχείων που αντικατοπτρίζει τη struct hostent της C:

  • $name - το κανονικό όνομα host.

  • $aliases - συμβολοσειρά εναλλακτικών ονομάτων διαχωρισμένη με κενά.

  • $addrtype - η οικογένεια διευθύνσεων, τυπικά AF_INET (2) ή AF_INET6 (10).

  • $length - το μήκος κάθε διεύθυνσης σε bytes (4 για IPv4, 16 για IPv6).

  • @addrs - κάθε διεύθυνση που επιστρέφεται για το όνομα, καθεμία πακεταρισμένη δυαδική συμβολοσειρά μήκους $length bytes.

Σε αποτυχία αναζήτησης σε περιβάλλον λίστας, η επιστροφή είναι η κενή λίστα.

Καθολική κατάσταση που επηρεάζει#

  • $? - τίθεται στην τιμή h_errno της C σε αποτυχία, όταν η πλατφόρμα την εκθέτει. Ελέγξτε με $? != 0 για να διακρίνετε το «δεν υπάρχει τέτοιος host» (HOST_NOT_FOUND) από το «δοκιμάστε ξανά» (TRY_AGAIN) και παρόμοια.

  • Ο δρομέας επανάληψης της βάσης δεδομένων host που μοιράζεται με τις gethostent, sethostent και endhostent. Μια κλήση της gethostbyname μπορεί να επαναφέρει έναν δρομέα που άφησε ανοιχτό η gethostent.

Παραδείγματα#

Βαθμωτή μορφή - η συνηθισμένη περίπτωση:

use Socket;
my $packed = gethostbyname("localhost");
defined $packed or die "cannot resolve localhost: $!";
print inet_ntoa($packed), "\n";      # 127.0.0.1

Μορφή λίστας - απαριθμήστε κάθε διεύθυνση για έναν πολυσυνδεδεμένο host:

use Socket;
my ($name, $aliases, $type, $len, @addrs) = gethostbyname("www.example.com");
for my $addr (@addrs) {
    print inet_ntoa($addr), "\n";
}

Αποπακετάρετε χειρωνακτικά μια διεύθυνση IPv4, χωρίς το Socket:

my $packed = gethostbyname("127.0.0.1");
my ($a, $b, $c, $d) = unpack("W4", $packed);
print "$a.$b.$c.$d\n";               # 127.0.0.1

Μπροστινή και έπειτα αντίστροφη - επιλύστε ένα όνομα, και έπειτα ψάξτε πίσω τη διεύθυνση:

use Socket;
my $packed = gethostbyname("www.perl.org");
my $back   = gethostbyaddr($packed, AF_INET);
print "$back\n";

Διεπαφή ανά όνομα μέσω της υπερκάλυψης Net::hostent - μέθοδοι προσπέλασης αντί για αποπακετάρισμα κατά θέση:

use Net::hostent;
my $h = gethostbyname("www.perl.org");
print $h->name, " ", join(",", @{$h->aliases}), "\n";

Οριακές περιπτώσεις#

  • Καλέστε πάντα σε βαθμωτό περιβάλλον όταν θέλετε «την IP». Η μορφή περιβάλλοντος λίστας δεν είναι ποτέ αυτό που θέλει ένας γρήγορος resolver και εκχωρεί τέσσερις επιπλέον τιμές επιστροφής. Τα upstream έγγραφα το επισημαίνουν ρητά: «Βεβαιωθείτε ότι η gethostbyname καλείται σε SCALAR περιβάλλον και ότι η τιμή επιστροφής της ελέγχεται για ορισμένο.»

  • Ελέγξτε για undef στη βαθμωτή μορφή. Μια αποτυχημένη αναζήτηση επιστρέφει undef, όχι κενή συμβολοσειρά. Αντιθέτως, μια κυριολεκτική διεύθυνση 0.0.0.0 είναι έγκυρη πακεταρισμένη συμβολοσειρά τεσσάρων bytes και μετατρέπεται σε συμβολοσειρά ως ακολουθία μηδενικών bytes, όχι σε undef.

  • Ο @addrs μπορεί να είναι κενός σε περιβάλλον λίστας ακόμη και όταν οι πρώτες τέσσερις τιμές επιστροφής είναι ορισμένες - ορισμένοι resolvers παράγουν εγγραφή χωρίς διευθύνσεις. Επαναλάβετε πάντα, μην ευρετηριάζετε [0] τυφλά.

  • Τα ψευδώνυμα είναι ένα βαθμωτό, όχι λίστα. Το $aliases είναι μία συμβολοσειρά διαχωρισμένη με κενά. Διαχωρίστε σε λευκούς χαρακτήρες αν χρειάζεστε λίστα.

  • Οι αριθμητικές συμβολοσειρές IP γίνονται δεκτές. Το πέρασμα του "127.0.0.1" επιστρέφει την πακεταρισμένη μορφή αυτής της διεύθυνσης χωρίς πλήρη κύκλο DNS - ο resolver βραχυκυκλώνει την αριθμητική είσοδο.

  • IPv6. Η gethostbyname ερωτά μόνο την οικογένεια διευθύνσεων IPv4 (AF_INET). Για επίλυση διπλής στοίβας χρησιμοποιήστε την Socket::getaddrinfo, που επιστρέφει εγγραφές για κάθε οικογένεια διευθύνσεων που προσφέρει ο host.

  • Ασφάλεια threads. Η υποκείμενη ρουτίνα C διατηρεί στατική κατάσταση ανά διεργασία για τον δρομέα του host. Ταυτόχρονες κλήσεις από πολλαπλά threads μπορεί να αναμείξουν αποτελέσματα. Σενάρια που χρειάζονται thread-safe επίλυση πρέπει να χρησιμοποιούν την Socket::getaddrinfo.

  • h_errno έναντι $!. Οι αποτυχίες DNS θέτουν το h_errno (που εκτίθεται μέσω του $?), όχι το errno / $!. Ο έλεγχος του $! μετά από αποτυχημένη gethostbyname είναι χωρίς νόημα.

Διαφορές από το upstream#

Πλήρως συμβατό με το upstream Perl 5.42.

Δείτε επίσης#

  • gethostbyaddr - η αντίστροφη αναζήτηση: πακεταρισμένη διεύθυνση → εγγραφή host

  • gethostent - επαναλάβετε κάθε εγγραφή στη βάση δεδομένων host αντί να αναζητήσετε ένα όνομα

  • sethostent - επαναφέρετε στην αρχή τον επαναλήπτη host και ελέγξτε αν το αρχείο παραμένει ανοιχτό μεταξύ αναζητήσεων

  • Socket::inet_ntoa - μετατρέψτε το πακεταρισμένο αποτέλεσμα βαθμωτού περιβάλλοντος σε συμβολοσειρά τετράδας με τελείες

  • Socket::inet_aton - ο καθαρός βοηθός ονόματος-προς-πακεταρισμένο όταν δεν χρειάζεστε την πλήρη εγγραφή host

  • unpack - αποκωδικοποιήστε χειρωνακτικά την πακεταρισμένη διεύθυνση όταν δεν είναι διαθέσιμο το Socket