Zjišťování služeb v rámci LAN

nápad

Předpokládejme situaci – máte dvě zařízení ve stejné Local Area Network a chcete odeslat soubor ze zařízeníA do zařízeníB .

    deviceA -> deviceB

Tak tohle funguje. Ale až příště spustíte tyto programy, zařízeníA a zařízení B může mít různé IP adresy nebo jiné zařízeníC může mít zájem podílet se na přenosu souborů, což vás nakonec může vést k ruční aktualizaci PEER's IP adresa 😞.

Tak se dáme do práce 🏃

model

Budeme používat DatagramSocket , za zpracování reklamy na služby a Zjišťování služby s v LAN. Implementace bude provedena pomocí jazyka Dart a úryvky pro JavaScript bude poskytnuto.

init

Nejprve napíšeme Inzerent služeb tj. program serveru UDP.

Inzerent služeb

Třídy požadované pro implementaci navrhované funkce.

import 'dart:io' show RawDatagramSocket, RawSocketEvent, InternetAddress, Datagram;
import 'dart:convert' show utf8;

Vazba RawDatagramSocket na InternetAddress.anyIPv4 a port 8000 , takže může naslouchat na všech rozhraních na portu 8000 .

RawDatagramSocket.bind(InternetAddress.anyIPv4, 8000).then((datagramSocket) {
    // more code coming ...
  });

Můžete vidět RawDatagramSocket.bind( ... ) vrátí Budoucnost . Povolíme READ posluchač událostí na tomto soketu, takže kdykoli se jakékoli jiné zařízení pokusí něco zapsat do tohoto soketu, posluchač bude upozorněn.

datagramSocket.readEventsEnabled = true; // put this line within aforementioned `then()`

Nyní budeme poslouchat READ události na toto téma
DatagramSocket . Kdykoli nový ČTĚTE dojde k události, je načtena pomocí DatagramSocket.receive() a druhý konec dostane upozornění, že dosáhl platného inzerenta služeb .

datagramSocket.listen((RawSocketEvent event) {
      if (event == RawSocketEvent.read) {
          // checking whether it's a read event or not
        Datagram dg = datagramSocket.receive();
        if (dg != null) {
        // notifying other end that it has reached a service advertiser
          datagramSocket.send(dg.data, dg.address, dg.port);
          print('${dg.address}:${dg.port} -- ${utf8.decode(dg.data)}');
        }
      }
    });

PEER's IP adresa, číslo portu a přijatá data jsou extrahována z Datagramu objekt, přijato při výskytu READ událost.

Přijatá data jsou dekódována zpět do řetězce ze Seznamu , pomocí následující funkce z utf8 modul.

utf8.decode(dg.data);

Dobře Inzerent služeb je hotovo 😉.

Service Discoverer

Možná jste již uhodli, že se bude jednat pouze o klienta UDP.

Třídy požadované pro implementaci funkce zjišťování služeb.

import 'dart:io' show RawDatagramSocket, RawSocketEvent, InternetAddress, Datagram;
import 'dart:convert' show utf8;

Opět potřebujeme svázat RawDatagramSocket na InternetAddress.anyIPv4 a port 0, který vrátí Budoucnost .

RawDatagramSocket.bind(InternetAddress.anyIPv4, 0).then((datagramSocket) {
    // more code coming ...
  });

Během Inzerce služeb , právě jsme poslouchali READ události na RawDatagramSocket , ale nyní také povolíme vysílání , aby tento soket mohl odeslat vysílanou zprávu na 255.255.255.255 , který se dostane na všechna zařízení v rámci LAN.

// put these two lines with in previous `then()`
datagramSocket.broadcastEnabled = true;
datagramSocket.readEventsEnabled = true;

Je čas poslat zprávu na broadcastAddress a port 8000.

datagramSocket.send("io.github.itzmeanjan.transferZ".codeUnits,
        InternetAddress("255.255.255.255"), 8000);

Výše uvedená zpráva se dostane ke všem zařízením přítomným v LAN, která naslouchají READ událost na portu 8000.

Možná vás zajímá, co je "io.github.itzmeanjan.transferZ".codeUnits , vrátí Seznam z řetězce , která má být odeslána jako broadcastMessage .

Nyní dáme logiku potřebnou pro poslech READ události na RawDatagramSocket . Následující úryvek je velmi blízký tomu, který jsme použili v Service Advertiser , kromě skutečnosti, že inzerentovi služby nic zpět neposíláme .

datagramSocket.listen((RawSocketEvent event) {
      if (event == RawSocketEvent.read) {
        Datagram dg = datagramSocket.receive();
        if (dg != null) {
          print('${dg.address}:${dg.port} -- ${utf8.decode(dg.data)}');
          //datagramSocket.close();
          // You may consider uncommenting previous line, if you want to explore only one Service Advertiser at a time.
        }
      }
    });

A náš Objevitel služeb je kompletní 😃.

spustit

Čas to spustit 🏃

Inzerent služeb

Spusťte jej pomocí

$ dart service_advertiser.dart

Service Discoverer

Nyní spusťte vyhledávač služeb pomocí

$ dart service_discoverer.dart

Zde je to, co se stalo ---

Spouštím Service Advertiser z jednoho terminálu, jiného inzerenta služeb z Flutter mobilní aplikace a Service Discoverer z jiného terminálu na stejném počítači. Všechna tato zařízení jsou ve stejné LAN.

Nejprve náš Služba Discoverer odešle broadcastMessage na 255.255.255.255 na portu 8000 a začne naslouchat READ události na RawDatagramSocket . Poté Inzerent(i) služeb přijímat PŘEČÍST oznámení o události a reaguje na něj. Odpověď přichází do Service Discoverer , přečte to a vytiskne na obrazovku.

konec

A úspěšně jsme implementovali reklamu a zjišťování blízkých služeb s zásuvkou pro datagram implementované pomocí jazyka Dart .

Pokud se chcete naučit, jak to používat s aplikací flutter, můžete zvážit kontrolu transferZ, aplikace pro Android vytvořená pomocí ❤️ pomocí Flutter pro odesílání souborů do zařízení v LAN.

Uvidíme se v dalším článku. Mezitím mě můžete sledovat na GitHubu a Twitteru.

Ukončete čas ✌️.