recv#
Διαβάζει ένα εισερχόμενο μήνυμα από υποδοχή σε βαθμωτό.
Η recv διαβάζει μέχρι LENGTH bytes από το SOCKET στο SCALAR, αντικαθιστώντας ό,τι κρατούσε προηγουμένως το SCALAR. Το SCALAR μεγαλώνει ή συρρικνώνεται στο πραγματικό πλήθος των bytes που ελήφθησαν. Το FLAGS είναι η ίδια μάσκα bits που δέχεται η υποκείμενη κλήση συστήματος recvfrom(2) - 0 για συνηθισμένες αναγνώσεις· οι συνηθισμένες μη μηδενικές τιμές είναι MSG_PEEK (κοίταγμα χωρίς κατανάλωση), MSG_WAITALL (μπλοκάρισμα μέχρι να φτάσουν LENGTH bytes), και MSG_DONTWAIT (ποτέ μπλοκάρισμα). Για υποδοχή χωρίς σύνδεση η recv επιστρέφει την πακεταρισμένη διεύθυνση του αποστολέα· για συνδεδεμένη υποδοχή επιστρέφει την κενή συμβολοσειρά. Στο παρασκήνιο αυτό είναι η recvfrom(2), όχι η recv(2).
Σύνοψη#
recv SOCKET, SCALAR, LENGTH, FLAGS
Τι επιστρέφεται#
Σε επιτυχία από υποδοχή χωρίς σύνδεση (UDP, UNIX datagram): η διεύθυνση του αποστολέα ως πακεταρισμένη συμβολοσειρά sockaddr. Κάντε unpack με τις
sockaddr_in,sockaddr_in6ήsockaddr_unτουSocketανάλογα με την οικογένεια διευθύνσεων.Σε επιτυχία από συνδεδεμένη υποδοχή (TCP, συνδεδεμένο UDP): η κενή συμβολοσειρά
"". Η κενή συμβολοσειρά είναι αληθής για τον έλεγχο ορισμένου-έναντι-undef αλλά ψευδής σε λογικό περιβάλλον - ελέγξτε μεdefined, όχι με απλή αληθοφάνεια.Σε σφάλμα:
undef, με το$!ρυθμισμένο στοerrnoαπό την αποτυχημένη κλήσηrecvfrom(2). Τυπικά σφάλματα:EAGAIN/EWOULDBLOCKσε μη μπλοκαριστική υποδοχή χωρίς δεδομένα έτοιμα,ECONNRESETσε επαναφορά TCP ομότιμου,EBADFσε κλειστό handle.
Το SCALAR πάντα αλλάζει μέγεθος στο πλήθος bytes που διαβάστηκε. Ανάγνωση μηδέν bytes σε συνδεδεμένη υποδοχή ροής σημαίνει ότι ο ομότιμος έκλεισε καθαρά την πλευρά εγγραφής του - η recv επιστρέφει "" και το SCALAR γίνεται η κενή συμβολοσειρά.
Καθολική κατάσταση που επηρεάζει#
Παραδείγματα#
Ανάγνωση ενός UDP datagram και αναγνώριση του αποστολέα:
use Socket;
my $from = recv($sock, my $buf, 1500, 0)
or die "recv: $!";
my ($port, $ip) = sockaddr_in($from);
print "got ", length($buf), " bytes from ",
inet_ntoa($ip), ":$port\n";
Ανάγνωση από συνδεδεμένη υποδοχή TCP. Η διεύθυνση αποστολέα είναι κενή, οπότε ελέγξτε με defined αντί για λογική αλήθεια:
defined(recv($sock, my $buf, 4096, 0))
or die "recv: $!";
# $buf now holds 0..4096 bytes; 0 means the peer closed.
Κοιτάξτε το επόμενο datagram χωρίς να το καταναλώσετε. Η δεύτερη κλήση επιστρέφει τα ίδια bytes:
use Socket;
recv($sock, my $peek, 1500, MSG_PEEK) or die $!;
recv($sock, my $consume, 1500, 0) or die $!;
# $peek and $consume hold the same datagram.
Βρόχος μη μπλοκαριστικής ανάγνωσης. Το EAGAIN / EWOULDBLOCK είναι το φυσιολογικό σήμα «δεδομένα ακόμα όχι», όχι πραγματικό σφάλμα:
use Errno qw(EAGAIN EWOULDBLOCK);
while (1) {
my $from = recv($sock, my $buf, 1500, 0);
unless (defined $from) {
last if $! == EAGAIN || $! == EWOULDBLOCK;
die "recv: $!";
}
handle_datagram($from, $buf);
}
Επιβολή ανάγνωσης πλήρους μήκους σε υποδοχή ροής που ενδέχεται να κατατμήσει το μήνυμα - το MSG_WAITALL μπλοκάρει μέχρι να φτάσουν LENGTH bytes ή να πεθάνει η σύνδεση:
use Socket;
defined(recv($sock, my $frame, 64, MSG_WAITALL))
or die "recv: $!";
# $frame is exactly 64 bytes, or the peer closed early.
Οριακές περιπτώσεις#
Υποδοχή με στρώμα UTF-8: αν το
SOCKETέχει στρώμα:utf8(απευθείας ή μέσω:encoding(...)), ηrecvρίχνει εξαίρεση. Ηrecvείναι προσανατολισμένη σε bytes και δεν αλληλεπιδρά με στρώματα PerlIO· χρησιμοποιήστεbinmodeγια να αφαιρέσετε το στρώμα πριν την ανάγνωση, ή αποκωδικοποιήστε τα αποτελούμενα bytes μόνοι σας.LENGTH έναντι μεγέθους datagram: για υποδοχές datagram, αν το
LENGTHείναι μικρότερο από το εισερχόμενο datagram, το πλεόνασμα απορρίπτεται σιωπηλά. Διαστασιολογήστε τον ενταμιευτή στο MTU του πρωτοκόλλου (τυπικά 1500 για UDP πάνω από Ethernet, 65507 για το μέγιστο IPv4 UDP).Η επιστροφή
""δεν είναι αρκετά ψευδής: ηrecvσε συνδεδεμένη υποδοχή επιστρέφει την κενή συμβολοσειρά, την οποία το!αντιμετωπίζει ως ψευδή. Κώδικας όπωςrecv(...) or die $!πεθαίνει σε κάθε επιτυχή συνδεδεμένη ανάγνωση. Χρησιμοποιήστεdefined:defined(recv($sock, $buf, $len, 0)) or die "recv: $!";
Αποτέλεσμα μηδέν bytes σε υποδοχή ροής: η
recvεπιστρέφει""και τοSCALARγίνεται κενό όταν ο ομότιμος έχει κάνει ομαλό κλείσιμο. Διακρίνετε το τέλος ροής από πραγματικό σφάλμα ελέγχονταςlength($buf) == 0μετά από ορισμένη επιστροφή.Σήματα: μια μπλοκαριστική
recvπου διακόπτεται από σήμα επιστρέφειundefμε$!==EINTR. Επαναλάβετε ή εγκαταστήστε κατάλληληsigactionμεSA_RESTARTαν αυτό δεν είναι αυτό που θέλετε.Κλειστή υποδοχή: η
recvσε κλειστό ή ποτέ-ανοιχτό handle επιστρέφειundef, θέτει το$!σεEBADF, και εκπέμπει προειδοποίησηrecv() on closed socketυπόuse warnings.Το προϋπάρχον περιεχόμενο του
SCALARκαταστρέφεται. Ηrecvδεν προσαρτά· αντικαθιστά. Χρησιμοποιήστε φρέσκο λεξιλογικό ή καθαρίστε το βαθμωτό πριν από κάθε κλήση.
Διαφορές από το upstream#
Πλήρως συμβατό με το upstream Perl 5.42.
Δείτε επίσης#
send- η πλευρά εγγραφής της ίδιας υποδοχής· ίδιο λεξιλόγιοFLAGS, ίδια διάκριση χωρίς σύνδεση έναντι συνδεδεμένηςsocket- δημιουργία του handleSOCKETαπό το οποίο διαβάζει ηrecvbind- απαιτείται πριν τηνrecvσε υποδοχή datagram πλευράς διακομιστή ώστε ο πυρήνας να γνωρίζει σε ποια θύρα να παραδώσειconnect- όταν χρησιμοποιείται σε υποδοχή datagram, κάνει τηνrecvνα επιστρέφει""όπως σε υποδοχή ροής και φιλτράρει datagrams από άλλους ομότιμουςsysread- ανάγνωση σε επίπεδο bytes για υποδοχές ροής όταν δεν χρειάζεστε τη διεύθυνση αποστολέα· ενσωματώνεται σε βρόχους βασισμένους σεselectSocket-sockaddr_in,inet_ntoa,MSG_PEEK,MSG_WAITALL, και οι υπόλοιπες σταθερές που καταναλώνει ηrecv