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

לאחר מכן, ישנן שתי אפשרויות:

  1. אם רוצים לבנות שרת (תוכנה שמשרתת תוכנות אחרות הנקראות בדרך־כלל "לקוחות") יש להזין את הקוד הבא:
conn.bind(('',port))

הפונקציה bind מקבלת touple, ומקשרת בין הפורט (מפתח) הרצוי לבין ה ip כדי לקבל חיבורים ולהעביר מידע במפתח זה.

  1. אם מעוניינים לבנות לקוח (תוכנה שמתחברת לשרת כדי להשתמש בשירותים שהוא מציע) יש להזין את הקוד הבא:
conn.connect((ip,port))

בשני המקרים, ip הוא הכתובת שאליה רוצים להתחבר (לקוח בלבד) ואילו port הוא הפתחה. לאחר מכן, על מנת לשלוח נתונים, יש להשתמש בפונקציה send של עצם השקע שיצרנו:

conn.send('DATA\r\n')

הפקודה הזו תשתמש בעצם conn ותשלח את המחרוזת DATA. אם מעוניינים לקבל מידע, ניתן לעשות זאת באמצעות לולאה אין-סופית:

while True:
    data = conn.recv(4096)

לאחר שסיימנו לשלוח, לקבל ולעבד את המידע, נוכל לסגור את החיבור:

conn.close()

שיטות מתקדמות עריכה

לשיטה הבסיסית שלמדנו ישנם מספר חסרונות:

  • ניתן להאזין לתעבורה ובכך לחשוף מידע, שבמקרים מסוימים עלול להיות רגיש ביותר.
  • הליך קבלת המידע הוא סנכרוני, כלומר התכנה שכתבנו תוכל לקבל מידע רק אחרי שהיא סיימה לעבד את המידע הקיים.
  • כתיבת שרת או לקוח דורשת בקיאות בפרוטוקול ולוקחת לא מעט שורות קוד.

מסיבות אלו, כדאי להשתמש בשיטות אחרות:

שימוש ב־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