עבודה עם ממשקי רשת בג'אווה

1. סקירה כללית

במאמר זה נתמקד בממשקי רשת ובאופן הגישה אליהם באופן תכנותי ב- Java.

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

בשפה יומיומית אנו מתייחסים אליהם במונח כרטיסי ממשק רשת (NIC) - אך לא כולם חייבים להיות בצורת חומרה.

לדוגמא, ה- IP הפופולרי של localhost 127.0.0.1, שאנו משתמשים בו רבות בבדיקת יישומי רשת ורשת הוא ממשק ה- loopback - שאינו ממשק חומרה ישיר.

כמובן שלמערכות יש לרוב חיבורי רשת פעילים מרובים, כגון Ethernet קווי, WIFI, Bluetooth וכו '.

ב- Java, ה- API הראשי שבו אנו יכולים להשתמש כדי לקיים אינטראקציה ישירה איתם הוא ה- java.net.NetworkInterface מעמד. וכך, כדי להתחיל במהירות, בואו נייבא את החבילה המלאה:

ייבא java.net. *;

2. מדוע לגשת לממשקי רשת?

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

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

בדרך כלל, כאשר אנו רוצים ליצור חיבור שקע לכתובת שרת ספציפית:

שקע שקע = שקע חדש (); socket.connect (InetSocketAddress חדש (כתובת, יציאה));

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

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

NetworkInterface nif = NetworkInterface.getByName ("lo"); ספירה nifAddresses = nif.getInetAddresses (); שקע שקע = שקע חדש (); socket.bind (InetSocketAddress חדש (nifAddresses.nextElement (), 0)); socket.connect (InetSocketAddress חדש (כתובת, יציאה));

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

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

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

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

עם זאת, במקרה שלך, הנה יכול היה אולי לייצג ממשקים אחרים כמו Bluetooth - net1, רשת אלחוטית - net0 או אתרנט - eth0. במקרים כאלה לא היית יודע את כתובת ה- IP בזמן הקומפילציה.

3. אחזור ממשקי רשת

בחלק זה, נחקור את ממשקי ה- API האחרים הזמינים לאחזור הממשקים הזמינים. בחלק הקודם ראינו רק אחת מהגישות הללו; ה getByName () שיטה סטטית.

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

ה- API שבחנו עד כה משמש לחיפוש ממשק רשת לפי השם שצוין:

@Test ציבורי בטל givenName_whenReturnsNetworkInterface_thenCorrect () {NetworkInterface nif = NetworkInterface.getByName ("lo"); assertNotNull (nif); }

זה חוזר ריק אם אין שם זה:

@Test ציבורי בטל givenInExistentName_whenReturnsNull_thenCorrect () {NetworkInterface nif = NetworkInterface.getByName ("שם לא קיים"); assertNull (nif); }

ה- API השני הוא getByInetAddress (), זה גם דורש לספק פרמטר ידוע, הפעם נוכל לספק את כתובת ה- IP:

בטל ציבורי @ מבט נתוןIP_whenReturnsNetworkInterface_thenCorrect () {בתים [] ip = בתים חדשים [] {127, 0, 0, 1}; NetworkInterface nif = NetworkInterface.getByInetAddress (InetAddress.getByAddress (ip)); assertNotNull (nif); }

או שם המארח:

@Test ציבורי בטל givenHostName_whenReturnsNetworkInterface_thenCorrect () {NetworkInterface nif = NetworkInterface.getByInetAddress (InetAddress.getByName ("localhost")); assertNotNull (nif); }

או אם אתה ספציפי לגבי localhost:

@Test הציבור בטל givenLocalHost_whenReturnsNetworkInterface_thenCorrect () {NetworkInterface nif = NetworkInterface.getByInetAddress (InetAddress.getLocalHost ()); assertNotNull (nif); }

חלופה נוספת היא גם להשתמש במפורש בממשק loopback:

@Test הציבור בטל givenLoopBack_whenReturnsNetworkInterface_thenCorrect () {NetworkInterface nif = NetworkInterface.getByInetAddress (InetAddress.getLoopbackAddress ()); assertNotNull (nif); }

