send#
שולח הודעה על סוקט.
send כותב את הסקלר MSG ל־SOCKET דרך שכבת הסוקטים של מערכת ההפעלה, לא דרך PerlIO. על סוקט מחובר (SOCK_STREAM לאחר connect, או עמית מתקבל) הצורה תלת־ארגומנטית מנפיקה send(2) - השתמשו בצורה ארבע־ארגומנטית על סוקט datagram לא־מחובר (SOCK_DGRAM) כדי לנתב כל הודעה ל־TO, מה שמפעיל sendto(2) תחת המכסה. FLAGS היא המסכה הביטית שקריאת המערכת מקבלת (בדרך כלל 0; ראו את דף ה־man של send(2) של הפלטפורמה שלכם עבור MSG_DONTWAIT, MSG_OOB, MSG_NOSIGNAL, וחבריהם).
תקציר#
send SOCKET, MSG, FLAGS, TO
send SOCKET, MSG, FLAGS
מה מקבלים בחזרה#
מספר הבתים שהקרנל קיבל, או undef בשגיאה כאשר $! מוגדר. תמיד בדקו את ערך ההחזרה:
my $n = send $sock, $buf, 0
or die "send failed: $!";
שתי תכונות נושכות אנשים:
הספירה היא בתים, לא תווים.
length $bufעל מחרוזת רחבה והספירה המוחזרת לא יסכימו.על סוקטי
SOCK_STREAMהקרנל עשוי לקבל פחות בתים ממה שנתתם לו - כתיבה קצרה. בצעו לולאה עד שכל ה־buffer נוקז, או השתמשו ב־syswriteשיש לו את אותה סמנטיקת כתיבה קצרה אך עובד על כל מטפל קובץ.
מצב גלובלי שהוא נוגע בו#
$!- מוגדר לשגיאת המערכת בכישלון.מחסנית שכבת PerlIO של הסוקט אינה נבדקת. שכבות פלט (
:utf8,:encoding(...),:crlf) אין להן השפעה על מה ש־sendכותב. בפרט, שכבת:utf8גורמת ל־sendלזרוק חריגה במקום לקודד בשקט - שכבת הסוקט ושכבת PerlIO אינן יכולות שתיהן להחזיק במסגור בתים.
דוגמאות#
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: $!";
טיפול בכתיבות קצרות על סוקט stream:
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 אם buffer הקרנל מלא:
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: $!";
}
}
מקרי קצה#
תווים רחבים: העברת מחרוזת עם נקודות קוד מעל
0xFFעל סוקט בתים כותבת את קידוד ה־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על עמית stream סגור: כתיבה ל־SOCK_STREAMשהקצה המרוחק שלו נסגר מעלהSIGPIPE, שכברירת מחדל מסיים את התהליך. העבירוMSG_NOSIGNALב־FLAGS(Linux) או התקינו$SIG{PIPE} = 'IGNORE'כדי לקבל החזרתEPIPEבמקום.sendmsg(2): Perl חושףsend/sendto, לאsendmsg. כתיבות scatter/gather ונתונים מסייעים (אישורים, descriptorים של קובץ מעלAF_UNIX) דורשים מודול XS כגוןSocket::MsgHdr.מטפל קובץ שאינו סוקט:
sendעל לא־סוקט מחזירundefכאשר$!מוגדר ל־ENOTSOCK. השתמשו ב־syswriteל־pipeים וקבצים רגילים.
הבדלים מהמקור#
תאימות מלאה עם Perl 5.42 המקורי.
ראו גם#
recv- ההפוך; קורא בתים מסוקט עם אותן הגבלות שכבה ואותו ארגומנטFLAGSsyswrite- כתיבה גולמית שעוקפת buffering של PerlIO על כל מטפל קובץ; השתמשו בה ל־pipeים וקבצים שבהםsendמסרב לעבודconnect- קובע את כתובת העמית שמאפשרת לכם להשתמש בצורה תלת־ארגומנטית שלsendsocket- יוצר את מטפל הקובץ ש־sendכותב אליו; סוג הסוקט (SOCK_STREAMלעומתSOCK_DGRAM) קובע איזו צורה שלsendחוקיתbind- מקצה כתובת מקומית; דרוש לפניsendעל סוקט datagram אם העמית מצפה לתשובות לפורט ידועbinmode- פושט שכבת:utf8תועה שאחרת תגרום ל־sendלזרוק שגיאה