Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

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()
{
    /// 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
#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);
}

...