NOVINKA - Online rekvalifikační kurz Java programátor. Oblíbená a studenty ověřená rekvalifikace - nyní i online.
NOVINKA – Víkendový online kurz Software tester, který tě posune dál. Zjisti, jak na to!

Diskuze: Linux+síťová komunikace C nebo BASH

Aktivity
Avatar
pyrin
Člen
Avatar
pyrin:30.8.2015 12:03

Dobrý den, chci si pohrát, abych nezlobil. Mám tu Alix routerboard a na něm OpenWRT distribuci. Potom mám vzdálený server a na něm běží aplikace, který po napojení klienta přes TCP spojení pošle klientovi 10 bajtů - je to jakýsi dotaz. Tento dotaz by měl Alix přeposlat na jeho fyzickou sériovou linku beze změny obsahu, na sériové lince je nějaký jednočip, který zpracuje příchozí dotaz a odešle zpět odpověď 128 bajtů. Těchto 128 bajtů musí beze změny projít sítí až na server. A teď otázka, jak řešit tunel na Alix routerboardu ? Zkoušel jsem nejdříve psát v C aplikaci, která sestaví spojení na server, přijme těch 10 bajtů, rozkóduje je, přepočítá CRC, znovu zakóduje a přepošle na sériovou linku. Očekává odpověď od jednočipu. Odpověď přijde, rozkóduje, přepočítá CRC, zakóduje a odešle 128 bajtů na server. Toto mi funguje jednak v jednom vláknu a pak jsem si to přepsal i do vícevláknové aplikace a funguje též. Potom jsem dal na radu kamaráda, který mi říkal, že psát to v C je naprostá blbost, když to lze udělat pomocí operačního systému. Tož jsem našel příkaz SOCAT a vyzkoušel jej. Ano nemusím se starat o rozkódování, přepočítání CRC a zakódování zpět (což je mimochodem i zbytečná operace). V tomto ohledu má kamarád pravdu. ALE !. Narážím na otázku, jak pomocí SOCAT zjistím, zda se mi spojení náhodou nerozpadlo a když ano, tak na jaké straně, zda směrem k serveru nebo zda směrem k jednočipu. Server posílá dotazy periodicky každých 55s. Tak jsem si říkal, že by to chtělo mít tam nějaký časovač třeba na 2 minuty a pokud během těch 2 minut nebude úspěšná komunikace, tak se uzavře - zabije SOCAT nebo můj původní céčkový kód a po nějakém čase se opět spustí znovu. Takže nevím jak to udělat pomocí SOCAT a dále mne jiný kamarád přesvědčuje, že by to pomocí SOCAT nedělal, protože to je spíš systémová záležitost a ne aplikační. Aplikace by tedy měla být spíš v C nebo jiném jazyku. Prosím názory, nějak v tom plavu, a na druhou stranu bych se rád něco dozvěděl, jak to dělat nebo nedělat. Pěkný den, Jirka

 
Odpovědět
30.8.2015 12:03
Avatar
Odpovídá na pyrin
Michal Žůrek - misaz:30.8.2015 12:34

Otázkou, ale je jestli když síť spadne nebo cokoliv jiného spadné (= nepošle to) je třeba ukončovat aplikaci? Já bych ji normálně nechal běžet.

 
Nahoru Odpovědět
30.8.2015 12:34
Avatar
David Novák
Tvůrce
Avatar
Odpovídá na pyrin
David Novák:30.8.2015 14:13

typicky se to řeší tak, že v tom paketu si posíláš číslo, které ho identifukuje.. např. paket č. 154894, takže pak pošleš paket a čekáš na odpověď se stejným číslem - pokud ti nějaký nepřijde v nějakém časovém limitu (ztratil se), pošleš ho znova.. Pokud se ti jich ztratí x, tak můžeš předpokládat, že se přerušilo spojení a vysílání třeba na nějakou dobu pozastavit..

Protokol TCP něco takového přímo implementuje, takže teoreticky můžeš používat nějakou aplikaci, které jen předložíš data a nastavíš parametry a ona se o to postará.. Nebo si v rámci zábavy můžeš udělat vlastní protokol (s ID paketů, etc - jak jsem řekl) ;)

Nahoru Odpovědět
30.8.2015 14:13
Chyba je mezi klávesnicí a židlí.
Avatar
pyrin
Člen
Avatar
Odpovídá na Michal Žůrek - misaz
pyrin:30.8.2015 14:32

OK, aplikaci tedy nechám běžet, a teď hloupě, server mi neposílá dotazy, tak aplikace by měla uzavřít socket a vytvořit nový? Tedy předpokládám, že na cestě se stávající socket nějakým způsobem rozpadl, třeba někdo provedl reset nějakého routru. A názor na to, zda použít C aplikaci a nebo SOCAT by byl ? Jirka

 
Nahoru Odpovědět
30.8.2015 14:32
Avatar
pyrin
Člen
Avatar
Odpovídá na David Novák
pyrin:30.8.2015 14:38

