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

gethostent#

Ανακτά την επόμενη εγγραφή από τη βάση δεδομένων υπολογιστών.

gethostent walks the host database - on traditional Unix systems the /etc/hosts file, on modern systems whatever NSS source is configured

  • returning one record per call until the database is exhausted. Use it when you want to enumerate every known host, not when you want to resolve a single name: gethostbyname is the right tool for a targeted lookup.

Ο δρομέας επανάληψης μοιράζεται με τις sethostent (που τον επαναφέρει) και endhostent (που τον κλείνει). Ανάμεσα σε αυτές τις δύο κλήσεις, η gethostent αποδίδει κάθε εγγραφή με τη σειρά και κατόπιν επιστρέφει την κενή λίστα (ή undef σε βαθμωτό περιβάλλον) μόλις φτάσει στο τέλος της βάσης δεδομένων.

Σύνοψη#

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

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

Σε περιβάλλον λίστας - μια λίστα πέντε στοιχείων που αντιστοιχεί στο C struct hostent:

  • $name - το κανονικοποιημένο hostname για αυτή την εγγραφή.

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

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

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

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

Στο τέλος της βάσης δεδομένων η επιστροφή είναι η κενή λίστα. Διάκριση που αξίζει να θυμάστε: η σημείωση του upstream perlfunc ότι μια εγγραφή που λείπει μπορεί να επιστρέψει «a single meaningless true value» αφορά τις αναζητήσεις κατά όνομα και κατά διεύθυνση, όχι την gethostent - η επανάληψη πέρα από το τέλος είναι μια καθαρή κενή λίστα.

Σε βαθμωτό περιβάλλον - μόνο το κανονικοποιημένο $name, ή undef στο τέλος της βάσης δεδομένων. Χρησιμοποιήστε περιβάλλον λίστας όποτε χρειάζεστε οτιδήποτε πέρα από το όνομα· η ανασύνθεση των υπόλοιπων πεδίων εκ των υστέρων δεν είναι δυνατή.

Μετατροπή πακεταρισμένης διεύθυνσης από τον @addrs με Socket::inet_ntoa για IPv4 ή απευθείας με unpack:

use Socket;
print inet_ntoa($addrs[0]), "\n";

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

  • Τον δρομέα της βάσης δεδομένων υπολογιστών, που μοιράζεται με τις sethostent, endhostent, gethostbyname και gethostbyaddr. Μια αναζήτηση κατά όνομα ή κατά διεύθυνση μπορεί να επαναφέρει ή να καταστήσει άκυρο έναν δρομέα που έχει αφεθεί στο μέσο επανάληψης από την gethostent· μη διαπλέκετε τα δύο στυλ χωρίς νέα sethostent ανάμεσα.

  • $? - τίθεται στην τιμή h_errno της C σε αποτυχία, όπου την εκθέτει η πλατφόρμα. Ένα απλό τέλος της βάσης δεδομένων δεν είναι αποτυχία και αφήνει την $? ανέπαφη.

  • $! - η gethostent είναι επαναλήπτης βάσης δεδομένων, όχι περιτύλιγμα κλήσης συστήματος με την έννοια των open/read. Τα σφάλματα DNS και NSS εμφανίζονται μέσω του h_errno (μέσω της $?), όχι μέσω της $!.

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

Απαρίθμηση κάθε υπολογιστή στη βάση δεδομένων:

use Socket;
sethostent(1);
while (my ($name, $aliases, $type, $len, @addrs) = gethostent) {
    my @dotted = map { inet_ntoa($_) } @addrs;
    print "$name  @dotted\n";
}
endhostent;

Βαθμωτό περιβάλλον - απαρίθμηση μόνο των κανονικοποιημένων ονομάτων:

sethostent(0);
while (defined(my $name = gethostent)) {
    print "$name\n";
}
endhostent;

Χτίσιμο ενός κατακερματισμού όνομα-προς-διεύθυνση σε ένα πέρασμα, και κατόπιν τοπική αναζήτηση εγγραφών χωρίς περαιτέρω κλήσεις DNS:

use Socket;
my %ip_of;
sethostent(1);
while (my ($name, $aliases, undef, undef, @addrs) = gethostent) {
    next unless @addrs;
    $ip_of{$name} = inet_ntoa($addrs[0]);
    $ip_of{$_}    = inet_ntoa($addrs[0]) for split ' ', $aliases;
}
endhostent;

print $ip_of{"localhost"} // "not in hosts DB", "\n";

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

