send#
Στέλνει ένα μήνυμα σε μια υποδοχή.
Η send γράφει το βαθμωτό MSG στο SOCKET μέσω του στρώματος υποδοχών του λειτουργικού συστήματος, όχι μέσω PerlIO. Σε συνδεδεμένη υποδοχή (SOCK_STREAM μετά από connect, ή αποδεκτό ομότιμο) η μορφή τριών ορισμάτων εκδίδει μια send(2) - χρησιμοποιήστε τη μορφή τεσσάρων ορισμάτων σε μη συνδεδεμένη υποδοχή datagram (SOCK_DGRAM) για να δρομολογήσετε κάθε μήνυμα στο TO, κάτι που πυροδοτεί την sendto(2) στο παρασκήνιο. Το FLAGS είναι η μάσκα bits που δέχεται η κλήση συστήματος (συνήθως 0· δείτε το man page της πλατφόρμας σας για την send(2) σχετικά με MSG_DONTWAIT, MSG_OOB, MSG_NOSIGNAL και παρόμοια).
Σύνοψη#
send SOCKET, MSG, FLAGS, TO
send SOCKET, MSG, FLAGS
Τι επιστρέφεται#
Το πλήθος των bytes που έγιναν δεκτά από τον πυρήνα, ή undef σε σφάλμα με ρυθμισμένο το $!. Ελέγχετε πάντα την τιμή επιστροφής:
my $n = send $sock, $buf, 0
or die "send failed: $!";
Δύο ιδιότητες δαγκώνουν τους χρήστες:
Το πλήθος είναι bytes, όχι χαρακτήρες. Το
length $bufσε συμβολοσειρά πλατιών χαρακτήρων και το επιστρεφόμενο πλήθος δεν θα συμφωνούν.Σε υποδοχές
SOCK_STREAMο πυρήνας ενδέχεται να δεχτεί λιγότερα bytes από όσα του δώσατε - σύντομη εγγραφή. Επαναλάβετε σε βρόχο μέχρι να εκκενωθεί ολόκληρος ο ενταμιευτής, ή χρησιμοποιήστεsyswriteπου έχει την ίδια σημασιολογία σύντομης εγγραφής αλλά λειτουργεί σε οποιοδήποτε filehandle.
Καθολική κατάσταση που επηρεάζει#
$!- τίθεται στο σφάλμα του συστήματος σε αποτυχία.Η στοίβα στρωμάτων PerlIO της υποδοχής δεν συμβουλεύεται. Τα στρώματα εξόδου (
:utf8,:encoding(...),:crlf) δεν έχουν καμία επίδραση σε αυτό που γράφει ηsend. Ειδικότερα, ένα στρώμα:utf8κάνει τηνsendνα ρίξει εξαίρεση αντί να κωδικοποιήσει σιωπηλά - το στρώμα υποδοχής και το στρώμα PerlIO δεν μπορούν να κατέχουν και τα δύο το byte framing.
Παραδείγματα#
Συνδεδεμένο TCP - μορφή τριών ορισμάτων:
use Socket;
socket my $sock, PF_INET, SOCK_STREAM, getprotobyname("tcp")
or die "socket: $!";
connect $sock, sockaddr_in(80, inet_aton("example.com"))
or die "connect: $!";
send $sock, "GET / HTTP/1.0\r\n\r\n", 0
or die "send: $!";
Μη συνδεδεμένο UDP - μορφή τεσσάρων ορισμάτων με ρητό προορισμό:
use Socket;
socket my $sock, PF_INET, SOCK_DGRAM, getprotobyname("udp")
or die "socket: $!";
my $to = sockaddr_in(514, inet_aton("10.0.0.1"));
send $sock, "<14>hello syslog\n", 0, $to
or die "send: $!";
Χειρισμός σύντομων εγγραφών σε υποδοχή ροής:
my $offset = 0;
while ($offset < length $buf) {
my $n = send $sock, substr($buf, $offset), 0;
defined $n or die "send: $!";
$offset += $n;
}
Αποστολή με σημαία - το MSG_DONTWAIT κάνει μία μη μπλοκαριστική προσπάθεια και επιστρέφει undef με το $! ρυθμισμένο σε EAGAIN/EWOULDBLOCK αν ο ενταμιευτής του πυρήνα είναι γεμάτος:
use Socket qw(MSG_DONTWAIT);
my $n = send $sock, $buf, MSG_DONTWAIT;
if (!defined $n) {
if ($!{EAGAIN} || $!{EWOULDBLOCK}) {
# back off, retry later
} else {
die "send: $!";
}
}
Οριακές περιπτώσεις#
Πλατιοί χαρακτήρες: το πέρασμα συμβολοσειράς με codepoints πάνω από
0xFFσε υποδοχή bytes γράφει την κωδικοποίηση UTF-8 κάθε χαρακτήρα και εκπέμπει προειδοποίησηWide character in sendυπόuse warnings. Κωδικοποιήστε ρητά μεEncode::encodeπριν την κλήση τηςsend.Στρώμα
:utf8στην υποδοχή: ηsendπεθαίνει. Είτε ανοίξτε την υποδοχή χωρίς το στρώμα, είτε καλέστεbinmode$sockγια να το αφαιρέσετε πριν την πρώτηsend. Ένα στρώμα:encoding(...)προσθέτει σιωπηρά το:utf8, οπότε απαγορεύεται και αυτό.Μορφή τεσσάρων ορισμάτων σε συνδεδεμένη υποδοχή: το πέρασμα
TOσε συνδεδεμένη υποδοχήSOCK_STREAMείναι σφάλμα - ο πυρήνας επιστρέφειEISCONN. Χρησιμοποιήστε τη μορφή τριών ορισμάτων αφού γίνει η σύνδεση.Μορφή τριών ορισμάτων σε μη συνδεδεμένη υποδοχή datagram: αποτυγχάνει με
ENOTCONN(ήEDESTADDRREQσε ορισμένες πλατφόρμες). Είτεconnect-άρετε πρώτα την υποδοχή datagram (που καρφώνει έναν προεπιλεγμένο ομότιμο), είτε παρέχετε τοTO.Κενό
MSGσε UDP: έγκυρο - στέλνει datagram μηδενικού μήκους που ο ομότιμος μπορεί να διαβάσει μεrecv. Σε TCP είναι no-op που επιστρέφει0.SIGPIPEσε κλεισμένο ομότιμο ροής: η εγγραφή σεSOCK_STREAMτης οποίας ο απομακρυσμένος άκρος έχει κλείσει εγείρειSIGPIPE, που εξ ορισμού τερματίζει τη διεργασία. ΠεράστεMSG_NOSIGNALσταFLAGS(Linux) ή εγκαταστήστε$SIG{PIPE} = 'IGNORE'για να λάβετε αντί αυτού επιστροφήEPIPE.sendmsg(2): η Perl εκθέτει τιςsend/sendto, όχι τηνsendmsg. Οι scatter/gather εγγραφές και τα ancillary δεδομένα (credentials, file descriptors πάνω απόAF_UNIX) απαιτούν άρθρωμα XS όπως τοSocket::MsgHdr.Μη-socket filehandle: η
sendσε μη-socket επιστρέφειundefμε το$!ρυθμισμένο σεENOTSOCK. Χρησιμοποιήστεsyswriteγια pipes και κανονικά αρχεία.
Διαφορές από το upstream#
Πλήρως συμβατό με το upstream Perl 5.42.
Δείτε επίσης#
recv- η αντίστροφη· διαβάζει bytes από υποδοχή με τους ίδιους περιορισμούς στρωμάτων και το ίδιο όρισμαFLAGSsyswrite- ακατέργαστη εγγραφή που παρακάμπτει την ενταμίευση PerlIO σε οποιοδήποτε filehandle· χρησιμοποιήστε την για pipes και αρχεία όπου ηsendαρνείται να λειτουργήσειconnect- εγκαθιδρύει τη διεύθυνση ομότιμου που σας επιτρέπει να χρησιμοποιήσετε τη μορφή τριών ορισμάτων τηςsendsocket- δημιουργεί το filehandle στο οποίο γράφει ηsend· ο τύπος υποδοχής (SOCK_STREAMέναντιSOCK_DGRAM) αποφασίζει ποια μορφή τηςsendείναι νόμιμηbind- εκχωρεί τοπική διεύθυνση· χρειάζεται πριν τηνsendσε υποδοχή datagram αν ο ομότιμος αναμένει απαντήσεις σε γνωστή θύραbinmode- αφαιρεί ένα αδέσποτο στρώμα:utf8που διαφορετικά θα έκανε τηνsendνα ρίξει εξαίρεση