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- κάθε διεύθυνση που επιστρέφεται για το όνομα, καθεμία πακεταρισμένη δυαδική συμβολοσειρά μήκους$lengthbytes.
Σε αποτυχία αναζήτησης σε περιβάλλον λίστας, η επιστροφή είναι η κενή λίστα.
Καθολική κατάσταση που επηρεάζει#
$?- τίθεται στην τιμή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- η αντίστροφη αναζήτηση: πακεταρισμένη διεύθυνση → εγγραφή hostgethostent- επαναλάβετε κάθε εγγραφή στη βάση δεδομένων host αντί να αναζητήσετε ένα όνομαsethostent- επαναφέρετε στην αρχή τον επαναλήπτη host και ελέγξτε αν το αρχείο παραμένει ανοιχτό μεταξύ αναζητήσεωνSocket::inet_ntoa- μετατρέψτε το πακεταρισμένο αποτέλεσμα βαθμωτού περιβάλλοντος σε συμβολοσειρά τετράδας με τελείεςSocket::inet_aton- ο καθαρός βοηθός ονόματος-προς-πακεταρισμένο όταν δεν χρειάζεστε την πλήρη εγγραφή hostunpack- αποκωδικοποιήστε χειρωνακτικά την πακεταρισμένη διεύθυνση όταν δεν είναι διαθέσιμο τοSocket