שידור ורב-שידור בג'אווה

1. הקדמה

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

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

לבסוף, אנו מסיימים בדיון בתמיכה בשתי שיטות ההתייחסות הללו ב- IPv4 וגם ב- IPv6.

2. סיכום נתונים

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

בג'אווה, ה- java.net החבילה חושפת את DatagramPacket ו DatagramSocket שיעורים שניתן להשתמש בהם לתקשורת באמצעות פרוטוקול UDP. UDP משמש בדרך כלל בתרחישים שבהם חביון נמוך יותר חשוב מאשר אספקה ​​מובטחת, כגון הזרמת שמע / וידאו, גילוי רשת וכו '.

למידע נוסף על UDP ודיאגרמות ב- Java, עיין במדריך ל- UDP ב- Java.

3. שידור

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

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

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

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

מחלקה ציבורית BroadcastingClient {שקע DatagramSocket פרטי סטטי = null; main public static void ((String [] args)) זורק IOException {שידור ("שלום", InetAddress.getByName ("255.255.255.255")); } שידור חלל סטטי ציבורי (String broadcastMessage, כתובת InetAddress) זורק IOException {socket = DatagramSocket חדש (); socket.setBroadcast (נכון); בתא [] חיץ = broadcastMessage.getBytes (); DatagramPacket מנות = DatagramPacket חדש (חיץ, buffer.length, כתובת, 4445); socket.send (חבילה); socket.close (); }}

קטע הקוד הבא מראה כיצד לחזור על הכל ממשקי רשת כדי למצוא את כתובת השידור שלהם:

List listAllBroadcastAddresses () זורק SocketException {List broadcastList = ArrayList חדש (); ממשקי ספירה = NetworkInterface.getNetworkInterfaces (); בעוד (interfaces.hasMoreElements ()) {NetworkInterface networkInterface = interfaces.nextElement (); אם (networkInterface.isLoopback () ||! networkInterface.isUp ()) {המשך; } networkInterface.getInterfaceAddresses (). stream () .map (a -> a.getBroadcast ()) .filter (Objects :: nonNull) .forEach (broadcastList :: add); } להחזיר שידור רשימה; }

ברגע שיש לנו את רשימת כתובות השידור, נוכל לבצע את הקוד ב- מִשׁדָר() השיטה המוצגת לעיל לכל אחת מהכתובות הללו.

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

4. שידור רב

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

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

ב- IPv4, כל כתובת בין 224.0.0.0 עד 239.255.255.255 יכולה לשמש ככתובת ריבוי שידורים. רק אותם צמתים שמנויים לקבוצה מקבלים מנות שהועברו לקבוצה.

בג'אווה, MulticastSocket משמש לקבלת מנות שנשלחות ל- IP של שידור חי. הדוגמה הבאה מדגימה את השימוש ב- MulticastSocket:

מחלקה ציבורית MulticastReceiver מרחיב את החוט {שקע MulticastSocket מוגן = null; בתים מוגנים [] buf = בתים חדשים [256]; הפעלה בטלנית ציבורית () {socket = MulticastSocket חדש (4446); InetAddress group = InetAddress.getByName ("230.0.0.0"); socket.joinGroup (קבוצה); while (true) {DatagramPacket packet = DatagramPacket חדש (buf, buf.length); שקע.קבל (חבילה); מחרוזת שהתקבלה = מחרוזת חדשה (packet.getData (), 0, packet.getLength ()); if ("סוף" .equals (קיבל)) {break; }} socket.leaveGroup (קבוצה); socket.close (); }}

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

הדוגמה הבאה מראה כיצד לפרסם ל- IP של שידור משולב:

מחלקה ציבורית MulticastPublisher {שקע DatagramSocket פרטי; קבוצת פרטי InetAddress; בתים פרטיים [] buf; שידור פומבי בציבור (String multicastMessage) זורק IOException {socket = חדש DatagramSocket (); group = InetAddress.getByName ("230.0.0.0"); buf = multicastMessage.getBytes (); DatagramPacket packet = DatagramPacket חדש (buf, buf.length, group, 4446); socket.send (חבילה); socket.close (); }}

5. שידור ו- IPv6

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

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

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

ב- IPv6 משתמשים בסיביות השמאליות ביותר של כתובת לקביעת סוגה. עבור כתובת שידור לקבוצה, 8 הביטים הראשונים הם כולם, כלומר FF00 :: / 8. יתר על כן, סיביות 113-116 מייצגות את היקף הכתובת, שיכולה להיות אחת מהארבע הבאות: גלובלי, אתר מקומי, קישור מקומי, צומת מקומי.

בנוסף ל- unicast ו- multicast, IPv6 תומך גם בכל שידור, שבו ניתן לשלוח חבילה לכל אחד מחברי הקבוצה, אך אין צורך לשלוח אותה לכל החברים.

6. סיכום

במאמר זה בחנו את המושגים של תקשורת אחת לכולם ואחד לרבים באמצעות פרוטוקול UDP. ראינו דוגמאות כיצד ליישם מושגים אלה ב- Java.

לבסוף, בדקנו גם תמיכה ב- IPv4 ו- IPv6.

קוד לדוגמא מלא זמין ב- Github.