תכנות תקשורת חריגת פייתון – דוגמא לשרת, לקוח

יום טוב למדים! בשיעור הקודם שלנו, דיברנו על מודול Python unittest. היום נתעסק בדוגמה לתכנות סוקט בפייתון. ניצור אפליקציות שרת ולקוח בפייתון.

תכנות סוקט בפייתון

כדי להבין תכנות סוקט בפייתון, אנו צריכים לדעת על שלושה נושאים מעניינים – שרת סוקט, לקוח סוקט ו־סוקט. אז מהו שרת? נו, שרת הוא תוכנה שמחכה לבקשות של לקוח ומכינה או מעבדת אותן לפי הצורך. מצד שני, לקוח הוא הבקשן של השירות הזה. תוכנית לקוח מבקשת משאבים מהשרת והשרת מגיב לבקשה זו. סוקט הוא הקצה של ערוץ תקשורת דו-כיווני בין השרת והלקוח. סוקטים יכולים לתקשר בתוך תהליך, בין תהליכים באותה מכונה או בין תהליכים במכונות שונות. לכל תקשורת עם תוכנית חיצונית, עלינו להתחבר דרך יציאת סוקט. המטרה העיקרית של השיעור הזה היא להציג לכם איך שרת ולקוח בסוקט תקשרו זה עם זה. תלמדו גם כיצד לכתוב תוכנית שרת סוקט בפייתון.

דוגמת סוקט Python

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

  1. תוכנית השרת של סוקט Python מתבצעת בתחילה וממתינה לבקשה כלשהי
  2. תוכנית הלקוח של סוקט Python תתחיל את השיחה בתחילה
  3. אז תוכנית השרת תגיב לבקשות הלקוח בהתאם
  4. התוכנית הלקוח תסיים אם המשתמש מזין הודעת "להתראות". תוכנית השרת תסיים גם כאשר תוכנית הלקוח מסיימת, זה אופציונלי וניתן להשאיר את תוכנית השרת פועלת לצמיתות או לסיים עם פקודה מסוימת בבקשת הלקוח.

שרת סוקט Python

נשמור תוכנית שרת פייתון סוקט כקובץ `socket_server.py`. כדי להשתמש בחיבור סוקט פייתון, נצטרך לייבא את המודול socket. לאחר מכן, בסדרה נצטרך לבצע מספר משימות כדי להקים חיבור בין השרת והלקוח. אנו יכולים לקבל כתובת מארח באמצעות פונקציית socket.gethostname(). מומלץ להשתמש בכתובת יציאה שעולה על 1024 מאחר ומספרי יציאה קטנים מ-1024 תפוסים עבור פרוטוקולי האינטרנט התקניים. ראו את קוד הדוגמה של שרת סוקט פייתון למטה, ההערות יעזרו לך להבין את הקוד.

import socket


def server_program():
    # קבל את שם המארח
    host = socket.gethostname()
    port = 5000  # initiate port no above 1024

    server_socket = socket.socket()  # get instance
    # שים לב. פונקציית bind() מקבלת tuple כארגומנט
    server_socket.bind((host, port))  # bind host address and port together

    # הגדר כמה לקוחות השרת יכול להאזין באותו זמן
    server_socket.listen(2)
    conn, address = server_socket.accept()  # accept new connection
    print("Connection from: " + str(address))
    while True:
        # קבל זרם נתונים. הוא לא יקבל חבילות נתונים גדולות מ-1024 בתים
        data = conn.recv(1024).decode()
        if not data:
            # אם הנתונים לא התקבלו הפסק
            break
        print("from connected user: " + str(data))
        data = input(' -> ')
        conn.send(data.encode())  # send data to the client

    conn.close()  # close the connection


if __name__ == '__main__':
    server_program()

לכן, שרת הסוקט שלנו רץ על פורט 5000 והוא ימתין לבקשת לקוח. אם ברצונך שהשרת לא יסיים כאשר חיבור הלקוח נסגר, פשוט הסר את התנאי if והצהרת השבר. לולאת while של פייתון משמשת להריץ את תוכנית השרת ללא הפסקה ולהמתין לבקשת לקוח.

לקוח סוקט פייתון

נשמור על קובץ הלקוח של סוקט בפייתון כ־socket_client.py. התוכנית הזו דומה לתוכנית השרת, חוץ מהקישור. ההבדל העיקרי בין תוכנית השרת והלקוח הוא שבתוכנית השרת, יש צורך לקשור את כתובת המארח וכתובת הפורט ביחד. ראה את קוד הדוגמה של לקוח סוקט בפייתון למטה, ההערה תעזור לך להבין את הקוד.

import socket


def client_program():
    host = socket.gethostname()  # as both code is running on same pc
    port = 5000  # socket server port number

    client_socket = socket.socket()  # instantiate
    client_socket.connect((host, port))  # connect to the server

    message = input(" -> ")  # take input

    while message.lower().strip() != 'bye':
        client_socket.send(message.encode())  # send message
        data = client_socket.recv(1024).decode()  # receive response

        print('Received from server: ' + data)  # show in terminal

        message = input(" -> ")  # again take input

    client_socket.close()  # close the connection


if __name__ == '__main__':
    client_program()

פלט תכנות סוקט פייתון

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

pankaj$ python3.6 socket_server.py 
Connection from: ('127.0.0.1', 57822)
from connected user: Hi
 -> Hello
from connected user: How are you?
 -> Good
from connected user: Awesome!
 -> Ok then, bye!
pankaj$
pankaj$ python3.6 socket_client.py 
 -> Hi
Received from server: Hello
 -> How are you?
Received from server: Good
 -> Awesome!
Received from server: Ok then, bye!
 -> Bye
pankaj$

שים לב שהשרת של סוקט רץ על פורט 5000 אך הלקוח גם דורש פורט סוקט כדי להתחבר לשרת. פורט זה מוקצה באופן אקראי על ידי קריאת ההתחברות של הלקוח. במקרה זה, זהו 57822. ולכן, כל זה בנוגע לתכנות סוקט בפייתון, שרת סוקט בפייתון ותוכניות דוגמה ללקוח סוקט. הפניה: תיעוד רשמי

Source:
https://www.digitalocean.com/community/tutorials/python-socket-programming-server-client