OK, děkuji za názor. S číslováním paketů mně to napadlo taky. Mně spíš ale v tuto chvilku zajímá to, zda když otevřu socket směrem do serveru a z nějakého důvodu (třeba se po cestě resetovalo nějaké zařízení) mi server nic neposílá, tak zda socket uzavřít a otevřít znovu a čekat na příchozí data. A opět se zeptám, zda řešení pomocí utilitky SOCKAT je vhodným řešením nebo ne a jak případně provézt nějakou diagnostiku. Se SOCKAT mám skriptík v BASH, který když se SOCKAT killne, tak se spustí znovu. Ale nevím, jak jej killnout v závislosti, jestli SOCKATEM něco teče nebo neteče. Udělat nějakou jako odbočku a tou to sledovat. Napadlo mne SOCKATem si udělat spojení mezi serverem a souborem - rourou, a potom ještě mezi rourou a sériovou linkou. A následně ty 2 roury spojit nějakým C prográmkem, který by diagnostikoval tok dat. Asi vymyšlím již vymyšlené, ale nějak nenacházím přesně to co chci. Jirka

 
Nahoru Odpovědět
30.8.2015 14:38
Avatar
David Novák
Tvůrce
Avatar
Odpovídá na pyrin
David Novák:30.8.2015 14:45

Typicky by měl komunikaci iniciovat klient (a server odpovídá). Takže můžeš třeba přenášet data takto: Klient si zažádá o data (tím také server ví, kam je má poslat -> nemáš problém se zjišťováním adresy, pokud je přidělována pomocí DHCP), server pošle paket 1, klient potvrdí příjem paketu 1, server pošle paket 2, atd..
Samozřejmě, že tvůj server se může ptát klienta (ovšem logicky jsou pak role prohozeny), ale bylo by pak dobré poslat na začátku broadcast (což může být do jiné sítě trochu komplikovanější) a klient na něj odpoví.. Nebo to neřešit vůbec a spoléhat se na statickou adresu (což ale trochu omezuje univerzálnost použití)..

V zásadě jde o to, jestli si jen tak hraješ, nebo jestli to na něco potřebuješ.. Jestli si hraješ, tak by možná i bylo lepší udělat nějaký jednoduchý protokol od píky a napsat si aplikace (server a klient) třeba v tom C.. Na učení se je to nejlepší ;)

Jinak si prostuduj: http://linux.die.net/man/1/socat

Nahoru Odpovědět
30.8.2015 14:45
Chyba je mezi klávesnicí a židlí.
Avatar
pyrin
Člen
Avatar
Odpovídá na David Novák
pyrin:30.8.2015 17:22

Tak to vezmu po pořadě. V zásadě si zatím hraju. Po baráku mám různé měření a různé ovládání. Měřím zatím jen teploty. Ale měřím třeba 8 teplot ve zdi. Čidla jsou umístěna v celé šířce zdi a měly by sloužit jen k poměrovému zobrazení prostupu tepla zdivem a izolací. Potom ovládám třeba rolety a zatím centrálně zdroj tepla. Zjednodušeně řečeno je to asi 12ks jednočipů, které umí adresovatelně komunikovat po RS485. Dnes mám v Alixu napsanou aplikaci v C, která po startu inicializuje sériovou linku a periodicky z každého jednočipu vyčítá datové pole 128 bajtů. Toto pole se rozparsuje a nastrká do MySQL. Zároveň v databázi mám seznam parametrů jednotlivých jednočipů, a tyto hodnoty mohu měnit. Na úrovni rozhraní typu PhpMyAdmin mi to všechno funguje. Takže trošku s programováním nějaké zkušenosti mám. Použitý protokol v jednočipech je tak trošku specifický. Používá znaky C0 pro start paketu a C1 pro konec paketu. Dále používá pro výskyt těchto znaků v paketu mimo začátek a konec ještě překódování XOR 7D. Je v tom ještě použito 16bit CRC. V podstatě každý paket obsahuje tyto křídelní značky, adresu slave jednotky, adresu master jednotky tedy třeba toho Alixe a dále typ paměťové oblasti, adresu v oblasti, počet přenášených data informaci o tom, zda se bude číst nebo zapisovat. Myslím, že toto velice dobře funguje a nehodlám na tom nic měnit. Tak a teď k mému vlastnímu problému. Chtěl bych hodnoty dostat na web ve formě tabulky, grafu a taky abych měl možnost zobrazit hodnoty parametrů a nastavit je, potažmo zapsat do konkrétní jednotky. S tvorbou webu jsem ale úplně mimo, proto jsem šáhnul po kamarádovi, který mi trošku upravil jakousi webovou aplikaci, která funguje takto: vezmu toho mého Alixe nebo jiný routerboard, otevřu jako klient socket na server. Server naslouchá a akceptuje spojení a vyšle mým protokolem směrem do klienta dotaz. Tento dotaz se přepošle až na RS485 a příslušný adresovaný jednočip zpracuje příchozí příkaz a odpoví zpět směrem routerboard a server. Tak a moje původní otázka zněla, jak routerboard pozná, že je spojení nefunkční a co by měl udělat ? Pokud to udělám v C, tak mám pod kontrolou data procházející za serveru do jednočipu i obráceně a mohu tedy reagovat uzavřením socketu a jeho znovu otevřením, popřípadě uzavřením sériové linky a jejím znovuotevřením. Pokud ale použiju utilitku SOCKAT, tak nějak neumím vyčíst z dokumentace, zda mohu nějakým způsobem kontrolovat třetí stranou, zda ním tečou předpokládaná data.
Nevím co si tedy vybrat. Každý řekne něco jinýho, někdo že mám použít především služby operačního systému a že je nevhodé použít nízkoúrovňové funkce typu read x write nad souborovými deskriptory.
Jirka

 
Nahoru Odpovědět
30.8.2015 17:22
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 7 zpráv z 7.