socketpair#
Δημιουργεί ένα ανώνυμο, συνδεδεμένο ζεύγος υποδοχών που μιλούν μεταξύ τους.
Η socketpair ανοίγει δύο φρέσκα filehandles στα SOCKET1 και SOCKET2 ήδη συνδεδεμένα μεταξύ τους, οπότε ο,τιδήποτε γράφεται στο ένα βγαίνει από το άλλο. Καμία διεύθυνση, κανένα bind, κανένα listen, κανένα accept. Η συνηθέστερη χρήση είναι η επικοινωνία με παιδική διεργασία δημιουργημένη από fork - κάθε πλευρά κρατά ένα handle και κλείνει το άλλο με close.
Σύνοψη#
use Socket;
socketpair(SOCKET1, SOCKET2, DOMAIN, TYPE, PROTOCOL) or die $!;
socketpair(my $s1, my $s2, AF_UNIX, SOCK_STREAM, PF_UNSPEC) or die $!;
Τι επιστρέφεται#
Αληθές σε επιτυχία, ψευδές σε αποτυχία (με ορισμένη την $!). Σε επιτυχία και τα δύο ορίσματα filehandle συμπληρώνονται με φρέσκα handles· σε αποτυχία μένουν άθικτα. Ελέγχετε πάντα την τιμή επιστροφής - κάθε συνδυασμός domain/type/protocol εξαρτάται από την πλατφόρμα.
socketpair(my $a, my $b, AF_UNIX, SOCK_STREAM, PF_UNSPEC)
or die "socketpair: $!";
Οι σταθερές DOMAIN, TYPE και PROTOCOL προέρχονται από το άρθρωμα Socket. Το AF_UNIX με SOCK_STREAM και PF_UNSPEC είναι η φορητή προεπιλογή.
Καθολική κατάσταση που επηρεάζει#
Η
$!ορίζεται σε αποτυχία στοerrnoτου συστήματος.$^F- ο μέγιστος περιγραφέας αρχείου συστήματος κάτω από τον οποίο το close-on-exec δεν τίθεται. Σε συστήματα μεFD_CLOEXEC, οι περιγραφείς πάνω από την$^Fαποκτούν αυτόματα close-on-exec· κάτω από αυτήν, επιβιώνουν στοexec. Η προεπιλογή είναι2(stdin/stdout/stderr). Αυξήστε την πριν τηνsocketpairαν θέλετε τα νέα handles να κληρονομούνται κατά τηνexec.
Παραδείγματα#
Απλή σωλήνωση γονέα/παιδιού με socketpair ροής. Κάθε πλευρά κλείνει την άκρη που δεν χρειάζεται, ώστε το EOF να διαδίδεται σωστά:
use Socket;
socketpair(my $child, my $parent, AF_UNIX, SOCK_STREAM, PF_UNSPEC)
or die "socketpair: $!";
my $pid = fork // die "fork: $!";
if ($pid == 0) {
close $child;
print $parent "hello from child\n";
close $parent;
exit;
}
close $parent;
chomp(my $msg = <$child>); # "hello from child"
waitpid $pid, 0;
Αμφίδρομη ροή: και οι δύο διεργασίες διαβάζουν και γράφουν στο ίδιο handle. Δεν χρειάζεται shutdown επειδή καμία πλευρά δεν κλείνει μια κατεύθυνση πρόωρα:
use Socket;
socketpair(my $a, my $b, AF_UNIX, SOCK_STREAM, PF_UNSPEC) or die $!;
my $pid = fork // die $!;
if ($pid == 0) {
close $a;
while (my $line = <$b>) {
chomp $line;
print $b "echo: $line\n";
}
exit;
}
close $b;
print $a "ping\n";
chomp(my $reply = <$a>); # "echo: ping"
close $a;
waitpid $pid, 0;
Εξομοίωση της pipe με socketpair. Η shutdown μετατρέπει μια αμφίδρομη υποδοχή σε μονόδρομο κανάλι:
use Socket;
socketpair(my $rdr, my $wtr, AF_UNIX, SOCK_STREAM, PF_UNSPEC) or die $!;
shutdown($rdr, 1); # reader cannot write
shutdown($wtr, 0); # writer cannot read
Ζεύγος datagram - τα μηνύματα διατηρούν τα όρια, οπότε μία recv επιστρέφει ακριβώς μία send:
use Socket;
socketpair(my $a, my $b, AF_UNIX, SOCK_DGRAM, PF_UNSPEC) or die $!;
send($a, "one", 0) or die $!;
send($a, "two", 0) or die $!;
recv($b, my $m1, 64, 0); # "one"
recv($b, my $m2, 64, 0); # "two"
Οριακές περιπτώσεις#
Το
AF_UNIXείναι το μόνο φορητό domain. Στα περισσότερα συστήματα ηsocketpairλειτουργεί μόνο μεAF_UNIX· άλλες οικογένειες επιστρέφουνEAFNOSUPPORT. Χρησιμοποιήστε τη σταθερά, όχι σκληρά κωδικοποιημένο1.Έξοδος χωρίς ενταμίευση. Τα handles ροής socketpair ενταμιεύουν όπως κάθε άλλο filehandle. Θέστε την
$|στον εγγραφέα (αφού τον επιλέξετε μεselect) αλλιώς ο αναγνώστης θα μπλοκάρει περιμένοντας έξοδο που βρίσκεται ακόμη στον ενταμιευτή του γονέα. Ηautoflushαπό τοIO::Handleείναι η συνήθης μορφή:$parent->autoflush(1);
Κλείστε και τις δύο άκρες αλλιώς το EOF δεν φτάνει ποτέ. Ένα socketpair ροής παραδίδει EOF σε αναγνώστη μόνο αφού κάθε εγγράψιμο αντίγραφο του handle του ομοτίμου κλείσει. Ένα παιδί που ξεχνά να κλείσει με
closeτην άκρη του γονέα θα κρεμάσει τον γονέα στο<$handle>για πάντα.Close-on-exec μέσω της
$^F. Filehandles των οποίων ο αριθμητικός περιγραφέας είναι μεγαλύτερος της$^FαποκτούνFD_CLOEXECσε πλατφόρμες που το υποστηρίζουν, οπότε εξαφανίζονται κατά τηνexec. Αυξήστε την$^Fπριν την κλήση αν το handle πρέπει να επιβιώσει μιαςexec.Μη υλοποιημένη στην πλατφόρμα. Αν η υποκείμενη κλήση συστήματος
socketpair(2)δεν υπάρχει, η perl εγείρει εξαίρεση αντί να επιστρέψει ψευδές. Παγιδέψτε την μεevalαν χρειάζεστε υποχώρηση.Datagram έναντι ροής. Το
SOCK_STREAMείναι προσανατολισμένο σε bytes (χωρίς όρια μηνυμάτων, χρησιμοποιήστε framing με νέα γραμμή ή προθέματα μήκους). ΤοSOCK_DGRAMδιατηρεί τα όρια μηνυμάτων αλλά τα χάνει σιωπηρά αν ο ενταμιευτής λήψης είναι μικρότερος από το μήνυμα.PROTOCOL. ΓιαAF_UNIXτο πρωτόκολλο αγνοείται· τοPF_UNSPEC(ή0) είναι σύμβαση. Ο ορισμός πρωτοκόλλου που δεν ταιριάζει στον συνδυασμό domain/type επιστρέφειEPROTONOSUPPORT.
Διαφορές από το upstream#
Πλήρως συμβατό με το upstream Perl 5.42.
Δείτε επίσης#
socket- δημιουργεί μία υποδοχή όταν μόνο η μία άκρη είναι δική σας (η άλλη έρχεται από το δίκτυο μέσωacceptήconnect)pipe- μονόδρομο κανάλι bytes· ελαφρύτερη από τηνsocketpairαλλά δεν μπορεί να κάνει αμφίδρομη κίνηση σε μία κλήσηsend/recv- I/O προσανατολισμένη σε μηνύματα, απαιτείται για socketpairsSOCK_DGRAMfork- ο τυπικός σύντροφος: μίαsocketpairπριν το fork δίνει σε γονέα και παιδί έτοιμο αγωγόSocket- πηγή τωνAF_UNIX,SOCK_STREAM,SOCK_DGRAM,PF_UNSPECκαι των άλλων σταθερών που περιμένει ηsocketpair$^F- κατώφλι πάνω από το οποίο νέοι περιγραφείς αποκτούν close-on-exec· έχει σημασία όταν τα handles πρέπει να επιβιώσουν μιαςexec