שימוש נכון ב-TCP וב - NIO

d70

Well-known member
סינכרוני? להיפך,אתם כרגע עובדים א-סינכרוני
ההודעה שלך מגיעה ללקוח מתי שבא לך לשלוח,לא בצורה מתואמת מולו.כרגע אין מנגנון ack/nack או משהו בסגנון לכן זה לא נקרא עבודה סינכרונית.
דבר שני,הלקוח החליט שהוא עובד עקום.וכרגע הפרוטוקול לא עובד.אם הוא תמיד צודק,כמו שזה נראה עכשיו, אתה צריך לעשות שינויים מהצד שלך.
 

ilgnd

New member
אני עובד א-סינכרו. הוא עובד סינכרונית

אני אעבור למצב סינכרוני שבו אני לא מטפל בהודעה עד שאני שולח את ההודעה הקודמת.
בפועל אני אשתמש ב - java.net במקום ב - java.nio.
&nbsp
 

choo

Active member
זה ממש לא מספיק. אתה צריך לחכות עד לקבלת ack אפליקטיבי

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

ilgnd

New member
מסכים אבל...

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

choo

Active member
אז ייתכן שהלקוח לא מבין ושאתה צריך להסביר לו

&nbsp
אחד הדברים שלקחתי על עצמי כשעבדתי בחברה שנתנה שרותי פיתוח תוכנה לחברות תוכנה - היה להעביר ידע רלוונטי במקומות שבהם הוא היה חסר. כמובן, ייתכן שהלקוח כן מבין אבל מאחר ולא אכפת לו לאבד הודעות מדי פעם והוא הגיע להסברה לעצמו למה זה יתרחש רק מדי פעם, הוא הגיע למסקנה שהפתרון הזה מספיק טוב עבורו.
&nbsp
עד לאותה נקודה שבה הלקוח ישתכנע - אתה צריך להכניס push אחרי סיום שליחת הודעה ואחריו sleep ארוך מספיק לפני תחילת שליחת ההודעה הבאה. ביצוע של push כזה יכריח את ה-socket לשלוח הודעות מייד ולא לחכות להצטברות עוד הודעות. לחליפין, אפשר לנטרל את ה-nagle algorithm מיד אחרי פתיחת הסוקט במקום אותו push (אבל עדיין צריך את ה-sleep).
&nbsp
כמובן שאפשר גם לא לעשות כלום ולחיות עם התקלות שיצוצו מדי פעם. (תקלות שלעולם לא תוכל להוכיח שנובעות ספציפית מהבעיה הזו, ותשארנה "תעלומה" מבחינת הלקוח, ותובלנה למימוש מנגנוני התאוששות מוזרים שעוקפים את הבעיה המקורית. לפחות אתה תרויח ידע טכני בנושאי תקשורת נתונים מההתנהלות הלא הגיונית הזו :) )
 

הפרבולה

New member
אם כבר אתם דנים על פרוטוקול מוסכם

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

כדאי למספר את ההודעות בצורה עוקבת ( האם זה הכוונה ב magic ? ) כדי שכל צד יוכל לוודא שלא פיספס הודעה, אמנם בTCP הודעות לא אמורות ללכת לאיבוד אבל זה יכול לקרות בגלל בג בתוכנה ו\או אולי תחליטו בעתיד לעבוד עם UDP במקום TCP ( משיקולי ביצועים ) ששם לא מובטח אי איבוד הודעות.
 

ilgnd

New member
אין צורך למספר את ההודעות:

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

הפרבולה

New member
גם אם לא איכפת לכם לאבד הודעות

לדעתי עדין כדאי לפחות שתהיה אפשרות לדעת שהודעה הלכה לאיבוד, זה יכול להיות שדה של בית בודד בפתיח שממספר ציקלי את ההודעות בתחום 0...255 .
&nbsp
איבוד הודעה יכול לקרות גם ב TCP בגלל בג .
 

ilgnd

New member
מדובר במידע שנכנס ב - stream

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

בצורת העבודה של סטרימינג דו כיווני, אאל״ט רק ההתחלה היא ב HTTP, אח״כ זה מאוד דומה ל TCP ״גולמי״.
לפעמים אפשר ״למכור״ פרוטוקול קיים, ואולי הלקוח יכול לשנות את דעתו.
כאמור, רק הצעתי.
 
למעלה