gethostbyaddr#
Αναζητά μια εγγραφή host με βάση την πακεταρισμένη διεύθυνση IP του.
Η gethostbyaddr εκτελεί αντίστροφη αναζήτηση DNS: δοθείσας μιας πακεταρισμένης δυαδικής διεύθυνσης (τέσσερα bytes για IPv4, δεκαέξι για IPv6) και της αντίστοιχης οικογένειας διευθύνσεων, καλεί τη ρουτίνα C gethostbyaddr(3) του συστήματος και επιστρέφει την εγγραφή host. Η τυπική περίπτωση χρήσης - «από ποιανού μηχάνημα είναι αυτό το πακέτο;» - θέλει τη μορφή βαθμωτού περιβάλλοντος: ένα μοναδικό όνομα host. Η μορφή περιβάλλοντος λίστας εκθέτει την πλήρη struct hostent: κανονικό όνομα, ψευδώνυμα, οικογένεια διευθύνσεων, μήκος διεύθυνσης και κάθε διεύθυνση που γνωρίζει ο resolver για αυτόν τον host.
Σύνοψη#
my $name = gethostbyaddr $packed_addr, $addrtype;
my ($name, $aliases, $addrtype, $length, @addrs) = gethostbyaddr $packed_addr, $addrtype;
Τι επιστρέφεται#
Βαθμωτό περιβάλλον - το κανονικό όνομα host ως απλή συμβολοσειρά, ή undef αν αποτύχει η αντίστροφη αναζήτηση.
Περιβάλλον λίστας - λίστα πέντε στοιχείων που αντικατοπτρίζει τη struct hostent της C:
$name- το κανονικό όνομα host στο οποίο αντιστοίχισε τη διεύθυνση ο resolver.$aliases- συμβολοσειρά εναλλακτικών ονομάτων διαχωρισμένη με κενά. Ένα βαθμωτό, όχι λίστα.$addrtype- η οικογένεια διευθύνσεων των επιστρεφόμενων διευθύνσεων, τυπικάAF_INET(2) ήAF_INET6(10).$length- το μήκος κάθε διεύθυνσης σε bytes (4για IPv4,16για IPv6).@addrs- κάθε διεύθυνση που επιστρέφεται για τον host, καθεμία πακεταρισμένη δυαδική συμβολοσειρά μήκους$lengthbytes. Συχνά μόνο μία, αλλά πολυσυνδεδεμένοι hosts μπορούν να αποδώσουν περισσότερες.
Σε αποτυχία αναζήτησης σε περιβάλλον λίστας, η επιστροφή είναι η κενή λίστα.
Καθολική κατάσταση που επηρεάζει#
$?- τίθεται στην τιμήh_errnoτης C σε αποτυχία, όταν η πλατφόρμα την εκθέτει. Ελέγξτε με$? != 0για να διακρίνετε τοHOST_NOT_FOUNDαπό τοTRY_AGAINκαι παρόμοια παροδικά σφάλματα.$!- δεν τίθεται με ουσιαστικό τρόπο από αποτυχίες DNS. Οι αντίστροφες αναζητήσεις αποτυγχάνουν μέσωh_errno, όχιerrno· μην ελέγχετε το$!μετά από αποτυχημένη κλήση.Ο δρομέας επανάληψης της βάσης δεδομένων host που μοιράζεται με τις
gethostent,sethostentκαιendhostent. Μια κλήση τηςgethostbyaddrμπορεί να επαναφέρει έναν δρομέα που άφησε ανοιχτό ηgethostent.
Παραδείγματα#
Βαθμωτή μορφή - αντιστοίχιση μιας τετράδας με τελείες σε όνομα host:
use Socket;
my $packed = inet_aton("127.0.0.1");
my $name = gethostbyaddr($packed, AF_INET);
print defined $name ? "$name\n" : "no PTR record\n";
Πλήρης κύκλος - μπροστινή αναζήτηση, και μετά αντιστροφή της πρώτης διεύθυνσης:
use Socket;
my $packed = gethostbyname("www.perl.org");
my $name = gethostbyaddr($packed, AF_INET);
print "$name\n";
Αναγνωρίστε τον ομότιμο σε αποδεκτή σύνδεση υποδοχής:
use Socket;
my $peer = getpeername($sock);
my ($port, $iaddr) = sockaddr_in($peer);
my $host = gethostbyaddr($iaddr, AF_INET);
printf "connection from %s:%d\n", $host // inet_ntoa($iaddr), $port;
Μορφή λίστας - κάθε όνομα και διεύθυνση που γνωρίζει ο resolver για τον host:
use Socket;
my $packed = inet_aton("8.8.8.8");
my ($name, $aliases, $type, $len, @addrs) = gethostbyaddr($packed, AF_INET);
print "canonical: $name\n";
print "aliases: $_\n" for split ' ', $aliases;
print "address: ", inet_ntoa($_), "\n" for @addrs;
Διεπαφή ανά όνομα μέσω της υπερκάλυψης Net::hostent - μέθοδοι προσπέλασης αντί για αποπακετάρισμα κατά θέση:
use Net::hostent;
use Socket;
my $h = gethostbyaddr(inet_aton("127.0.0.1"), AF_INET);
print $h->name, "\n" if $h;
Οριακές περιπτώσεις#
Η
ADDRείναι πακεταρισμένη δυαδική συμβολοσειρά, όχι τετράδα με τελείες. Το άμεσο πέρασμα"127.0.0.1"δεν λειτουργεί - η Perl θα καλέσει τον resolver με εννέα ακατέργαστα bytes και δεν θα λάβει τίποτα χρήσιμο. Περάστε πάντοτε πρώτα από τιςSocket::inet_aton,Socket::inet_pton, ή ισοδύναμο packer.Το
ADDRTYPEπρέπει να ταιριάζει με το πλάτος της διεύθυνσης. ΗAF_INETθέλειADDRτεσσάρων bytes· ηAF_INET6δεκαέξι. Μια αναντιστοιχία είτε επιστρέφειundef, είτε σε ορισμένες πλατφόρμες διαβάζει πέρα από τον ενταμιευτή. Χρησιμοποιήστε τη σταθερά από τοSocket, όχι έναν χειρωνακτικά γραμμένο ακέραιο.Ελέγξτε για
undefστη βαθμωτή μορφή. Μια εγγραφή PTR που λείπει επιστρέφειundef, όχι κενή συμβολοσειρά. Πολλές διευθύνσεις στο δημόσιο internet δεν έχουν καθόλου αντίστροφη αντιστοίχιση.Ο
@addrsμπορεί να μην περιλαμβάνει τη διεύθυνση που ρωτήσατε. Ο resolver επιστρέφει την πλήρη εγγραφή για τον κανονικό host, που μπορεί να περιέχει επιπλέον διευθύνσεις που τυχαίνει να μοιράζονται το όνομα host.Το βαθμωτό περιβάλλον εκτελεί ούτως ή άλλως την πλήρη κλήση resolver. Η ρουτίνα C πάντα συμπληρώνει ολόκληρη την
hostent· η Perl απλώς απορρίπτει τη λίστα. Δεν υπάρχει πλεονέκτημα απόδοσης στη βαθμωτή μορφή πέραν από τον σαφέστερο κώδικα.Η αντιστροφή μιας μπροστινής αναζήτησης δεν εγγυάται πλήρη κύκλο. Η
gethostbyaddr(gethostbyname($h), AF_INET)μπορεί να επιστρέψει διαφορετικό όνομα από το$h- το αντίστροφο DNS αντιστοιχίζει στο κανονικό όνομα host, που συχνά διαφέρει από το ψευδώνυμο που χρησιμοποίησε η μπροστινή ερώτηση.Η υποστήριξη IPv6 εξαρτάται από την πλατφόρμα. Δεν χειρίζεται κάθε
gethostbyaddr(3)της libc τηνAF_INET6καθαρά. Για φορητή αντίστροφη επίλυση διπλής στοίβας χρησιμοποιήστε τηνSocket::getnameinfo.Ασφάλεια threads. Η υποκείμενη ρουτίνα C διατηρεί στατική κατάσταση ανά διεργασία για τον δρομέα του host. Ταυτόχρονες κλήσεις από πολλαπλά threads μπορεί να αναμείξουν αποτελέσματα. Σενάρια που χρειάζονται thread-safe αντίστροφη επίλυση πρέπει να χρησιμοποιούν την
Socket::getnameinfo.
Διαφορές από το upstream#
Πλήρως συμβατό με το upstream Perl 5.42.
Δείτε επίσης#
gethostbyname- η μπροστινή αναζήτηση: όνομα host → πακεταρισμένη διεύθυνσηgethostent- επαναλάβετε κάθε εγγραφή στη βάση δεδομένων host αντί να αναζητήσετε μία διεύθυνσηsethostent- επαναφέρετε στην αρχή τον επαναλήπτη host και ελέγξτε αν το αρχείο παραμένει ανοιχτό μεταξύ αναζητήσεωνSocket::inet_aton- δημιουργήστε το πακεταρισμένο όρισμαADDRαπό συμβολοσειρά τετράδας με τελείεςSocket::inet_ntoa- αποδώστε μια πακεταρισμένη διεύθυνση από τον@addrsπίσω σε μορφή τετράδας με τελείεςSocket::getnameinfo- σύγχρονος, ανεξάρτητος πρωτοκόλλου αντίστροφος resolver που χειρίζεται IPv6 και είναι thread-safe