2
votes

I'm developing a server that responds multiple connections from a client. But I have a problem where I have not found any solution. I created a class (TcpSocket) for QTcpSocket, which separates the signals and slots for each connection.

But my server is not recognizing the signal of this class, it looks for QTcpSocket, and not by TcpSocket.

I'll post the code, maybe you understand better, because my English is not good.

tcpsocket.h

#ifndef TCPSOCKET_H
#define TCPSOCKET_H

#include <QObject>
#include <QtNetwork>

class TcpSocket: public QTcpSocket
{
    Q_OBJECT
    QTcpSocket *Socket;
public:
    TcpSocket (QTcpSocket *);
    virtual ~TcpSocket();

public slots:
    void slotReadyRead();
    void slotConnected();
    void slotDisconnected();

signals:
    void dataReady (TcpSocket *sckt);
    void newConnection(TcpSocket *sckt);
    void lostConnection(TcpSocket *sckt);
};


#endif // TCPSOCKET_H

tcpsocket.cpp

#include "tcpsocket.h"

TcpSocket::TcpSocket(QTcpSocket * socket)
    : Socket (socket)
{
    connect(Socket, SIGNAL(readyRead()), this, SLOT (slotReadyRead()));
    connect(Socket, SIGNAL(connected()), this, SLOT(slotConnected()));
    connect(Socket, SIGNAL(disconnected()), this, SLOT(slotDisconnected()));
}

TcpSocket::~TcpSocket()
{

}

void TcpSocket::slotReadyRead()
{
    emit dataReady(this);
}

void TcpSocket::slotConnected()
{
    emit newConnection(this);
}

void TcpSocket::slotDisconnected()
{
    emit lostConnection(this);
}

server.h

#ifndef SERVER_H
#define SERVER_H

#include <QMainWindow>
#include <QTcpServer>
#include <QTcpSocket>
#include "custom/player.h"
#include "events.h"
#include "socketmanager.h"
#include "tcpsocket.h"

#include <QMessageBox>

namespace Ui {
class Server;
}

class Server : public QMainWindow
{
    Q_OBJECT


public:
    explicit Server(QWidget *parent = 0);
    int max_connections;
    ~Server();

private slots:
    ...
    void client_Disconnected(TcpSocket *socket);
    void client_SendedBytes(qint64 bytes);
    void client_GetBytes(TcpSocket* socket);
    ...

private:
    Ui::Server *ui;
    QTcpServer *server;
    QList<TcpSocket *> client;
    ...

};

#endif // SERVER_H

server.cpp

int j; // connection count
void Server::server_Connected()
{
    client.insert(j, (TcpSocket*)server->nextPendingConnection());
    TcpSocket *sckt = client[j];
    // error:
    connect(sckt, SIGNAL(newConnection(TcpSocket*)), this, SLOT(client_GetBytes(TcpSocket*)));
    connect(sckt, SIGNAL(lostConnection(TcpSocket*)), this, SLOT(client_Disconnected(TcpSocket*)));

    QByteArray block;
    QTextStream out(&block, QIODevice::WriteOnly);
    out << "accepted";

    ui->log->append(QString("Host connected: %1, index %2").arg(sckt->localAddress().toString()).arg(j));

    std::string stdString = "accepted";
    QByteArray byteArray(stdString.c_str(), stdString.length());
    qint64 len = sckt->write(byteArray);
    if(len != byteArray.size())
        ui->log->append("Error!");
    sckt->flush();

    j++;
}

void Server::client_Disconnected(TcpSocket *socket)
{
...
}

void Server::client_GetBytes(TcpSocket *socket)
{
...
}

The error:

QObject::connect: No such signal QTcpSocket::newConnection(TcpSocket*) in ..\SOLEditorServer\server.cpp:45 QObject::connect: (receiver name: 'Server')

QObject::connect: No such signal QTcpSocket::lostConnection(TcpSocket*) in ..\SOLEditorServer\server.cpp:46 QObject::connect: (receiver name: 'Server')

also full code (server)

#include "server.h"
#include "ui_server.h"

#include <QHostAddress>

