Práca so sieťovými rozhraniami v prostredí Java

1. Prehľad

V tomto článku sa zameriame na sieťové rozhrania a na to, ako k nim programovo pristupovať v prostredí Java.

Jednoducho povedané, a sieťové rozhranie je bodom prepojenia medzi zariadením a ktorýmkoľvek z jeho sieťových pripojení.

V bežnom jazyku ich označujeme výrazom Network Interface Cards (NIC) - všetky však nemusia mať hardvérovú podobu.

Napríklad populárny localhost IP 127.0.0.1, ktoré pri testovaní webových a sieťových aplikácií často používame, je rozhranie spätnej väzby - ktoré nie je priamym hardvérovým rozhraním.

Systémy majú samozrejme často viac aktívnych sieťových pripojení, napríklad drôtový ethernet, WIFI, Bluetooth atď.

V Jave je hlavným API, ktoré môžeme použiť na priamu interakciu s nimi, API java.net.NetworkInterface trieda. Aby sme mohli rýchlo začať, importujme celý balík:

import java.net. *;

2. Prečo pristupovať k sieťovým rozhraniam?

Väčšina programov Java s nimi pravdepodobne nebude priamo komunikovať; Existujú však špeciálne scenáre, keď potrebujeme tento druh prístupu na nízkej úrovni.

Najvýznamnejšie z nich je, keď má systém viac kariet a vy by ste ich chceli mať sloboda výberu konkrétneho rozhrania, s ktorým sa bude soket používať. V takomto scenári zvyčajne poznáme meno, ale nie nevyhnutne adresu IP.

Normálne, keď chceme vykonať soketové pripojenie na konkrétnu adresu servera:

Zásuvka zásuvky = nová zásuvka (); socket.connect (nová InetSocketAddress (adresa, port));

Týmto spôsobom systém vyberie vhodnú lokálnu adresu, naviaže sa na ňu a bude komunikovať so serverom prostredníctvom svojho sieťového rozhrania. Tento prístup nám však neumožňuje zvoliť si ten svoj.

Tu urobíme predpoklad; nepoznáme adresu, ale vieme meno. Len na demonštračné účely predpokladajme, že chceme pripojenie cez rozhranie spätnej slučky. Podľa konvencie sa volá hľa, minimálne na systémoch Linux a Windows, na OSX áno lo0:

NetworkInterface nif = NetworkInterface.getByName ("lo"); Výpočet nifAddresses = nif.getInetAddresses (); Zásuvka zásuvky = nová zásuvka (); socket.bind (new InetSocketAddress (nifAddresses.nextElement (), 0)); socket.connect (nová InetSocketAddress (adresa, port));

Takže načítame sieťové rozhranie pripojené k hľa najskôr načítajte adresy, ktoré sú s ním spojené, vytvorte soket, naviažte ho na ktorúkoľvek z vymenovaných adries, ktorú v čase kompilácie ani nepoznáme, a potom sa pripojte.

A NetworkInterface objekt obsahuje meno a skupinu IP adries, ktoré sú mu priradené. Viazanie na ktorúkoľvek z týchto adries teda zaručí komunikáciu prostredníctvom tohto rozhrania.

Toto v skutočnosti nehovorí o API nič zvláštne. Vieme, že ak chceme, aby naša lokálna adresa bola localhost, stačil by prvý úryvok, keby sme práve pridali kód väzby.

Navyše by sme nikdy nemuseli absolvovať všetkých niekoľko krokov, pretože localhost má jednu známu adresu, 127.0.0.1 a ľahko k nej pripojíme zásuvku.

Vo vašom prípade však hľa by mohli predstavovať iné rozhrania ako Bluetooth - net1, bezdrôtová sieť - net0 alebo ethernet - eth0. V takýchto prípadoch by ste IP adresu v čase kompilácie nepoznali.

3. Načítanie sieťových rozhraní

