loader
Foto

TCP csomagok küldése a felhőbe C# nyelv segítségével

Folytatjuk az Internet of Things (IoT) sorozatunkat, most elkészítjük azt az alkalmazást, amelynek segítségével el tudjuk tárolni azokat az adatokat, amelyek TCP protokoll segítségével érkeznek a felhőbe. Fontosnak tartjuk megjegyezni, hogy sok Olvasónknak nincs Quectel (vagy egyéb GSM-es fejlesztőeszköze), ezért az adatot küldő érzékelőt egy C# nyelven megírt klienssel helyettesítjük a szimuláció során.

Nem mindenki rendelkezik olyan eszközzel (pl.: Quectel, M66), amelynek segítségével adatok továbbíthatók (pl.: TCP segítségével) a felhőbe, azaz egy szerveren lévő adatbázisba.
Ezért először megnézzük azt is, hogy hogyan tudjuk helyettesíteni ezt az eszközt egy C# nyelven megírt alkalmazással. Ha nincs olyan fejlesztő panelunk, amelynek segítségével TCP csomagokat tudunk küldeni a felhőbe (a felhőben lévő C# nyelven írt szerverhez), akkor ezt a panelt egy C# nyelven írt klienssel is kiválthatjuk most (1. ábra).

kep
1. ábra   Az elkészíteni kívánt architektúra modell


Cikkünk végén megadjuk azt a linket is természetesen, hogy valamilyen fejlesztőeszköz birtokában milyen "kliens programot" kell írnunk. A cikk írásakor mi a C# nyelven írt klienst használtuk fel.

Indítsuk el a Visual Studio 2015 Community-t, és töltsük be a korábban létrehozott projektünket (ConsoleIoTPelda).

A ConsoleIotPelda (al)projektünkhöz, amely a szerver funkciót valósítja meg, adjunk hozzá egy "LINQ to SQL Classes" típusú új item-et (2. ábra). Ennek segítségével egy proxyosztályt adunk a szerver(al)projekthez.

kep
2. ábra   Proxyosztály (paldeDataContext) hozzáadása a szerver alprojekthez
 

Ha ezt hozzáadtuk a projektünkhöz (3. ábra), akkor megjelenik egy grafikus tervezőnézet.

kep

3. ábra   A projektünkhöz hozzáadott proxyosztály (pelda.dbml)
 

Az automatikusan megjelenő grafikus tervezőnézetbe tegyük be a Server Explorer ablakból az "Eredmeny" nevű adattáblánkat a "Felho" adatbázisból (4. ábra). Ezután mentsük el a pelda.dbml file-t.

kep
4. ábra   Az Eredmeny nevű adattábla
 

Ezekkel a műveletekkel elértük azt, hogy az adatbázisunk (amely egy állandó IP címmel rendelkező VPS-en van) kényelmesen elérhető C# programsorokkal, tehát nem szükséges connection string-et, illetve SQL parancsokat írnunk.

Akár használunk fejlesztőpanelt, akár "modellezzük" azt egy C# kliens alkalmazással, szükségünk van egy szerverre, amely fogadja a TCP csomagokat, és azokat eltárolja egy adatbázisban (MSSQL). 
Készítsük el most először a szervert, amely "összeköti" tehát az érzékelőnket / klienst az adatbázissal!

A kliens modellünk véletlenszámokat állít elő 0-tól 255-ig terjedő tartományban. A feladatunk az, hogy ezeket a véletlenszámokat átküldjük TCP protokollal a szerverhez. A szerver ezeket a kapott számokat a fogadás dátumával együtt elmenti az "Eredmeny" nevű adattáblába.

A projektünkben található ConsolIoTPelda (3. ábra) alprojektben található Program.cs file-t nyissuk meg és másoljuk be a következő kódot :

 