הגישה השלישית שהייתה זמינה רק מאז Java 7 היא להשיג ממשק רשת לפי האינדקס שלה:

NetworkInterface nif = NetworkInterface.getByIndex (אינדקס int);

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

רשתות ספירה = NetworkInterface.getNetworkInterfaces (); עבור (NetworkInterface nif: Collections.list (nets)) {// לעשות משהו עם ממשק הרשת}

4. פרמטרים של ממשק רשת

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

אנו יכולים לקבל כתובות IP באמצעות שני ממשקי API. ה- API הראשון הוא getInetAddresses (). זה מחזיר ספירה שֶׁל InetAddress מקרים בהם נוכל לעבד כראות עינינו:

@Test ציבורי בטל givenInterface_whenReturnsInetAddresses_thenCorrect () {NetworkInterface nif = NetworkInterface.getByName ("lo"); ספירת כתובתEnum = nif.getInetAddresses (); כתובת InetAddress = addressEnum.nextElement (); assertEquals ("127.0.0.1", address.getHostAddress ()); }

ה- API השני הוא getInterfaceAddresses (). זה מחזיר א רשימה שֶׁל ממשק כתובת מקרים חזקים יותר מאשר InetAddress מקרים. לדוגמה, מלבד כתובת ה- IP, אתה עשוי להתעניין בכתובת השידור:

@Test ציבורי בטל givenInterface_whenReturnsInterfaceAddresses_thenCorrect () {NetworkInterface nif = NetworkInterface.getByName ("lo"); כתובת addressEnum = nif.getInterfaceAddresses (); InterfaceAddress address = addressEnum.get (0); InetAddress localAddress = address.getAddress (); InetAddress broadCastAddress = address.getBroadcast (); assertEquals ("127.0.0.1", localAddress.getHostAddress ()); assertEquals ("127.255.255.255", broadCastAddress.getHostAddress ()); }

אנו יכולים לגשת לפרמטרים של רשת על ממשק שמעבר לשם ולכתובות ה- IP שהוקצו לו. כדי לבדוק אם הוא פועל:

@Test ציבורי בטל givenInterface_whenChecksIfUp_thenCorrect () {NetworkInterface nif = NetworkInterface.getByName ("lo"); assertTrue (nif.isUp ()); }

כדי לבדוק אם מדובר בממשק loopback:

@Test ציבורי בטל givenInterface_whenChecksIfLoopback_thenCorrect () {NetworkInterface nif = NetworkInterface.getByName ("lo"); assertTrue (nif.isLoopback ()); }

כדי לבדוק אם הוא מייצג חיבור רשת נקודה לנקודה:

בטל ציבורי @Test givenInterface_whenChecksIfPointToPoint_thenCorrect () {NetworkInterface nif = NetworkInterface.getByName ("lo"); assertFalse (nif.isPointToPoint ()); }

או אם מדובר בממשק וירטואלי:

@Test ציבורי בטל givenInterface_whenChecksIfVirtual_thenCorrect () {NetworkInterface nif = NetworkInterface.getByName ("lo"); assertFalse (nif.isVirtual ()); }

כדי לבדוק אם תמיכה ברב-שידור:

בטל ציבורי @Test givenInterface_whenChecksMulticastSupport_thenCorrect () {NetworkInterface nif = NetworkInterface.getByName ("lo"); assertTrue (nif.supportsMulticast ()); }

או כדי לאחזר את הכתובת הפיזית שלה, המכונה בדרך כלל כתובת MAC:

בטל ציבורי @Test givenInterface_whenGetsMacAddress_thenCorrect () {NetworkInterface nif = NetworkInterface.getByName ("lo"); בתים [] בתים = nif.getHardwareAddress (); assertNotNull (בתים); }

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

בטל ציבורי @Test givenInterface_whenGetsMTU_thenCorrect () {NetworkInterface nif = NetworkInterface.getByName ("net0"); int mtu = nif.getMTU (); assertEquals (1500, mtu); }

5. מסקנה

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

קוד המקור המלא והדוגמאות המשמשים במאמר זה זמינים בפרויקט Github.


$config[zx-auto] not found$config[zx-overlay] not found