V tejto časti preskúmame ďalšie dostupné API na načítanie dostupných rozhraní. V predchádzajúcej časti sme videli iba jeden z týchto prístupov; the getByName () statická metóda.

Stojí za zmienku, že NetworkInterface trieda nemá žiadnych verejných konštruktorov, takže samozrejme nie sme schopní vytvoriť novú inštanciu. Namiesto toho použijeme dostupné API na ich získanie.

Rozhranie API, na ktoré sme sa doteraz pozreli, sa používa na vyhľadávanie sieťového rozhrania podľa zadaného názvu:

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

Vracia sa to nulový ak žiadny nie je pre meno:

@Test public void givenInExistentName_whenReturnsNull_thenCorrect () {NetworkInterface nif = NetworkInterface.getByName ("inexistent_name"); assertNull (nif); }

Druhé API je getByInetAddress (), vyžaduje sa tiež poskytnutie známeho parametra, tentokrát môžeme poskytnúť adresu IP:

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

Alebo meno hostiteľa:

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

Alebo ak ste konkrétni o localhost:

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

Ďalšou alternatívou je tiež výslovne použiť rozhranie spätnej väzby:

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

Tretím prístupom, ktorý je k dispozícii iba od verzie Java 7, je získanie sieťového rozhrania pomocou jeho indexu:

NetworkInterface nif = NetworkInterface.getByIndex (int index);

Konečný prístup zahŕňa použitie getNetworkInterfaces API. Vracia sa Vymenovanie všetkých dostupných sieťových rozhraní v systéme. Je na nás načítať vrátené objekty v slučke, štandardný frazém používa a Zoznam:

Sčítacie siete = NetworkInterface.getNetworkInterfaces (); pre (NetworkInterface nif: Collections.list (nets)) {// urobte niečo so sieťovým rozhraním}

4. Parametre sieťového rozhrania

Po získaní objektu môžeme od jedného získať veľa cenných informácií. Jedným z najužitočnejších je zoznam adries IP, ktoré sú mu priradené.

IP adresy môžeme získať pomocou dvoch API. Prvé API je getInetAddresses (). Vracia sa Vymenovanie z InetAddress prípady, ktoré môžeme spracovať, ako to považujeme za vhodné:

@Test public void givenInterface_whenReturnsInetAddresses_thenCorrect () {NetworkInterface nif = NetworkInterface.getByName ("lo"); Výčet addressEnum = nif.getInetAddresses (); InetAddress address = addressEnum.nextElement (); assertEquals ("127.0.0.1", address.getHostAddress ()); }

Druhé API je getInterfaceAddresses (). Vracia a Zoznam z Adresa rozhrania prípady, ktoré sú výkonnejšie ako InetAddress inštancie. Napríklad okrem adresy IP by vás mohla zaujímať adresa vysielania:

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

Môžeme pristupovať k sieťovým parametrom rozhrania okrem názvu a adries IP, ktoré sú mu priradené. Skontrolujte, či je funkčný:

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

Ak chcete skontrolovať, či ide o rozhranie so spätnou väzbou:

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

Ak chcete skontrolovať, či predstavuje sieťové pripojenie typu point to point, postupujte takto:

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

Alebo ak je to virtuálne rozhranie:

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

Kontrola podpory multicastu:

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

Alebo môžete zistiť jeho fyzickú adresu, ktorá sa zvyčajne nazýva MAC adresa:

@Test public void givenInterface_whenGetsMacAddress_thenCorrect () {NetworkInterface nif = NetworkInterface.getByName ("lo"); byte [] bytes = nif.getHardwareAddress (); assertNotNull (bajty); }

Ďalším parametrom je jednotka maximálneho prenosu, ktorá definuje najväčšiu veľkosť paketu, ktorá sa dá preniesť cez toto rozhranie:

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

5. Záver

V tomto článku sme si ukázali sieťové rozhrania, ako k nim programovo pristupovať a prečo by sme k nim potrebovali prístup.

Celý zdrojový kód a ukážky použité v tomto článku sú k dispozícii v projekte Github.


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