class Program
    {
        public static void Main()
        {
            int portszam = 8080;
            int fogadott = 0;
            try
            {
                peldaDataContext pdc = new peldaDataContext();

                IPAddress ipAd = IPAddress.Parse("127.0.0.1");
                TcpListener weListener = new TcpListener(ipAd, portszam);
                weListener.Start();
                Console.WriteLine("Működik ezen a porton : " + portszam);
                Console.WriteLine("Végpont : " + weListener.LocalEndpoint);
                while (true)
                {
                    Socket sck = weListener.AcceptSocket();

                    byte[] tomb = new byte[10];
                    int darab = sck.Receive(tomb);
                    string str = System.Text.Encoding.UTF8.GetString(tomb, 0, darab);
                    fogadott = int.Parse(str);
                    DateTime dt = DateTime.Now;

                    Console.Write("Fogadott : {0}",str);
                    Console.WriteLine(",   ekkor : {0}",dt.ToLongTimeString());

                    Eredmeny ujErtek = new Eredmeny()
                    {
                        Ertek = fogadott,
                        Datum = dt
                    };

                    pdc.Eredmenies.InsertOnSubmit(ujErtek);
                    pdc.SubmitChanges();

                    sck.Close();
                }
                weListener.Stop();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
            Console.ReadLine();
        }
    }

 

Ez a kód nagyon hasonlít a korábban közölt TCP szerverhez, ezért részletesen nem mutatjuk be, csak pár sort emelnénk ki.

  1. Példányosítjuk a proxyosztályt, ezután a "pdc" példány segítségével könnyen elérjük az adattáblánkat, illetve az adattáblába történő beírás kényelmessé válik 
    "peldaDataContext pdc = new peldaDataContext();"
  2. A klienstől érkező adatok byte-okban (nem char!) érkeznek, nekünk a byte-okból kell string-et létrehoznunk. Fontos az átalakításnál a fogadott adatok száma, ez határozza meg a létrehozandó string hosszát. Erre szolgál a
    "string str = System.Text.Encoding.UTF8.GetString(tomb, 0, darab);"
  3. Az adattáblánkba egész számot tudunk elmenteni a string helyett, ezért parsolnunk kell
    fogadott = int.Parse(str);
  4. Az Eredmeny osztályból létrehozott "ujErtek" példány tulajdonságai értéket kapnak, majd ezt beírjuk az adattáblába.
    pdc.Eredmenies.InsertOnSubmit(ujErtek);
  5. Hiába írjuk be az adattáblába a TCP-n kapott véletlen számot és a fogadás dátumát, a beírást véglegesítenünk kell
    pdc.SubmitChanges();

 

Ha nincs fejlesztőpanelünk, akkor valósítsuk meg most a klienst is. A ConsoleIoTPeldaKliens nevű alprojektben található Program.cs-t nyissuk meg és másoljuk bele a következő kódrészletet :

 

class Program
    {
        public static void Main()
        {
            int portszam = 8080;
            Timer tmr = new Timer(5000);
            tmr.Elapsed += Tmr_Elapsed;
            tmr.Enabled = true;
            Console.WriteLine("Elindult a tesztkliens");
            while (true) ;
        }

        private static void Tmr_Elapsed(object sender, ElapsedEventArgs e)
        {
            try
            {
                TcpClient tcpKliens = new TcpClient();
                tcpKliens.Connect("127.0.0.1", 8080);

                Random rnd = new Random();
                int Veletlen = rnd.Next(0, 256);
                Stream stm = tcpKliens.GetStream();

                ASCIIEncoding asen = new ASCIIEncoding();
                byte[] tomb = asen.GetBytes(Veletlen.ToString());
                stm.Write(tomb, 0, tomb.Length);

                tcpKliens.Close();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }
    }

 

Nézzük meg ennek a programnak (korábbi verzió) néhány érdekességét.

  1. A Timer osztály több szerelvényben is megtalálható, nem mindegy, melyiket használjuk. Mi a "using System.Timers;"-t alkalmaztuk.
  2. A Timer-ünk időzítését (5 másodperc) a Timer példányosításánál állítjuk be a konstruktornál.
    Timer tmr = new Timer(5000);
  3. A Timer-ünk 5 másodpercenként kiváltja az "Elapsed" eseményt, amelyben hozzuk létre a véletlenszámot és küldjük el.
  4. A "Veletlen" nevű véletlenszámból készítünk egy string-et, majd egy byte tömböt, mert byte-okat tudunk TCP-n átküldeni
  5. A Main() metódus a while(true) végtelen ciklus miatt soha nem ér véget.

 

Indítsuk el a Visual Studio-ban a projektünket. Először a szerver, azután a kliens (ezzel modellezzük a TCP csomagokat küldő szenzort) indul el.

Ha mindent jól csináltunk, akkor a szerver és a kliens kapcsolat létrejön, és a kliens 5 másodpercenként küld egy véletlenszámot. A szerver a konzolon megjeleníti ezt a számot, illetve ennek a számnak a fogadási dátumát (5. ábra).

kep
5. ábra   Működik a szerver-kliens, adatok érkeznek 5 másodpercenként
 

Ez a szerverprogram a tesztelés során localhost-ban (IP cím : 127.0.0.1) fut, de az adatbázis egy saját IP-vel rendelkező VPS-en helyezkedik el. Tehét hiába fut a saját asztali számítógépen a szerveralkalmazásunk a klienssel együtt debug módban, a beérkezett adatok eltárolása már egy külön számítógépen, egy adatbázisban történik.
A tesztelés során ez a projekt debug módban 200*5 másodpercig futott, tehát 200 rekordot tároltunk el az adattáblában. A rekordok egy részét látjuk a 6. ábrán.

kep
6. ábra   Az első 15 eltárolt rekord a felhőben
 

Felmerülhet a kérdés, hogy hogyan lehet módosítani az adatbázis elérhetőségét? Például, nincs VPS-ünk, de szívesen kipróbálnánk ezt a projektet úgy, hogy az adatbázisunk is azon a számítógépen van, ahol az alkalmazásaink is futnak.

Módosíthatjuk a szerverprojekt App.config file tartalmát, mert itt található a VPS-nek az elérhetősége, illetve a loginnév és a jelszó is (7. ábra).

kep
7. ábra   App.config file tartalma, itt található az SQL szerveren lévő "felho2" adatbázis, benne az "Eredmeny" adattábla
 

A másik lehetőség a localhost-ban található adatbázisunk használatára, hogy amikor a Visual Studio Server Explorerénél felvesszük a localhost-ban található adatbázis(oka)t, akkor az adatbázis elérési útvonala : ".\sqlexpress", és windows-os autentikációt kell alkalmaznunk (8. ábra).

kep
8. ábra   Localhost-ban található SQLExpress nevű SQL szerver felvétele
 

Aki rendelkezik Quectel fejlesztőpanellel, annak az Olvasónak nem kell a klienst elkészíteni C# nyelven, hanem ebben a cikkben leírt módon tudja a most megvalósított felhőt elérni.

A következő részben a felhőben eltárolt adatokat jelenítjük meg chart-on, illetve táblázatos formában.

 



Egyéb cikkek

Mappa

További cikkeink ebben a témakörben

Régebbi cikkeink

Ebben a cikkben elkészítünk nulláról egy ASP.NET Core MVC projektet. Egy kitalált IoT alkalmazás által küldött adatokat fogunk megjeleníteni MVC alkalmazás segítségével. Célünk az, hogy az MVC projekt ismertetése során megismerjük a C.R.U.D. művelete. . . .

Az ASP.NET Core környezet alkalmaz handler-eket. Most átnézzük ennek a handlerek használatának alapjait. Áttekintjük a get és a post lehetőségeket, illetve készítünk saját handlereket is, amelyek egyikével még paramétert is átadhatunk. Ezeknek a hasz. . . .

Korábban többször foglalkoztunk webszolgáltatásokkal, terítékre került a WCF is. Most a TcpListener osztály segítségével létrehozunk egy TCP szervert, pár nap múlva pedig az ehhez tartozó klienst készítjük el.. . . .