תעלומות מפתח של חיבורי TCP של מתווך חבילות רשת: פירוט הצורך בלחיצת יד משולשת

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

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

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

 לחיצת יד משולשת של TCP

בואו נבחן מקרוב את חבילות ה-TCP שנשלחות בכל חיבור.

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

 חבילת SYN

כאשר לקוח יוצר חיבור, הוא מייצר מספר רצף התחלתי אקראי (client_isn) וממקם אותו בשדה "מספר רצף" של כותרת ה-TCP. במקביל, הלקוח מגדיר את מיקום דגל SYN ל-1 כדי לציין שהחבילה היוצאת היא חבילת SYN. ​​הלקוח מציין שהוא מעוניין ליצור חיבור עם השרת על ידי שליחת חבילת ה-SYN הראשונה לשרת. חבילה זו אינה מכילה נתוני שכבת יישומים (כלומר, נתונים שנשלחו). בשלב זה, סטטוס הלקוח מסומן כ-SYN-SENT.

חבילת SYN+ACK

כאשר שרת מקבל חבילת SYN מלקוח, הוא מאתחל באופן אקראי את המספר הסידורי שלו (server_isn) ולאחר מכן מכניס מספר זה לשדה "מספר סידורי" של כותרת ה-TCP. לאחר מכן, השרת מזין client_isn + 1 בשדה "מספר אישור" ומגדיר את סיביות SYN ו-ACK ל-1. לבסוף, השרת שולח את החבילה ללקוח, שאינה מכילה נתוני שכבת יישומים (ואינה נתונים לשליחה על ידי השרת). בשלב זה, השרת נמצא במצב SYN-RCVD.

חבילת ACK

לאחר שהלקוח מקבל את החבילה מהשרת, עליו לבצע את האופטימיזציות הבאות כדי להגיב לחבילת התגובה הסופית: ראשית, הלקוח מגדיר את סיבית ה-ACK של כותרת ה-TCP של חבילת התגובה ל-1; שנית, הלקוח מזין את הערך server_isn + 1 בשדה "אישור מספר תשובה"; לבסוף, הלקוח שולח את החבילה לשרת. חבילה זו יכולה לשאת נתונים מהלקוח לשרת. עם השלמת פעולות אלה, הלקוח ייכנס למצב ESTABLISHED.

ברגע שהשרת מקבל את חבילת התשובה מהלקוח, הוא גם עובר למצב ESTABLISHED.

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

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

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

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

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

כאשר לקוח שולח מספר חבילות יצירת חיבור SYN ברצף, במצבים כגון עומס ברשת, עלולים להתרחש הדברים הבאים:

1- חבילות ה-SYN הישנות מגיעות לשרת לפני חבילות ה-SYN האחרונות.
2- השרת יענה ללקוח עם חבילת SYN + ACK לאחר קבלת חבילת SYN הישנה.
3- כאשר הלקוח מקבל את חבילת SYN + ACK, הוא קובע שהחיבור הוא חיבור היסטורי (מספר רצף פג תוקף או פסק זמן) בהתאם להקשר שלו, ולאחר מכן שולח את חבילת RST לשרת כדי לבטל את החיבור.

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

1- אם מדובר בחיבור היסטורי (מספר הרצף פג תוקף או פסק זמן), החבילה שנשלחת על ידי לחיצת היד השלישית היא חבילת RST לביטול החיבור ההיסטורי.
2- אם לא מדובר בחיבור היסטורי, החבילה שנשלחה בפעם השלישית היא חבילת ACK, ושני הצדדים המתקשרים הצליחו ליצור את החיבור.

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

סיבה 2: כדי לסנכרן את מספרי הרצף הראשוניים של שני הצדדים
שני צידי פרוטוקול ה-TCP חייבים לשמור על מספר רצף, שהוא גורם מפתח להבטחת שידור אמין. מספרי רצף ממלאים תפקיד חשוב בחיבורי TCP. הם מבצעים את הפעולות הבאות:

המקלט יכול למנוע נתונים כפולים ולהבטיח את דיוק הנתונים.

המקבל יכול לקבל חבילות לפי סדר מספר הרצף כדי להבטיח את שלמות הנתונים.

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

לכן, עם יצירת חיבור TCP, הלקוח שולח חבילות SYN עם מספר הרצף ההתחלתי ודורש מהשרת להשיב עם חבילת ACK המציינת קליטה מוצלחת של חבילת SYN של הלקוח. לאחר מכן, השרת שולח את חבילת SYN עם מספר הרצף ההתחלתי ללקוח וממתין לתשובתו, אחת ולתמיד, כדי להבטיח שמספרי הרצף ההתחלתיים מסונכרנים באופן אמין.

סנכרן את המספרים הסידוריים הראשוניים של שני הצדדים

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

סיבה 3: הימנעו מבזבוז משאבים
אם יש רק "לחיצת יד שנייה", כאשר בקשת ה-SYN של הלקוח חסומה ברשת, הלקוח אינו יכול לקבל את חבילת ה-ACK שנשלחה על ידי השרת, ולכן ה-SYN יישלח מחדש. עם זאת, מכיוון שאין לחיצת יד שלישית, השרת אינו יכול לקבוע אם הלקוח קיבל אישור ACK ליצירת החיבור. לכן, השרת יכול ליצור חיבור באופן יזום רק לאחר קבלת כל בקשת SYN. ​​זה מוביל לתוצאות הבאות:

בזבוז משאבים: אם בקשת ה-SYN של הלקוח נחסמת, וכתוצאה מכך שידור חוזר של חבילות SYN מרובות, השרת ייצור מספר חיבורים לא חוקיים מיותרים לאחר קבלת הבקשה. זה מוביל לבזבוז מיותר של משאבי שרת.

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

הימנעו מבזבוז משאבים

לכן, על מנת להבטיח את היציבות והאמינות של חיבור הרשת, TCP משתמש בלחיצת יד משולשת כדי ליצור את החיבור ולמנוע את התרחשותן של בעיות אלו.

תַקצִיר
המתווך חבילות רשתיצירת חיבור TCP מתבצעת באמצעות לחיצת יד משולשת. במהלך לחיצת היד המשולשת, הלקוח שולח תחילה חבילה עם דגל SYN לשרת, המציינת שהוא רוצה ליצור חיבור. לאחר קבלת הבקשה מהלקוח, השרת משיב ללקוח חבילה עם דגלי SYN ו-ACK, המציינת שבקשת החיבור התקבלה, ושולח מספר רצף ראשוני משלו. לבסוף, הלקוח משיב לשרת עם דגל ACK כדי לציין שהחיבור נוצר בהצלחה. לפיכך, שני הצדדים נמצאים במצב ESTABLISHED ויכולים להתחיל לשלוח נתונים זה לזה.

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


זמן פרסום: ינואר-08-2025