Hálózati interfészek használata Java-ban

1. Áttekintés

Ebben a cikkben a hálózati csatolókra és azok Java-ban történő programszerű elérésére összpontosítunk.

Egyszerűen fogalmazva: a A hálózati interfész az eszköz és bármely hálózati kapcsolata közötti összekapcsolódás pontja.

A mindennapi nyelvben a Hálózati interfészkártyák (NIC) kifejezéssel utalunk rájuk - de nem mindegyiknek kell hardveresnek lennie.

Például a népszerű localhost IP 127.0.0.1, amelyet sokat használunk a webes és hálózati alkalmazások teszteléséhez, az a loopback interfész - ami nem közvetlen hardver interfész.

Természetesen a rendszereknek gyakran több aktív hálózati kapcsolata van, például vezetékes Ethernet, WIFI, Bluetooth stb.

A Java-ban a fő API, amellyel közvetlenül kapcsolatba léphetünk velük, az java.net.NetworkInterface osztály. Tehát a gyors kezdéshez importáljuk a teljes csomagot:

import java.net. *;

2. Miért érdemes hozzáférni a hálózati interfészekhez?

A legtöbb Java program valószínűleg nem fog közvetlenül kapcsolatba lépni velük; vannak azonban speciális forgatókönyvek, amikor valóban szükségünk van ilyen alacsony szintű hozzáférésre.

Ezek közül a legkiemelkedőbb az, ahol egy rendszernek több kártyája van, és szeretné, ha a szabad választani egy adott interfészt, amellyel egy aljzatot használhat. Ilyen esetekben általában tudjuk a nevet, de nem feltétlenül az IP-címet.

Normális esetben, ha socket kapcsolatot akarunk létrehozni egy adott kiszolgáló címével:

Socket socket = új Socket (); socket.connect (új InetSocketAddress (cím, port));

Így a rendszer kiválaszt egy megfelelő helyi címet, hozzákapcsolódik és kommunikál a szerverrel a hálózati interfészén keresztül. Ez a megközelítés azonban nem teszi lehetővé, hogy saját magunkat választhassuk.

Itt feltételezést fogunk tenni; nem tudjuk a címet, de tudjuk a nevet. Csak demonstrációs célból tegyük fel, hogy a kapcsolatot a loopback interfészen keresztül akarjuk, megegyezés szerint annak a neve lo, legalábbis Linux és Windows rendszereken, OSX-en igen lo0:

NetworkInterface nif = NetworkInterface.getByName ("lo"); Számlálás nifAddresses = nif.getInetAddresses (); Socket socket = új Socket (); socket.bind (új InetSocketAddress (nifAddresses.nextElement (), 0)); socket.connect (új InetSocketAddress (cím, port));

Tehát lekérjük a csatolt hálózati interfészt lo először keresse meg a hozzá csatolt címeket, hozzon létre egy foglalatot, kösse össze a felsorolt ​​címek bármelyikével, amelyeket fordításkor nem is ismerünk, majd csatlakoztassa.

A Hálózati felület objektum tartalmaz egy nevet és egy hozzá rendelt IP-címkészletet. Tehát ezen címek bármelyikéhez való kötés garantálja a kommunikációt ezen a felületen keresztül.

Ez valójában nem mond semmi különöset az API-ról. Tudjuk, hogy ha azt szeretnénk, hogy helyi címünk localhost legyen, akkor az első kódrészlet elegendő lenne, ha csak hozzáadnánk a kötési kódot.

Ezenkívül soha nem kellene végigcsinálnunk a több lépést, mivel a localhostnak van egy jól ismert címe, 127.0.0.1 és könnyen megköthetjük az aljzatot hozzá.

Az Ön esetében azonban lo talán képviselhetett volna más interfészeket, például a Bluetooth-t - net1, vezetéknélküli hálózat - net0 vagy ethernet - eth0. Ilyen esetekben nem tudná az IP-címet fordításkor.

3. Hálózati interfészek lekérése

Ebben a szakaszban megvizsgáljuk a többi elérhető API-t az elérhető interfészek lekéréséhez. Az előző részben ezek közül csak egyet láttunk; a getByName () statikus módszer.

Érdemes megjegyezni, hogy a Hálózati felület osztályban nincsenek nyilvános konstruktorok, így természetesen nem vagyunk képesek új példányt létrehozni. Ehelyett a rendelkezésre álló API-kat fogjuk használni az egyik lekéréséhez.

Az eddig megtekintett API-t arra használják, hogy a megadott felületen keressen egy hálózati felületet:

@Test public void givenName_whenReturnsNetworkInterface_thenCorrect () {NetworkInterface nif = NetworkInterface.getByName ("lo"); assertNotNull (nif); }

Visszatér nulla ha egyik sem a névre vonatkozik:

@Test public void givenInExistentName_whenReturnsNull_thenCorrect () {NetworkInterface nif = NetworkInterface.getByName ("nem létező_név"); assertNull (nif); }

A második API az getByInetAddress (), megköveteli egy ismert paraméter megadását is, ezúttal megadhatjuk az IP-címet:

@Test public void givenIP_whenReturnsNetworkInterface_thenCorrect () {byte [] ip = new byte [] {127, 0, 0, 1}; NetworkInterface nif = NetworkInterface.getByInetAddress (InetAddress.getByAddress (ip)); assertNotNull (nif); }

