12.4 תכנות אסינכרוני עם eventloop תרגול
תרגול: תכנות אסינכרוני עם לולאת אירועים - event loop programming¶
תרגיל 1 - event loop בסיסי¶
ממשו event loop מעל epoll עם תמיכה באירועי קריאה וכתיבה.
הevent loop צריך לתמוך ב:
- event_loop_add_reader(loop, fd, callback, data) - רשום callback לקריאה.
- event_loop_add_writer(loop, fd, callback, data) - רשום callback לכתיבה.
- event_loop_remove(loop, fd) - הסר fd.
- event_loop_run(loop) - הרץ את הלולאה.
- event_loop_stop(loop) - עצור.
בדקו עם stdin: כל שורה שמקלידים תודפס עם timestamp.
דרישות:
- השתמשו ב-epoll_create1, epoll_ctl, epoll_wait.
- אל תשכחו לטפל ב-EINTR מ-epoll_wait.
- ה-callback מקבל fd ו-void* data.
תרגיל 2 - טיימרים ב-event loop¶
הוסיפו תמיכה בטיימרים ל-event loop מתרגיל 1.
הוסיפו פונקציה event_loop_add_timer(loop, interval_ms, callback, data) שמשתמשת ב-timerfd_create מתחת למכסה המנוע.
צרו תוכנית עם 3 טיימרים:
- טיימר 1: כל שנייה - מדפיס "tick".
- טיימר 2: כל 3 שניות - מדפיס סטטיסטיקה (כמה ticks היו).
- טיימר 3: אחרי 10 שניות (חד-פעמי) - עוצר את הloop.
דרישות:
- השתמשו ב-timerfd_create ו-timerfd_settime.
- אחרי 10 שניות התוכנית חייבת לצאת.
- הדפיסו timestamp ליד כל הודעה.
תרגיל 3 - שרת echo עם event loop¶
כתבו שרת echo מלא שמשתמש ב-event loop שבניתם.
דרישות:
- הsocket של השרת במצב non-blocking.
- כל חיבור חדש נרשם ב-event loop כ-reader.
- כשמתקבלים נתונים, שלחו אותם חזרה (echo).
- טפלו בסגירת חיבור (read מחזיר 0).
- בדקו עם nc localhost <port> מכמה טרמינלים במקביל.
- הוסיפו טיימר שכל 5 שניות מדפיס כמה חיבורים פעילים.
תרגיל 4 - שרת HTTP מינימלי¶
בנו שרת HTTP שמחזיר דף HTML פשוט, באמצעות event loop.
דרישות:
- טפלו בקריאת הבקשה באופן חלקי (non-blocking read שמצטבר בחוצץ).
- זהו את סוף הheaders - המחרוזת \r\n\r\n.
- כשקיבלתם בקשה שלמה, בנו תשובת HTTP עם:
- שורת סטטוס: HTTP/1.1 200 OK
- כותרות: Content-Type, Content-Length, Connection: close
- גוף: דף HTML עם כותרת ופסקה.
- כתבו את התשובה באופן non-blocking (התקדמו בכתיבה עד שנגמר).
- בדקו בדפדפן: http://localhost:8080
- בדקו עם curl: curl -v http://localhost:8080
תרגיל 5 - מכונת מצבים לפרוטוקול¶
ממשו שרת מבוסס event loop שמטפל בפרוטוקול פשוט. הפרוטוקול:
- לקוח שולח:
LOGIN <username>\n - שרת עונה:
OK\n(אם שם המשתמש לא ריק) אוERROR\n - לקוח שולח:
MSG <text>\n - שרת עונה:
ECHO: <username>: <text>\n - לקוח שולח:
QUIT\n - שרת סוגר את החיבור.
דרישות:
- כל חיבור מנוהל כמכונת מצבים עם המצבים: WAIT_LOGIN, LOGGED_IN, DONE.
- טפלו בקלט חלקי: הודעה עלולה להגיע בכמה read()-ים.
- טפלו בכמה לקוחות במקביל.
- הדפיסו לוג של כל פעולה בצד השרת.