...
Seuraavana esimerkki, jossa esitellään käyttäjän (Client) ja serverin (Server) toiminta, sekä pieni pääohjelma jossa käyttäjä yhdistetään serveriin. Ideana on, että pääohjelmassa luodaan Client-olio, joka huolehtii saamansa signaalin lähettämisestä edelleen serverilleserveriin (joka esimerkiksi ylläpitää jonkin laitteen toimintaa) voidaan ottaa yhteys verkosta.
tcp_client.h
Code Block |
---|
#ifndef TCP_CLIENT_H #define TCP_CLIENT_H #include <QxtNetwork/qxtrpcpeer.h> class TCPClient : public QObject { Q_OBJECT public: TCPClient(); ~TCPClient(); private: /// QxtRPCPeer-olio joka huolehtii fyysisesti serverille yhdistämisestä /// ja signaalin lähettämisestä/vastaanottamisesta QxtRPCPeer *client; /// Serverin IP QString hostIp; /// Serverin portti int hostPort; /// Ollaanko yhteydessä vai ei bool connected; signals: /// Signaalin (viestin) lähettäminen serverille void sendSignal(QVector<QString>); /// Signaali, kun serveriin yhdistäminen onnistuu void connectedToServer(); /// Signaali, kun serveriin yhdistäminen epäonnistuu void serverError(); private slots: /// Slotti, joka yhdistää käyttäjän serveriin void connectToServer(); /// Slotti, joka yhdistää käyttäjän serveriin (annettuun ip-osoitteeseen (QString) /// ja annettuun porttiin (int)) void connectToServer(QString, int); /// Yhteyden katkaiseminen serveriin void disconnectFromServer(); /// Viestin lähetys, aktivoi sendSignal()-signaalin void sendData(QVector<QString>); /// Viestin vastaanotto serveriltä (esim. käyttöliittymän päivittäminen uusilla tiedoilla) void receiveData(QVector<QString>); /// Ilmoitus mikäli yhteyden luominen onnistui (ei pakollinen) void connectionEstablished(); /// Ilmoitus mikäli yhteyden muodostamisessa ilmenee ongelmia (ei pakollinen) void connectionError(); }; #endif // TCP_CLIENT_H |
...
Code Block |
---|
#include "tcp_client.h" TCPClient::TCPClient() { /// QxtRPCPeer-olio joka huolehtii fyysisesti serverin toiminnasta (uusien yhteyksien /// kuuntelusta, signaalien vastaanottamisesta/lähettämisestä jne.)Olion luominen client = new QxtRPCPeer(); /// Oletus IP, johon yhdistetään mikäli käyttäjä ei syötä IP:tä hostIp = "127.0.0.1"; /// Oletusportti johon yhdistetään hostPort = 45123; /// Ollaanko yhteydessä? Oletuksena false connected = false; /// Jotta signaaleihin voidaan yhdistää QVector-tyyppisiä parametreja, on ne määrittettävä seuraavasti qRegisterMetaTypeStreamOperators< QVector<QString> >("QVector<QString>"); /// Liitetään signaalit slotteihin connect(this->client, SIGNAL(connectedToServer()), this, SLOT(connectionEstablished())); connect(this->client, SIGNAL(serverError(QAbstractSocket::SocketError)), this, SLOT(connectionError())); /// attachSignal-funktio kapseloi signaalin muotoon, jossa se voidaan lähettää verkkoyhteyden yli /// Funktion QString-parametri on tunniste, jolla signaali tunnistetaan serverin puolella ja /// pystytään yhdistämään tiettyyn slottiin. client->attachSignal(this, SIGNAL(sendSignal(QVector<QString>)), QString("signalToServer")); /// attachSlot-funktio vastaanottaa serveriltä tullevan kapseloidun signaalin, jonka /// joka välitetään receiveData-slot ottaa vastaanslotille client->attachSlot(QString("signalFromServer"), this, SLOT(receiveData(QVector<QString>))); } TCPClient::~TCPClient() { /// Poistetaan muodostettu olio muistin säästämiseksi delete client; } /// Yhdistetään serveriin oletusarvoilla tai käyttäjän antamilla arvoilla void TCPClient::connectToServer() { /// Connect metodi muodostaa connectedToServer- tai serverError-signaalin client->connect(this->hostIp, this->hostPort); } void TCPClient::connectToServer(QString ip, int port) { client->connect(ip, port); } void TCPClient::disconnectFromServer() { client->disconnectServer(); connected = false; } void TCPClient::sendData(QVector<QString> data) { emit sendSignal(data); } void TCPClient::receiveData(QVector<QString>) { qDebug() << "message from server"; } void TCPClient::connectionEstablished() { connected = true; qDebug() << "connected"; } void TCPClient::connectionError() { qDebug() << "connection error"; } |
...
Code Block |
---|
#ifndef TCP_SERVER_H #define TCP_SERVER_H #include <QxtNetwork/qxtrpcpeer.h> class TCPServer : public QObject { Q_OBJECT public: TCPServer(); ~TCPServer(); /// Serverin käynnistäminen oletusarvoilla void startServer(); /// Serverin käynnistäminen käyttäjän antamilla parametreilla void startServer(QHostAddress, int); /// Serverin pysäyttäminen void stopServer(); private: /// QxtRPCPeer-olio joka huolehtii fyysisesti serverin toiminnasta (uusien yhteyksien /// kuuntelusta, signaalien vastaanottamisesta/lähettämisestä jne.) QxtRPCPeer *server; /// Serverin ip-osoite QHostAddress serverIp; /// Serverin käyttämä portti int serverPort; /// Lista pitämään kirjaa aktiivisista yhteyksistä (käyttäjistä/clienteista) QList<quint64> clients; signals: /// Signaali, joka muodostetaan käyttäjän yhdistyessä serverille void clientConnected(quint64); /// Signaali käyttäjän katkaistaessa yhteyden void clientDisconnected(quint64); /// Signaali, joka lähetetään takaisin käyttäjälle (esim. käyttöliittymän päivittäminen) void sendSignal(QVector<QString>); private slots: /// Slotti jossa lisätään käyttäjä yhteyslistaan (clients) jne. void newClient(quint64); /// Slotti, jossa poistetaan käyttäjä yhteyslistasta tämän katkaistaessa yhteyden void deleteClient(quint64); /// Slotti joka huolehtii käyttäjältä tulevan signaalin käsittelystä void receiveSignal(quint64, QVector<QString>); }; #endif // TCP_SERVER_H |
...
Code Block |
---|
#include "tcp_server.h" TCPServer::TCPServer() { server = new QxtRPCPeer(); serverIp = QHostAddress::Any; serverPort = 45123; /// Signaalien ja slottien yhdistäminen Client-puolen tapaan qRegisterMetaTypeStreamOperators< QVector<QString> >("QVector<QString>"); /// Käyttäjältä tulevassa signaalissa on lisänä quint64-tyyppinen muuttuja, joka on yhteyden ID server->attachSlot(QString("signalToServer"), this, SLOT(receiveSignal(quint64, QVector<QString>))); server->attachSignal(this, SIGNAL(sendSignal(QVector<QString>)), QString("signalFromServer")); connect(this->server, SIGNAL(clientConnected(quint64)), this, SLOT(newClient(quint64))); connect(this->server, SIGNAL(clientDisconnected(quint64)), this, SLOT(deleteClient(quint64))); } TCPServer::~TCPServer() { delete server; } void TCPServer::startServer() { /// Käynnistetään serveri listen-funktiolla, jolloin se kuuntelee jatkuvasti uusia yhteyksiä /// Huom. Client-puolella ei käytetä listen-funktiota, vaan pelkästään connect-funktiota server->listen(this->serverIp, this->serverPort); qDebug() << "server up"; } void TCPServer::startServer(QHostAddress address, int port) { server->listen(address, port); qDebug() << "server up"; } void TCPServer::stopServer() { server->stopListening(); clients.empty(); qDebug() << "server down"; } void TCPServer::newClient(quint64 clientId) { clients.append(clientId); qDebug() << clientId << " connected"; } void TCPServer::deleteClient(quint64 clientId) { int delClient = clients.indexOf(clientId); clients.removeAt(delClient); qDebug() << clientId << " disconnected"; } void TCPServer::receiveSignal(quint64 connectionId, QVector<QString> data) { // Tee jotain data:lle // Lähetetään tietoa serverin tilasta takaisin käyttäjälle // emit sendSignal(vector); } |
...