Vagy a gazdagép neve:

@Test public void givenHostName_whenReturnsNetworkInterface_thenCorrect () {NetworkInterface nif = NetworkInterface.getByInetAddress (InetAddress.getByName ("localhost")); assertNotNull (nif); }

Vagy ha konkrétan foglalkozik a localhosttal:

@Test public void givenLocalHost_whenReturnsNetworkInterface_thenCorrect () {NetworkInterface nif = NetworkInterface.getByInetAddress (InetAddress.getLocalHost ()); assertNotNull (nif); }

Egy másik alternatíva a visszacsatoló felület kifejezett használata:

@Test public void givenLoopBack_whenReturnsNetworkInterface_thenCorrect () {NetworkInterface nif = NetworkInterface.getByInetAddress (InetAddress.getLoopbackAddress ()); assertNotNull (nif); }

A harmadik megközelítés, amely csak a Java 7 óta áll rendelkezésre, az, hogy a hálózati felületet az indexével szerezze be:

NetworkInterface nif = NetworkInterface.getByIndex (int index);

A végső megközelítés a getNetworkInterfaces API. Visszaad egy Felsorolás az összes rendelkezésre álló hálózati interfész a rendszerben. Rajtunk múlik, hogy a visszaküldött objektumokat hurokban kapjuk-e le, a szokásos idióma a-t használ Lista:

Számláló hálók = NetworkInterface.getNetworkInterfaces (); for (NetworkInterface nif: Collections.list (nets)) {// tegyen valamit a hálózati felülettel}

4. Hálózati interfész paraméterek

Nagyon sok értékes információt kaphatunk az egyiktől az objektum lekérése után. Az egyik leghasznosabb a hozzá rendelt IP-címek listája.

Két API-t használva kaphatunk IP-címeket. Az első API az getInetAddresses (). Visszaad egy Felsorolás nak,-nek InetAddress olyan eseteket, amelyeket feldolgozhatunk, ahogyan azt megfelelőnek tartjuk:

@Test public void givenInterface_whenReturnsInetAddresses_thenCorrect () {NetworkInterface nif = NetworkInterface.getByName ("lo"); Számlálási címEnum = nif.getInetAddresses (); InetAddress address = addressEnum.nextElement (); assertEquals ("127.0.0.1", address.getHostAddress ()); }

A második API az getInterfaceAddresses (). Visszaadja a Lista nak,-nek InterfaceAddress példányok, amelyek erősebbek, mint InetAddress példányok. Például az IP-címen kívül érdekelheti a sugárzási cím:

@Test public void givenInterface_whenReturnsInterfaceAddresses_thenCorrect () {NetworkInterface nif = NetworkInterface.getByName ("lo"); List 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 ()); }

Hozzáférhetünk egy interfész hálózati paramétereihez, amelyek meghaladják a hozzá rendelt nevet és IP-címet. Ellenőrizze, hogy működik-e:

@Test public void givenInterface_whenChecksIfUp_thenCorrect () {NetworkInterface nif = NetworkInterface.getByName ("lo"); assertTrue (nif.isUp ()); }

Ellenőrizze, hogy loopback interfészről van-e szó:

@Test public void givenInterface_whenChecksIfLoopback_thenCorrect () {NetworkInterface nif = NetworkInterface.getByName ("lo"); assertTrue (nif.isLoopback ()); }

Ellenőrizze, hogy pont-pont hálózati kapcsolatot jelent-e:

@Test public void givenInterface_whenChecksIfPointToPoint_thenCorrect () {NetworkInterface nif = NetworkInterface.getByName ("lo"); assertFalse (nif.isPointToPoint ()); }

Vagy ha ez egy virtuális felület:

@Test public void givenInterface_whenChecksIfVirtual_thenCorrect () {NetworkInterface nif = NetworkInterface.getByName ("lo"); assertFalse (nif.isVirtual ()); }

A multicasting támogatásának ellenőrzéséhez tegye a következőket:

@Test public void givenInterface_whenChecksMulticastSupport_thenCorrect () {NetworkInterface nif = NetworkInterface.getByName ("lo"); assertTrue (nif.supportsMulticast ()); }

Vagy a fizikai címének lekérdezéséhez, amelyet általában MAC-címnek hívnak:

@Test public void givenInterface_whenGetsMacAddress_thenCorrect () {NetworkInterface nif = NetworkInterface.getByName ("lo"); bájt [] bájt = nif.getHardwareAddress (); assertNotNull (bájt); }

Egy másik paraméter a Maximum Transmission Unit, amely meghatározza az ezen az interfészen keresztül továbbítható legnagyobb csomagméretet:

@Test public void givenInterface_whenGetsMTU_thenCorrect () {NetworkInterface nif = NetworkInterface.getByName ("net0"); int mtu = nif.getMTU (); assertEquals (1500, mtu); }

5. Következtetés

Ebben a cikkben bemutattuk a hálózati interfészeket, azt, hogy hogyan lehet hozzájuk programszerűen hozzáférni, és miért kellene hozzáférnünk hozzájuk.

Az ebben a cikkben használt teljes forráskód és minták a Github projektben érhetők el.


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