1. ספרייה
  2. TCP ו-UDP
  3. יסודות פרוטוקולים

עודכן לפני חודש

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

אבל למחשב שלך יש חיבור רשת אחד.

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

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

כתובת הסוקט

סוקט מזוהה על ידי שלושה דברים:

  • כתובת IP — איזה מחשב ברשת
  • מספר פורט — איזו תוכנית באותו מחשב (0–65535)
  • פרוטוקול — TCP או UDP

יחד, אלה יוצרים כתובת סוקט. הדפדפן שלך עשוי ליצור סוקט בכתובת 192.168.1.50:52431/TCP. לשרת האינטרנט יש סוקט בכתובת 93.184.216.34:443/TCP. מנות הנתונים שנעות ביניהם נושאות את שתי הכתובות.

כתובת ה-IP היא באיזה בניין. הפורט הוא באיזה דירה. זהו.

מדוע קיימים מספרי פורטים

המחשב שלך יכול לנהל אלפי חיבורים בו-זמנית מפני שלכל אחד מהם יש שילוב ייחודי של כתובות IP ומספרי פורטים.

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

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

סוקטי זרם לעומת סוקטי דאטאגרם

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

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

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

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

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

מחזור החיים של הסוקט

לסוקטי זרם יש מחזור חיים מפני שגם לחיבורי TCP יש אחד.

סוקט שרת קורא ל-listen() כדי להתחיל לקבל חיבורים. סוקט לקוח קורא ל-connect() כדי לפנות. לאחר שלחיצת היד התלת-כיוונית של TCP מושלמת, שני הסוקטים נכנסים למצב ESTABLISHED — שבו הנתונים זורמים.

הסגירה מורכבת יותר. TCP זקוק לשני הצדדים כדי להסכים שהשיחה הסתיימה. הצד היוזם עובר דרך FIN-WAIT-1, FIN-WAIT-2 ו-TIME-WAIT. הצד השני עובר דרך CLOSE-WAIT ו-LAST-ACK.

TIME-WAIT נראה מוזר בהתחלה. לאחר הסגירה, הסוקט נשאר פעיל למשך 60 שניות (ב-Linux; מערכות אחרות משתנות) לפני שנעלם לחלוטין. מדוע לבודד סוקט שנסגר?

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

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

ממשק התכנות

ממשק ה-API של הסוקטים נוצר ב-BSD Unix של שנות ה-80 והפך לתקן האוניברסלי. C, Python, Go, JavaScript — כולם משתמשים באותו מודל.

יצירת סוקט: socket() מחזירה אחיזה לסוקט חדש.

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

עבור לקוחות: connect() עם כתובת השרת. לאחר ההתחברות, הסוקט מוכן.

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

זו הסיבה שתכנות רשת בכלל אפשרי. אתה לא בונה כותרות TCP או מחשב סיכומי ביקורת. אתה אומר לסוקט מה לשלוח; הוא מטפל בפרוטוקולים.

אפשרויות הסוקט

ניתן לכוונן סוקטים.

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

SO_KEEPALIVE שולח בדיקות תקופתיות על חיבורים סרק כדי לזהות אם הצד השני נעלם.

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

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

הבסיס

כל יישום מחובר לרשת בנוי על סוקטים. הם הגבול שבו התוכנית שלך מסתיימת והרשת מתחילה.

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

סוקטים הם היחידה הבסיסית של תקשורת הרשת. HTTP, WebSockets, חיבורי מסד נתונים, API — כל זה נשען על הבסיס הזה.

שאלות נפוצות בנושא סוקטים

כמה סוקטים יכול מחשב לקיים פתוחים בו-זמנית?

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

מה ההבדל בין סוקט לפורט?

פורט הוא מספר (0–65535) המזהה נקודת קצה על מכונה. סוקט הוא נקודת הקצה הממשית — יש לו פורט, אבל גם כתובת IP ופרוטוקול. מספר סוקטים יכולים לשתף פורט (עם כתובות מרוחקות שונות), אבל כל סוקט הוא ייחודי.

מדוע יישומים מסוימים משתמשים גם ב-TCP וגם ב-UDP?

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

מה קורה אם שתי תוכניות מנסות להשתמש באותו פורט?

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

האם דף זה היה מועיל?

😔
🤨
😃