פייתון/פייתון גרסה 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