getprotobyname#
Αναζητά ένα πρωτόκολλο IP βάσει του ονόματος κειμένου του και επιστρέφει την εγγραφή της βάσης δεδομένων του.
Η getprotobyname είναι το περιτύλιγμα της Perl γύρω από την getprotobyname(3) της C library του συστήματος. Δοθέντος ενός ονόματος πρωτοκόλλου όπως "tcp", "udp", ή "icmp", επιστρέφει την αντίστοιχη εγγραφή από τη βάση δεδομένων /etc/protocols του συστήματος (ή όποιο backend κατευθύνει το nsswitch.conf). Η τυπική χρήση είναι η μετατροπή ενός αναγνώσιμου από άνθρωπο ονόματος πρωτοκόλλου στην αριθμητική τιμή που θέλουν οι socket και setsockopt.
Σύνοψη#
getprotobyname NAME
my ($name, $aliases, $proto) = getprotobyname NAME;
my $proto = getprotobyname NAME; # scalar context
Τι επιστρέφεται#
Σε περιβάλλον λίστας, μια λίστα που μοιάζει με τετραστοιχειακή με τρία πεδία:
my ($name, $aliases, $proto) = getprotobyname("tcp");
# $name => canonical name, e.g. "tcp"
# $aliases => space-separated alias list, e.g. "TCP"
# $proto => numeric protocol number, e.g. 6
Σε βαθμωτό περιβάλλον, μόνο τον αριθμητικό αριθμό πρωτοκόλλου ($proto). Αυτή είναι η συνηθισμένη μορφή, επειδή ο αριθμός πρωτοκόλλου είναι ολόκληρος ο λόγος για τον οποίο έγινε η αναζήτηση:
my $tcp = getprotobyname("tcp"); # 6
Αν το πρωτόκολλο δεν βρεθεί, η επιστροφή είναι κενή λίστα σε περιβάλλον λίστας και undef σε βαθμωτό περιβάλλον. Πάντα ελέγχετε την οριστικότητα πριν χρησιμοποιήσετε το αποτέλεσμα - το 0 είναι έγκυρος αριθμός πρωτοκόλλου ("ip"), οπότε ο έλεγχος μόνο για αλήθεια είναι λάθος.
defined(my $tcp = getprotobyname("tcp"))
or die "tcp protocol not in /etc/protocols";
Καθολική κατάσταση που επηρεάζει#
Μοιράζεται τον δρομέα επανάληψης της βάσης δεδομένων πρωτοκόλλων με τις
getprotobynumber,getprotoent,setprotoent, καιendprotoent. Μια κλήση στηνgetprotobynameμπορεί να επανατοποθετήσει ή να επαναφέρει αυτόν τον δρομέα ανάλογα με την C library του συστήματος· μη διαπλέκετε αναζητήσεις βάσει ονόματος με βρόχο επανάληψηςgetprotoent.Σε ορισμένες πλατφόρμες η υποκείμενη
getprotobyname(3)θέτει το$!/errnoσε περίπτωση αποτυχίας. Φορητός κώδικας δεν πρέπει να βασίζεται σε αυτό - αντιμετωπίστε μια απροσδιόριστη επιστροφή ως «δεν βρέθηκε» και προχωρήστε.
Παραδείγματα#
Μετατροπή ονόματος σε αριθμό πρωτοκόλλου για την socket:
use Socket;
my $proto = getprotobyname("tcp")
// die "tcp not configured";
socket(my $sock, PF_INET, SOCK_STREAM, $proto)
or die "socket: $!";
Μορφή λίστας, για να δείτε το κανονικό όνομα και τα ψευδώνυμα που χρησιμοποιεί ένα σύστημα:
my ($name, $aliases, $proto) = getprotobyname("TCP");
print "name=$name aliases=$aliases number=$proto\n";
# name=tcp aliases=TCP number=6
Αμυντική αναζήτηση με εφεδρεία για τα δύο πρωτόκολλα που πραγματικά χρειάζεται κάθε σενάριο:
my %num_for = (tcp => 6, udp => 17, icmp => 1);
sub proto_num {
my ($name) = @_;
return getprotobyname($name) // $num_for{lc $name};
}
Το βαθμωτό περιβάλλον απαιτείται όταν η τιμή επιστροφής τροφοδοτεί έκφραση· το περιβάλλον λίστας θα ισοπεδωνόταν στην περιβάλλουσα λίστα:
my @args = (SOCK_STREAM, scalar getprotobyname("tcp"));
Οριακές περιπτώσεις#
Η ευαισθησία στα πεζά/κεφαλαία εξαρτάται από το σύστημα. Η
getprotobyname(3)της glibc ταιριάζει το κανονικό όνομα και κάθε ψευδώνυμο χωρίς διάκριση πεζών-κεφαλαίων· άλλες C libraries μπορεί να μην το κάνουν. Αν έχει σημασία η φορητότητα, περάστε τη μορφή πεζών ("tcp", όχι"TCP").Ο αριθμός πρωτοκόλλου
0είναι έγκυρος ("ip"). Χρησιμοποιήστεdefined(...), όχι λογική αλήθεια, όταν ελέγχετε για επιτυχία.Δεν είναι το ίδιο με αριθμό θύρας. Η
getprotobyname("http")επιστρέφειundef- το"http"είναι όνομα υπηρεσίας, όχι πρωτοκόλλου. Χρησιμοποιήστε τηνgetservbynameγια αναζητήσεις υπηρεσιών.Η κενή συμβολοσειρά ψευδωνύμου είναι κανονική. Πολλές εγγραφές δεν έχουν ψευδώνυμα· η δεύτερη τιμή επιστροφής είναι τότε η κενή συμβολοσειρά, όχι
undef.Παρενέργειες του δρομέα επανάληψης. Αν το πρόγραμμά σας είναι στη μέση ενός βρόχου
getprotoent, η κλήση τηςgetprotobynameμπορεί να επαναφέρει τον δρομέα και να παραλείψει ή να επαναλάβει εγγραφές. Ολοκληρώστε την επανάληψη, ή αποθηκεύστε την κατάσταση, πριν κάνετε αναζητήσεις βάσει ονόματος.Ασφάλεια threads. Η υποκείμενη κλήση C δεν είναι thread-safe σε κάθε πλατφόρμα - τυπικά χρησιμοποιεί στατικό ενταμιευτή ανά διεργασία. Η Perl μπορεί να χρησιμοποιήσει την επανεισόδιμη μορφή
getprotobyname_rόταν είναι διαθέσιμη, αλλά μην το υποθέτετε.Λείπει η εγγραφή
/etc/protocols. Σε minimal containers η βάση δεδομένων μπορεί να απουσιάζει, οπότε κάθε κλήση επιστρέφειundef. Δομήστε πίνακες πρωτοκόλλων μέσα στον κώδικά σας όταν το περιβάλλον στόχος δεν εγγυάται την παρουσία βάσης πρωτοκόλλων.
Διαφορές από το upstream#
Πλήρως συμβατό με το upstream Perl 5.42.
Δείτε επίσης#
getprotobynumber- η αντίστροφη αναζήτηση· χρησιμοποιήστε την όταν έχετε το αριθμητικό πρωτόκολλο και θέλετε το όνομά τουgetprotoent- επανάληψη σε κάθε εγγραφή της βάσης δεδομένων πρωτοκόλλων μία εγγραφή τη φοράsetprotoent/endprotoent- έλεγχος του δρομέα επανάληψης που μοιράζονται με αυτή τη συνάρτησηgetservbyname- η ισοδύναμη αναζήτηση για υπηρεσίες (θύρες), όχι πρωτόκολλα· τα δύο συγχέονται συχνάsocket- ο συνήθης καταναλωτής του επιστρεφόμενου αριθμού πρωτοκόλλουNet::protoent- αντικειμενοστραφές περιτύλιγμα που επιστρέφει blessed εγγραφή με ονομασμένους accessors αντί για λίστα κατά θέση