Server::Server(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::Server)
{
    max_connections = 20;
    SM = new SocketManager();
    ui->setupUi(this);
    server = new QTcpServer(this);
    connect(server, SIGNAL(acceptError(QAbstractSocket::SocketError)), this, SLOT(server_Error()));
    connect(server, SIGNAL(newConnection()), this, SLOT(server_Connected()));

    event = new Events(ui->log);
    setWindowFlags(Qt::WindowCloseButtonHint);
}

Server::~Server()
{
    delete ui;
}

void Server::on_pushButton_clicked()
{
    QHostAddress host;
    host.setAddress(ui->txt_ip->text());

    server->listen(host, ui->txt_port->value());
    ui->log->append("Connected!");
}

void Server::server_Error()
{
    ui->log->append(server->errorString());
}

int j;
void Server::server_Connected()
{
    client.insert(j, (TcpSocket*)server->nextPendingConnection());
    TcpSocket *sckt = client[j];
    connect(sckt, SIGNAL(newConnection(TcpSocket*)), this, SLOT(client_GetBytes(TcpSocket*)));
    connect(sckt, SIGNAL(lostConnection(TcpSocket*)), this, SLOT(client_Disconnected(TcpSocket*)));

    QByteArray block;
    QTextStream out(&block, QIODevice::WriteOnly);
    out << "accepted";

    ui->log->append(QString("Host connected: %1, index %2").arg(sckt->localAddress().toString()).arg(j));

    std::string stdString = "accepted";
    QByteArray byteArray(stdString.c_str(), stdString.length());
    qint64 len = sckt->write(byteArray);
    if(len != byteArray.size())
        ui->log->append("Error!");
    sckt->flush();

    j++;
}

void Server::client_Disconnected(TcpSocket *socket)
{
    ui->log->append(QString("Desconectado. (%1)").arg(socket->localAddress().toString()));
    client.removeAt(client.indexOf(socket));
}

void Server::client_SendedBytes(qint64 bytes)
{
    QString dataxD = QString::number(bytes);
    ui->log->append(QString("%1 bytes enviados.").arg(dataxD));
}

void Server::client_GetBytes(TcpSocket *socket)
{
    QByteArray buffer;
    buffer.resize(socket->bytesAvailable());
    socket->read(buffer.data(), buffer.size());
    QString data(buffer);

    if(data.startsWith("REGISTER "))
    {
        QString received = data.split("REGISTER ")[1];
        ui->log->append(received);
        QString user = received.split(":")[0];
        QString key = received.split(":")[1];
        playerList.append(user);
        playerKey.append(key);
        event->eventNewPlayer(user);
        SM->sendPacketToAll(client, QString("GREETING %1").arg(user));
    } else if(data.startsWith("CHAT("))
    {
        QString UserData = data.split("CHAT(")[1].split(")")[0];
        if(!checkUser(UserData))
        {
            ui->log->append("Username without a valid hash!");
            return;
        }
        QString User = getUsernameFromData(UserData);
        QString Message = data.split(QString("CHAT(%1) ").arg(UserData))[1];
        event->eventNewChatmessage(Message, User);
        SM->sendPacketToAll(client, QString("CHAT(%1) %2").arg(User).arg(Message));
    }
}

bool Server::checkUser(QString usernamedata)
{
    if(!usernamedata.contains(":"))
        return false;

    QString username = usernamedata.split(":")[0];
    QString key = usernamedata.split(":")[1];

    if(!playerList.contains(username) || !playerKey.contains(key))
        return false;

    int playerIndex = playerList.indexOf(username);
    QString hashFromList = playerKey[playerIndex];

    if(hashFromList != key)
        return false;

    return true;
}

bool Server::checkUser2(QString username, QString key)
{
    if(!playerList.contains(username) || !playerKey.contains(key))
        return false;

    int playerIndex = playerList.indexOf(username);
    QString hashFromList = playerKey[playerIndex];

    if(hashFromList != key)
        return false;

    return true;
}

QString Server::getUsernameFromData(QString usernamedata)
{
    if(!usernamedata.contains(":"))
        return "Unknow";

    QString username = usernamedata.split(":")[0];
    return username;
}

QString Server::getUserkeyFromData(QString usernamedata)
{
    if(!usernamedata.contains(":"))
        return "Unknow";

    QString key = usernamedata.split(":")[1];
    return key;
}

