Az előző bejegyzésben elindítottuk a kliens programokat ugyanazon a gépen ahol a server fut. De le is kellene állítani őket a gép újraindítása nélkül. Erre való az IPC. Rövid összefoglaló itt található. Multi platformos megoldásként a sharedmemory és a tcp jöhet számításba. A sharedmemory linux alatt "beragad", ha lefagy a program, míg a windows elengedi. Marad a tcp, de ez is trükkös. Felépíthetünk egy klasszikus kliens - szerver kapcsolatot ip címmel, porttal, meg az ehhez szükséges init dolgokkal. Vagy használjuk az erre a célra tökéletesen megfelelő QLocalServer - QLocalSOcket kapcsolatot. Itt nem kell ip cím,port, hanem csakegy név amire a kliens hivatkozni tud. Ez végülis a kapcsolat neve.
Server oldal:
- QLocalServer init (server = new QLocalServer();)
- várható kliensek számának beállítása (server->setMaxPendingConnections()), default 30
- új kliens kapcsolódásnál értesítés fogadása (connect(server, SIGNAL(newConnection()), this, SLOT(ertesito()));). Az ertesito függvény hívódik meg.
- fülelés indítása (server->listen("qt_labor");) Erre a névre fognak a kliensek kapcsolódni.
- newConnection beáll, levesszük a kliens adatait (QLocalSocket *kliens = server->nextPendingConnection();). Ez visszaad egy, a kliensre mutató pointert.
- írunk, olvasunk
- kliens->write("STOP");
- kliens->flush(); <- pufferezés nélkül rögtön kitolja az anyagot
- kliens->waitForReadyRead(2000); <- ennyi ms-t vár a válaszra
- kliens->read(olv, 3);
Kliens oldal:
- QLocalSocket init (kliens = new QLocalSocket();)
- ha jön olvasnivaló, értesítsen (connect(kliens, SIGNAL(readyRead()), this, SLOT(olvaso()));) <- ezt a connectToServer élesíti
- amikor kell, felcsatlakozunk a szerverre (kliens->connectToServer("qt_labor");)
- olvasunk, írunk
- char olv[10];
- kliens->read(olv,10);
- kliens->write("OK");
- kliens->flush();
- kliens->disconnectFromServer();
Hibakezelés:
A socket aktuális állapotát a int : state() függvénnyel tudjuk lekérdezni. Az esetleges hibáról olvasható formában a QString : errorString() ad infót.
Ez eddig nagyon szép, egy kis hibával. Szerver oldalon nem automatikusan fut a kapcsolat kezelése, kliensekre várakozás, hanem egy esemény váltja ki. Pl. egy gombnyomás. És itt jön a nagy kérdés: hogyan lehet megoldani, hogy a szerver oldal addig várakozzon amíg az összes kliens be nem jelentkezik? Mondjuk ciklusban futtatjuk a szerver oldal 5,6 pontját, amíg be nem jelentkezett minden kliens. Ezzel dinamikusan megakasztjuk az egész program futását, hiszen a ciklus ki tudja meddig pörög. Jobb megoldás kell keresnünk. Legközelebb...