A hálózatban dolgozik a qt
A cikk bemutatja, hogyan kell a hálózattal együttműködni a nagyon egyszerű hálózati csevegés példájával, és leírja azt a hálózati adaptert is, amely nem rendelkezik tervezési sablonokkal (adapter, csomagoló, csomagoló).
Annak ellenére, hogy csevegésünk a lehető legegyszerűbb (nem engedélyezi fájlok és offline üzenetek átvitelét, nem tárol történelmet, nem továbbít titkosított üzeneteket stb.), Továbbra is elkülönítjük a hálózattal való munkavégzésért felelős részt. Ez a rész fogja használni a QTcpSocket osztályt, amelynek kezelőfelülete nem felel meg nekünk, ezért alkalmazzuk a Wrapper tervezési mintát.
A csevegõszerver ugyanabban a szálban dolgozik, mert Ennek a cikknek az a célja, hogy olyan példát írjon le, amely a legegyszerűbben és egyértelműen Qt-foglalatok használatát mutatja. A következő cikkek egyikében valószínűleg egy többszálas csevegést írok le.
- tervezési minta Adapter;
- dolgozik a hálózattal a Qt. QTcpServer és QTcpSocket osztályok;
- példa az Adapter minta használatára;
- a hálózati csevegõ forráskódja.
1. Tervezési mintaadapter
Az adapter szerkezeti tervezési mintákra vonatkozik, és olyan esetekben használatos, ahol egy osztály jelenik meg, amelynek a kezelőfelülete valamilyen okból nem megfelelő. A probléma nyilvánvaló megoldása az, hogy egy új osztályt hozunk létre egy "helyes" interfésszel, amely valamilyen módon átruházza a kéréseket egy "rossz" felülethez tartozó osztályra - míg a felületet, amely nem tetszik nekünk, úgy tűnik, hogy "rejtőzik". Ezért az adapter tervezési mintáját is nevezik csomagolónak.
Ábra. 1 tervezési sablon adapter. probléma
Az 1. ábra egy olyan tipikus helyzetet mutat be, amelyben egy adapter használata megfelelő lehet. Vannak olyan kódok (Kliens), amelyek A és B osztályú példányokat használnak, közös interfészt alkalmazva. Egy ponton az Adaptee osztályt kellett használni az A és a B ponttal. de nem hajtja végre a szükséges felületet.
Valószínűleg az Adaptee osztály eléggé összetett, hogy nem fordul elő, hogy átírjuk egy új interfésszel, vagy felmászunk rá, hogy "podpilit" a felület.
Ennek a problémának az első megoldása, hogy az Interface és az Adaptee osztályokat örököse az Adapter osztályban. amint azt a 2. ábra mutatja. Ebben az esetben a privát örökséget az Adaptee osztályhoz használják. mert az adapternek nem szabad extra felületet biztosítania. Ez a megoldás osztályadapternek, többszörös öröklésnek és az abból következő összes problémának köszönhető.
Ábra. 2 osztályú adapter
Egy másik lehetőség az objektum adapter, amely az interfész örökléséből és az adaptálható osztály összesítéséből áll (3. ábra). Egy ilyen megoldás rugalmasabb, és nincs hátránya a többszörös öröklésnek. Azonban, mivel az adaptálható osztály elemeinek elérése a mutatón keresztül történik, a sebesség csökken.
Ábra. 3 objektumadapter
A diagrammokból álló példa nagyon egyszerű és absztrakt, valójában minden teljesen másképp zajlik - a feladat nem csak a függvénysáv csere a foo-val. de sok munkát kell elvégeznie az interfész adaptálásával kapcsolatban.
2. A hálózathoz való munka a Qt. QTcpServer és QTcpSocket osztályok
A Qt könyvtárban egy modul működik a hálózattal - a Qt Network-rel. melynek csatlakozásához a projektfájlban elegendő egy sor hozzáadása:
A modul számos hasznos osztályt tartalmaz, többek között a korábban tárgyalt QHttp [2], QTcpSocket és QTcpServer.
A QTcpServer fő feladata az ügyfelek kapcsolódásának felügyelete. A kiszolgáló egy adott porton figyel. a meghallgatás módjának megadásakor. Amikor az ügyfél csatlakoztatva van, újConnection jelet generál és egy socket (QTcpSocket) van létrehozva, hogy adatokat cseréljen az ügyféllel. Az aljzatba mutató mutatót a nextPendingConnection hívásával kaphat.
Az ügyféllel történő adatcsere az aljzaton keresztül történik. Amikor az ügyfél leválik, az aljzat szétkapcsolt jelet generál. és amikor bejön az adatcsatlakozóba, a jel készen áll. A ReadRead jelet akkor hívják meg, amikor egy új adat kerül be az aljzatba, és megismerheti, hogy mennyi adat áll rendelkezésre az aljzat olvasásához a bájt elérhetõ módszerrel.
Annak érdekében, hogy az adatok belépjenek az aljzatba, ott meg kell írni őket, ehhez használják a QTcpSocket :: write módszert. Régi bájt sorozatot írhatunk az aljzatba:
Az 1. sorban a karakterláncot az aljzatba írjuk. Ha a soron kívül valami mást is szeretne írni, csak az 5 sor fog változni. Az aljzat adatblokkjait írjuk, a blokk elején számos bájt van. Az ötödik sorban. A blokk kezdetén tároljuk a jövőbeli méretű memóriát, írjuk be a blokk többi adatait, állítsuk be a rekordmutatót a 7. sor elejére, és helyezzük el a kapott blokkméretet ebben a sorban.
Amikor az adatokat az aljzatból olvassa, figyelembe kell vennie, hogy az adatok része lehet. Senki sem garantálja, hogy az írási funkciókhoz két hívás következik. a readyRead jel pontosan kétszer küldhető el - lehet többször is küldeni (akár csak egyszer).
A 2. listában pontosan egy sor olvasható le az aljzatból, de ha több adat olvasható, csak a 14 sornyi kód változna. Az ebben a kódban levő örök ciklusra azért van szükség, mert az aljzatba való íráshoz több jel juthat el egy jelzéssel. Olvassa el - meg kell dolgoznia az összes adatot az aljzatban. Szöveg olvasásakor az üzenetjelzés ebben a példában generálódik.
3. Példa az Adapter minta használatára
Az adapter példája nem lesz túl jellegzetes, mert nem lesz A és B osztály (3. ábra) - az osztályt nem a meglévő rendszerhez igazítjuk, hanem a tervezetthez.
Ábra. 4 szokatlan adapter
A 4. ábra nagyjából megmutatja, hogy mit fogunk tenni. Mivel az Adaptee a Qt könyvtárak osztályú QTcpSocket foglalataként működik. Nem nagyon kellemes dolgozni ezzel az aljzattal - még mindig nagyon alacsony szintű dolog. Az ügyfél chat vagy szerver lesz, amelynek fejlesztésében kényelmesebb felületet szeretnénk elérni - ezért egy réteget adunk hozzá adapterként. Külsőleg ez nem nagyon hasonlít a szabványos adapterhez. de ugyanazokat a problémákat oldja meg - az aljzatosztály interfésze (illeszkedik) a kívánt formához.
Szeretném, ha az aljzat bejelenti, hogy a kapcsolat és az új adatok megszakadnak, amikor teljesen beérkeznek, és lehetővé teszik az adatok elküldését is. Ehhez az illesztőfelületnek 2 jelet és egy küldési módot (vagy rést) kell tartalmaznia. Ez az interfész a 3. listán látható.
Az illesztőosztály összesíti a foglalatot, és örököli az interfészt. Ennek eredményeképpen az összes csatlakozó művelet egy szép felület mögött rejlik.
Egy példa lenne sikeresebb, ha a csevegés más forrásokból (a TCP aljzatból) származó adatokat is megkaphat, amelyek végrehajtaná a felületünket. Ilyen források lehetnek például a QUdpSocket fölött lévő csomagolások vagy a védett formában történő adatátvitel témájával kapcsolatos változatok. Példánkban az adapter az alkalmazás eredményén kiderült, hogy hasonlít a homlokzatra.
4. A hálózati chat forráskódja
A kliens és a szerver osztályainak (nem pontosan UML) diagramját az 5. ábra mutatja. Néhány osztályt már részletesen megvizsgáltunk.
Ábra. A hálózati csevegőórák 5 diagramja
A MainWidget a fő chat ablak, összefoglalja a Qt Designer által létrehozott űrlapot [4]. Az űrlap 2 beviteli mezőt és egy gombot tartalmaz. A gomb megnyomásakor a ClientSocketAdapter osztály sendString funkciója hívásra kerül. és a beviteli mező törlődik. Amikor az üzenetjelet a ClientSocketAdapter fogadja. A fő formanyomtatvány második mezőjét a kiszolgálótól kapott vonal egészíti ki.
A szerverosztály összesíti a QTcpServert. valamint a socket adapterek mutatóinak listáját. Amikor az ügyfél csatlakozik, szervereink a QTcpServer létrehozott aljzatához mutatót kapnak, amely alapján a szervercsatlakozó (ServerSocketAdapter) létrejön és hozzáadódik a listához. A kiszolgáló tárolja a csatlakoztatott ügyfelek listáját, hogy üzeneteket továbbítson közöttük. Amikor minden ügyfél megkapja az üzenetet, a kiszolgáló megkerüli az adapterek listáját, és meghívja az sendString metódust. Az ügyfél leválasztása után az illesztő eltávolításra kerül a listáról. Az adapter megsemmisítője biztosítja a memória helyes kiadását az aljzat alatt (QTcpSocket).
Mivel az ügyfél és a szerver ugyanazon formátumú üzeneteket cserél, a kliens socket adapter szinte azonos a kiszolgálócsatlakozóval. így a kód nagy része átvihető a SocketAdapter osztályba.
Az első különbség az, hogy a szervercsatlakozó a már létező QTcpSocket objektum alapján jön létre. és a kliens socket adapternek létre kell hoznia egy ilyen objektumot. Ezt a különbséget figyelembe veszik a SocketAdapter osztály konstruktorában.
Ezenkívül az ügyfélcsatlakozónak futtatnia kell a connectToHost módszert, hogy elindítsa a párbeszédet a kiszolgálóval. A szerver nem tehet ilyen lépéseket.
A kliens és a szerver teljes forráskódja ingyenesen letölthető: ügyfél-szerver chat Qt.
A következő cikkben a QThread használatával párhuzamosan gondolkodunk.
Hasznos források listája
Post navigáció
7 gondolkodás a "Munka a hálózattal Qt. Aljzatok. Mintaadapter "
A funkció a mellékletben található.
Ha minden ügyfél bezárul, a kiszolgáló továbbra is működik.
Ie A kiszolgáló csak a feladatkezelőn keresztül leállítható.
Ez nem jellemző. A kiszolgáló nem az ügyfelektől függ, hanem egy másik gépen (valahol az interneten).
Az ügyfelek kilépése a csevegésből nem eredményezheti a kiszolgáló leállítását. Most mindenki elment, de egy perc múlva jön (megpróbál csatlakozni), és mi? - Az Ön által használt szerver elérhetetlen, tk. mielőtt ez mindenki jött ki?
Vladimir, jó délután.
1. Miért nem használja az override metódus bejövő kapcsolódását (int)?
2. Nos, miért használják a #include helyett a QTcpSocket osztályt. - Mint az írás stílusa?
Miért nem használja a felülbírálási módot a bejövő kapcsolat (int)
A szerver oldalon (ahol új kapcsolatok jelennek meg) a QTcpServer :: newConnection () jelet használom:
csatlakoztassa (m_ptcpServer, SIGNAL (newConnection ()), SLOT (on_newConnection ()));
Ez a jel minden új csatlakozáskor keletkezik. A dokumentációból:
Ezt a jelet minden egyes új kapcsolat rendelkezésre bocsátja.
QTcpServer :: incomingConnection egy virtuális függvény, amelyet akkor is neveznek, amikor új kapcsolat jelenik meg. A dokumentáció azt mondja, hogy ez a függvény a QTcpServer-ben kerül megvalósításra, így hozzáadja a socket (kapcsolat) listát, és végrehajtja az emulációt newConnection (). Módosíthatja költségek csak abban az esetben, ha van egy másik viselkedését, de ha csak kell egy jelet, hogy van egy új kapcsolat - mindig használja QTcpServer :: newConnection () jel.
Módosíthatja költségek csak abban az esetben, ha van egy másik viselkedését, de ha csak kell egy jelet, hogy van egy új kapcsolat - mindig használja QTcpServer :: newConnection () jel
És mit jelent egy másik viselkedés. Nos, csak azért jött be a jel, és elkezdtük leírni, hogy mit kell, például számoltunk valamit a kiszolgálón, és átadtuk az ügyfélnek. Mintha az összes tevékenység attól függ, hogy van-e jel, vagy sem. Nos, ez van egy jel, mindent megteszünk.
Mikor használjuk a bejövő kapcsolatot (int) a mi esetünkben? Hát csak egy példa.
2) Alkalmazás
Néha valamit csinálok Arduinóban. Most megrendeltem az ESP-8266 wi-fi modulokat az Arduino számára. Azt is meg akarom rendelni egy kamerát, hogy beilleszkedjen és fogadjon információkat a számítógépen az ESP-8266-ban. Elvileg Arduino-nak nincs szüksége, mert mindent az ESP-8266 (annál inkább könnyítheti az Arduino IDE-t). A wi-fi kommunikációhoz és a fejlesztéshez hasznos. Köszönöm.
Azt is szeretném használni az opencv egy PC-n, hogy valahogy feldolgozza a kapott képet.