פייתון/פייתון גרסה 2/שימוש בשקעים
מהם שקעים?
עריכהשקעים (בלועזית: sockets) הם למעשה הדרך הבסיסית ביותר ליצור תקשורת אינטרנט - כל יישום המתחבר לאינטרנט, החל מדפדפן ועד יישומי שורת־פקודה, כמו ping.
שימוש בשקעים בפייתון
עריכהלפייתון ספריית קוד פשוטה לשימוש בשם socket. לתחילת העבודה, יש לייבא את ספריית השקעים כך:
import socket
כך יוצרים עצם מסוג שקע שיתמש ב IPv4 ובפרוטוקול TCP:
conn = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
לעצם מסוג שקע בפרוטוקול UDP:
conn = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
לאחר מכן, ישנן שתי אפשרויות:
- אם רוצים לבנות שרת (תוכנה שמשרתת תוכנות אחרות הנקראות בדרך־כלל "לקוחות") יש להזין את הקוד הבא:
conn.bind(('',port))
הפונקציה bind מקבלת touple, ומקשרת בין הפורט (מפתח) הרצוי לבין ה ip כדי לקבל חיבורים ולהעביר מידע במפתח זה.
- אם מעוניינים לבנות לקוח (תוכנה שמתחברת לשרת כדי להשתמש בשירותים שהוא מציע) יש להזין את הקוד הבא:
conn.connect((ip,port))
בשני המקרים, ip הוא הכתובת שאליה רוצים להתחבר (לקוח בלבד) ואילו port הוא הפתחה. לאחר מכן, על מנת לשלוח נתונים, יש להשתמש בפונקציה send של עצם השקע שיצרנו:
conn.send('DATA\r\n')
הפקודה הזו תשתמש בעצם conn ותשלח את המחרוזת DATA. אם מעוניינים לקבל מידע, ניתן לעשות זאת באמצעות לולאה אין-סופית:
while True:
data = conn.recv(4096)
לאחר שסיימנו לשלוח, לקבל ולעבד את המידע, נוכל לסגור את החיבור:
conn.close()
שיטות מתקדמות
עריכהלשיטה הבסיסית שלמדנו ישנם מספר חסרונות:
- ניתן להאזין לתעבורה ובכך לחשוף מידע, שבמקרים מסוימים עלול להיות רגיש ביותר.
- הליך קבלת המידע הוא סנכרוני, כלומר התכנה שכתבנו תוכל לקבל מידע רק אחרי שהיא סיימה לעבד את המידע הקיים.
- כתיבת שרת או לקוח דורשת בקיאות בפרוטוקול ולוקחת לא מעט שורות קוד.
מסיבות אלו, כדאי להשתמש בשיטות אחרות:
- שימוש ב־asyncore
- שימוש ב־ssl(ניתן לשלב עם ספריות אחרות).
- שימוש בספרייה http://twistedmatrix.com.
- שימוש בספרייה של הפרוטוקול הספציפי שאנו רוצים לעבוד עמו.
שימוש ב־asyncore
עריכההספרייה asyncore נכללת עם המפרש ואין צורך בהתקנתה. כדי ליצור לקוח באמצעותה, יש צורך תחילה לייבא את הספרייה socket וליצור מחלקה שמתבססת על asyncore.dispatcher ולהוסיף בפונקציה __init__ את השורות הבאות:
asyncore.dispatcher.__init__(self) # אתחול מחלקת הבסיס
self.create_socket(socket.AF_INET, socket.SOCK_STREAM) # יצירת אובייקט מסוג שקע
self.connect((host, port)) # התחברות לשרת
self.buffer = [] # יצירת מערך שמכיל את המידע שמתקבל
- | שימוש בשקעים | - |
לאחר מכן, ניתן להוסיף את הפונקציות הבאות כדי לטפל באירועים שונים של הלקוח:
- התחברות מוצלחת לשרת - handle_connect
- התנתקות מהשרת - handle_close
- קבלת מידע מהשרת - handle_read
- זיהוי שקע שניתן לשלוח בו מידע לשרת - handle_write