void Server::on_pushButton_2_clicked()
{
    /*std::string stdString = "BANNED";
    QByteArray byteArray(stdString.c_str(), stdString.length());
    clientConnection->write(byteArray);*/
}

full server.h

#ifndef SERVER_H
#define SERVER_H

#include <QMainWindow>
#include <QTcpServer>
#include <QTcpSocket>
#include "custom/player.h"
#include "events.h"
#include "socketmanager.h"
#include "tcpsocket.h"

#include <QMessageBox>

namespace Ui {
class Server;
}

class Server : public QMainWindow
{
    Q_OBJECT


public:
    explicit Server(QWidget *parent = 0);
    int max_connections;
    ~Server();

private slots:
    void on_pushButton_clicked();
    void server_Error();
    void server_Connected();
    void client_Disconnected(TcpSocket *socket);
    void client_SendedBytes(qint64 bytes);
    void client_GetBytes(TcpSocket* socket);
    void on_pushButton_2_clicked();
    bool checkUser(QString usernamedata);
    bool checkUser2(QString username, QString key);
    QString getUsernameFromData(QString usernamedata);
    QString getUserkeyFromData(QString usernamedata);

private:
    Ui::Server *ui;
    QTcpServer *server;
    QList<TcpSocket *> client;
    QStringList playerList;
    QStringList playerKey;
    Events *event;
    SocketManager *SM;

};

#endif // SERVER_H
1
I cannot see any error here. Maybe share full code so we can investigate it more carefullyMichał Walenciak
Done, thx for your reply. =DNiunzin
Hi ! I suppose clean/qmake/make again solve nothing ? One thing strange in your error is that at line 45/46, your object type is TcpSocket* and in your error it says QTcpSocket::signalName(..). As if no such signal was found in TcpSocket header or as if sckt (l.45/46) was implicitely casted.Martin
Hey, thanks for your reply! I fixed it! - (i'll post the solution)Niunzin
-1 since it is a wall of text, and you're not describing anywhere what is it that you're trying to do.Kuba hasn't forgotten Monica

1 Answers

0
votes

Fixed!

Modifications:

class TcpSocket: public QTcpSocket // old
class TcpSocket: public QObject // new

// old
void dataReady (TcpSocket *sckt);
void newConnection(TcpSocket *sckt);
void lostConnection(TcpSocket *sckt);

// new
void dataReady(QTcpSocket *sckt);
void newConnection(QTcpSocket *sckt);
void lostConnection(QTcpSocket *sckt);

// old
TcpSocket::TcpSocket(QTcpSocket * socket)
    : Socket (socket)
{
    connect(Socket, SIGNAL(readyRead()), this, SLOT (slotReadyRead()));
    connect(Socket, SIGNAL(connected()), this, SLOT(slotConnected()));
    connect(Socket, SIGNAL(disconnected()), this, SLOT(slotDisconnected()));
}

// new
TcpSocket::TcpSocket (QTcpSocket * socket)
    : Socket (socket)
{
    this->sock = socket;
    connect(socket, SIGNAL(readyRead()), this, SLOT (slotReadyRead()));
    connect(socket, SIGNAL(connected()), this, SLOT(slotConnected()));
    connect(socket, SIGNAL(disconnected()), this, SLOT(slotDisconnected()));
}

// old
void TcpSocket::slotReadyRead()
{
    emit dataReady(this);
}

void TcpSocket::slotConnected()
{
    emit newConnection(this);
}

void TcpSocket::slotDisconnected()
{
    emit lostConnection(this);
}

// new
void TcpSocket::slotReadyRead()
{
    emit dataReady(this->sock);
}

void TcpSocket::slotConnected()
{
    emit newConnection(this->sock);
}

void TcpSocket::slotDisconnected()
{
    emit lostConnection(this->sock);
}

// old
public:
    TcpSocket (QTcpSocket *);
    virtual ~TcpSocket();

// new
public:
    TcpSocket (QTcpSocket *);
    QTcpSocket *sock;

Done, now just use connect() function, like this:

QTcpSocket *socket = (your QTcpSocket);
TcpSocket *tcpSocket = new TcpSocket(socket);
connect(tcpSocket, SIGNAL(dataReady(QTcpSocket*)), this, SLOT(your_slot(QTcpSocket*)));

You really helped me, and sorry. Good luck, if anyone has the same problem that I had (not solved), please contact me!