use Net::hostent;
while (my $h = gethostent) {
    printf "%-30s %s\n", $h->name, join(",", @{$h->aliases});
}

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

  • Δεν υπάρχει έμμεση επαναφορά. Η gethostent δεν ανοίγει ούτε επαναφέρει η ίδια τη βάση δεδομένων. Η πρώτη κλήση μετά την έναρξη του προγράμματος λειτουργεί επειδή η βιβλιοθήκη C ανοίγει νωχελικά τη βάση δεδομένων, αλλά μόλις φτάσετε στο τέλος οι περαιτέρω κλήσεις συνεχίζουν να επιστρέφουν τέλος-βάσης μέχρι μια sethostent να επαναφέρει τον δρομέα. Πάντα συνδυάζετε την απαρίθμηση με ρητές sethostent / endhostent.

  • Όρισμα STAYOPEN προς την sethostent. Το πέρασμα αληθούς τιμής ζητά από τη βιβλιοθήκη να κρατήσει το αρχείο της βάσης δεδομένων ανοιχτό μεταξύ αναζητήσεων, πράγμα που έχει σημασία για πηγές NSS που διαφορετικά επανασυνδέονται σε κάθε κλήση. Το πέρασμα 0 επιτρέπει στη βιβλιοθήκη να κλείσει και να ανοίξει εκ νέου μεταξύ κλήσεων.

  • Το τέλος της βάσης δεδομένων είναι η κενή λίστα, όχι το undef. Σε περιβάλλον λίστας η συνθήκη βρόχου while (my @r = gethostent) λειτουργεί επειδή η κενή λίστα είναι ψευδής. Σε βαθμωτό περιβάλλον χρησιμοποιήστε while (defined(my $name = gethostent)) - ένα hostname "0" είναι θεωρητικά έγκυρο και θα τερμάτιζε ψευδώς έναν βρόχο βασισμένο σε αλήθεια.

  • Ο @addrs μπορεί να είναι κενός ακόμη και για επιστρεφόμενη εγγραφή σε ορισμένα NSS backends. Προστατέψτε το βήμα αποπακεταρίσματος διεύθυνσης:

    next unless @addrs;
    
  • Τα aliases είναι ένα βαθμωτό, όχι λίστα. Το $aliases είναι μία μεμονωμένη συμβολοσειρά διαχωρισμένη με κενά. Διασπάστε σε λευκούς χαρακτήρες αν θέλετε λίστα.

  • Μείγμα πηγών NSS. Σε συστήματα βασισμένα σε glibc, η βάση δεδομένων hosts μπορεί να αντλεί από το /etc/hosts, το DNS, το mDNS και άλλα αρθρώματα NSS ανάλογα με το nsswitch.conf. Τα αρθρώματα NSS με backend DNS συνήθως δεν απαριθμούν - η gethostent σε βάση δεδομένων hosts μόνο μέσω DNS επιστρέφει την κενή λίστα αμέσως. Στις περισσότερες πραγματικές αναπτύξεις μόνο η πηγή files συνεισφέρει εγγραφές στην επανάληψη.

  • Διαπλοκή με αναζητήσεις κατά όνομα / κατά διεύθυνση. Μια κλήση gethostbyname ή gethostbyaddr μπορεί να επαναφέρει τον κοινόχρηστο δρομέα. Ολοκληρώστε πρώτα την επανάληψη, ή επανεκκινήστε την με sethostent μετά την αναζήτηση.

  • Ασφάλεια threads. Η υποκείμενη ρουτίνα C διατηρεί στατική κατάσταση ανά διεργασία για τον δρομέα επανάληψης. Ταυτόχρονες κλήσεις από πολλαπλά threads διαπλέκουν τα αποτελέσματα απρόβλεπτα. Περιορίστε την απαρίθμηση σε ένα μόνο thread.

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

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

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

  • sethostent - επαναφέρει τον επαναλήπτη και ελέγχει αν η βάση δεδομένων παραμένει ανοιχτή μεταξύ κλήσεων

  • endhostent - κλείνει τον επαναλήπτη και απελευθερώνει το handle της βάσης δεδομένων

  • gethostbyname - στοχευμένη αναζήτηση κατά όνομα αντί για πλήρη απαρίθμηση

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

  • getnetent - ίδιο μοτίβο επανάληψης για τη βάση δεδομένων δικτύων

  • Socket::inet_ntoa - μετατρέπει πακεταρισμένη διεύθυνση από τον @addrs σε συμβολοσειρά dotted-quad