מודול socket
socket הוא מודול לממשק עם תכנות רשת ברמת-בסיס.
בפרק זה אין כוונה ללמד תכנות רשתות, בשל קוצר היריעה. מה שכן נלמד בפרק זה, זה איך לעבוד עם socket בפייתון.
הממשק של socket בפייתון הוא תעתיק
של ממשק קריאות המערכת (system calls) של יוניקס, באופן
שיתאים לסביבה מוכוונת העצמים של פייתון: הפונקציה socket() מחזירה אובייקט socket, והמתודות של אובייקט זה מיישמות את קריאות המערכת השונות.
הפרמטרים שמקבלות המתודות השונות הם ב"רמה גבוהה" יותר של שימוש מאשר
אלו של קריאות המערכת ב-C, כך שלמשל בפקודות
הכתיבה והקריאה הקצאת המאגר הזמני (buffer) מתבצעת אוטומטית.
כתובות מיוצגות על ידי מחרוזת בודדת בשביל הכתובות ממשפחת ה-AF_UNIX, וכזוג (רשומה של שני איברים) – (host, port), בשביל הכתובות ממשפחת ה-AF_INET, כאשר host הוא מחרוזת המכילה
את שם הדומיין או את כתובת ה-IP, ו-port הוא מספר שלם. סוגי כתובות אחרים אינם נתמכים. הסוג
של הכתובת בו נשתמש נקבע בעת יצירת אובייקט ה-socket.
כתובות IP מיוחדות: המחרוזת הריקה מייצגת את INADDR_ANY, בעוד שהמחרוזת '<broadcast>' מייצגת את INADDR_BROADCAST.
כל השגיאות בעת השימוש במודול, מעלות קריאות שגיאה -
exception. הודעות השגיאה הנזרקות עשויות להיות הודעות רגילות
במקרה של ארגומנט לא מתאים, או מחסור בזיכרון. שגיאות הנוגעות לנושאי
ה-socket או לתחביר של הכתובות הן מסוג
socket.error.
ניתן לעבוד
במצב פעולה non-blocking, על ידי שימוש במתודה
setblocking().
רשימת המתודות
של אובייקט socket:
accept()
מקבל חיבור (connection). ה-socket חייב
להיות במצב קשור, ומאזין (כלומר אחרי שימוש ב-bind
ובlisten-). הערך המוחזר הינו זוג
(רשומה בת שני איברים) – כפי שהודגם בפרק השמה מרובה.
מהתבנית: (conn, address) , כאשר
conn הוא
אובייקט socket חדש בו
ניתן להשתמש כדי לשלוח ולקבל מידע דרך החיבור, ו-address היא
הכתובת שנמצאת בקצה השני של החיבור.
bind(address)
קושר את אובייקט ה-socket לכתובת
הנתונה. אסור שהאובייקט יהיה כבר קשור לכתובת כלשהי. הפורמט של הכתובת
תלוי במשפחת הכתובות בה משתמשים.
close()
סוגר את ה-socket. לאחר
הסגירה, כל פעולה על החיבור תיכשל. הצד הרחוק של החיבור לא יקבל יותר
מידע. סגירה מתבצעת באופן אוטומטי עם "מחיקת האובייקט" על ידי
מערכת איסוף הזבל
connect(address)
מתחבר לכתובת מרוחקת נתונה. תבנית הכתובת תלויה
במשפחת הכתובות בה נעשה שימוש.
connect_ex(address)
זהה ל-connect() הרגיל,
אך מחזיר ערך שגיאה במקום לזרוק שגיאה במקרה שהשגיאה נבעה מרמת
ה-C של
הקריאה לconnect(). בעיות
אחרות עדיין גורמות לזריקת שגיאה, כמו למשל במקרה שהכתובת לא נמצאה.
הערך המוחזר הוא 0 אם הפעולה הצליחה, או ערכו של errno
אחרת.
fileno()
מחזיר את מתאר הקובץ (file descriptor) של ה-socket.
getpeername()
מחזיר את הכתובת אליה מחובר ה-socket. יעיל כדי לדעת את מספר ה-port של חיבור IP,
למשל.
getsockname()
מחזיר את הכתובת של ה-socket
עצמו.
listen(backlog)
מעביר את ה-socket למצב
של האזנה לחיבורים נכנסים. Backlog מגדיר
את המספר המקסימלי של חיבורים ממתינים, ועליו להיות לפחות
1.
recv(bufsize[,
flags])
מקבל מידע מה-socket. הערך
המוחזר הוא מחרוזת המייצגת את המידע שהתקבל. האורך המקסימלי של המידע
שמתקבל מוגדר על ידי bufsize.
Flags מסמן
אפשרויות נוספות (ראו man
ביוניקס, בערך recv(2)), והוא
0 על פי ברירת המחדל.
recvfrom(bufsize[,
flags])
מקבל מידע מה-socket. הערך
המוחזר הוא זוג, מהתבנית
(string, address), כאשר
string
הוא מחרוזת המייצגת את המידע שהתקבל,
ו-address היא
הכתובת ממנה נשלח המידע. האורך המקסימלי של המידע שמתקבל מוגדר על ידי
bufsize.
Flags מסמן
אפשרויות נוספות (ראו man
ביוניקס, בערך recv(2)), והוא
0 על פי ברירת המחדל.
send(string[,
flags])
שולח מידע ב-socket, שחייב
להיות מחובר ל-socket מרוחק.
String הוא
מחרוזת המידע הנשלח, flags הוא
ארגומנט אפשרויות אופציונלי, ראה recv() לעיל.
מחזיר את מספר הבייטים שנשלחו.
sendto(string[,
flags],
address)
שולח מידע ב-socket
ל-address – ה-socket לא
צריך להיות מחובר. מחזיר את מספר הבייטים שנשלחו.
setblocking(flag)
קובע את צורת הפעולה של האובייקט. אם flag הוא 0, צורת הפעולה נקבעת
ל-non-blocking, אחרת
היא נקבעת ל-blocking. כל
אובייקט socket מאותחל
תמיד למצב פעולה blocking.
במצב non-blocking, אם
recv() לא
מקבלת שום מידע, או אם send() לא
יכול מיידית לשלוח את המידע, נזרקת הודעת שגיאה. במצב blocking,
הקריאה לפונקציה מחכה עד שניתן להמשיך.
|