עבור לתוכן

בעיה בתכנות סוקטים ב-Python

Featured Replies

פורסם

שלום לכולם,

קיבלתי תרגיל לתכנות שרת HTTP שממתין על פורט 80 לחיבור ואמור לקבל מחרוזת מסויימת מהלקוח לצורך העניין.

הקוד שלי הוא כזה:

from socket import *

server_s = socket(AF_INET, SOCK_STREAM)
server_s.bind(('0.0.0.0', 80))
server_s.listen(5)
while(1):
(client_s, client_addr) = server_s.accept()
rcv = client_s.recv(1000)
cmd = rcv.split(' ')
client_s.sendall("a")
client_s.close()

משום מה, ברגע שאני מתחבר דרך ה-CMD בצורה הבאה:

telnet localhost 80

השרת לא ממתין לקבלת המחרוזת מהלקוח, כלומר, אני מקבל ישר a וConnection Lost.

אציין שהידע של בפייתון הוא בסיסי בהחלט (בעבר תכנתתי בשפות שונות, פייתון רק התחלתי ללמוד ע"מ להבין את החוברת - כך שאם למישהו יש מדריך טוב על הדרך, גם באנגלית - אשמח לקבל :) )

אשמח להצעות פתרון

תודה מראש

פורסם

נסה להפעיל את המתודות setblocking ו-settimeout כדי לוודא שהסוקט יחכה לתשובה מהלקוח.

פורסם
  • מחבר

אוקיי הסתדרתי מהבחינה הזו, אבל משום מה ה-recv קולט אך ורק תו אחד.

איך ניתן לעשות שרק לאחר לחיצה על אנטר של המשתמש הוא ישלח את הפקודה מהלקוח לשרת?

תודה

פורסם
  • מחבר

למישהו יש אולי הצעות איך ניתן לסדר את זה?

אני אסביר במידה ולא הייתי מובן, אני מעוניין שבעת client_s.recv(1024) השרת יקבל מחרוזת, בגודל של עד 1024, ובתור לקוח, אני אקליד עד שאני לוחץ "אנטר" ורק לאחר מכן זה ישלח אל השרת.

אני משתמש בגרסא 2.7 של פייתון.

אשמח לעזרתכם, חשוב לי נורא.

פורסם
  • מחבר

טוב הסתדרתי בדרך יצירתית, אני מקווה שהיא יעילה, כתבתי פעולה פשוטה שעושה את זה:

def RecieveString(s, ln):
ch = s.recv(ln)
tx = ""
while ch != "\r\n" and ch != "\n":
tx += ch
ch = s.recv(ln)
return tx

פורסם

הרעיון סבבה, אבל הביצוע בעייתי - קודם כל, אתה לא בודק מקרה של שגיאה (במקרה כזה recv מחזיר מחרוזת ריקה).

חוץ מזה, אתה מסתמך על ההנחה שתמיד recv מחזירה בית אחד בלבד (או שניים, משום מה) שזה לא נכון לעשות. אתה יכול להמשיך לקרוא כל עוד הקלט לא מכיל סוף שורה.

אגב, נראה לי שהבעיה המקורית היא דווקא עם telnet, ששולח כל פעם תו אחד (ולא רק בסוף שורה).

פורסם
  • מחבר

הרעיון סבבה, אבל הביצוע בעייתי - קודם כל, אתה לא בודק מקרה של שגיאה (במקרה כזה recv מחזיר מחרוזת ריקה).

חוץ מזה, אתה מסתמך על ההנחה שתמיד recv מחזירה בית אחד בלבד (או שניים, משום מה) שזה לא נכון לעשות. אתה יכול להמשיך לקרוא כל עוד הקלט לא מכיל סוף שורה.

אגב, נראה לי שהבעיה המקורית היא דווקא עם telnet, ששולח כל פעם תו אחד (ולא רק בסוף שורה).

כן הבעיה כנראה בטלנט.

עשיתי את זה ככה בגלל שהוא שולח ברגע שנקלט תו יחיד, לכן אני קולט בלולאה עד שהמשתמש יורד שורה (אנטר).

לא הבנתי, באיזה מקרה יכולה להיות כאן שגיאה?

פורסם

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

חוץ תחשוב מה קורה כשהמשתמש מסיים את ההתקשרות (רמז: במקרה כזה, recv מחזירה מחרוזת ריקה).

פורסם

או במילים אחרות - פרוטוקול.

פורסם
  • מחבר

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

חוץ תחשוב מה קורה כשהמשתמש מסיים את ההתקשרות (רמז: במקרה כזה, recv מחזירה מחרוזת ריקה).

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

ובנוגע לשאר המקרים, והרמז - יש להפסיק את הלולאה גם ברגע שמתקיימת מחרוזת ריקה?

ארכיון

דיון זה הועבר לארכיון ולא ניתן להוסיף בו תגובות חדשות.

דיונים חדשים