QTcpSocket和多个客户端(信号问题)

QTcpSocket and multiples clients (signal issue)

本文关键字:信号 问题 客户端 QTcpSocket      更新时间:2023-10-16

我正在开发一个响应来自客户端的多个连接的服务器。但我有一个问题,我没有找到任何解决方案。我为QTcpSocket创建了一个类(TcpSocket),它为每个连接分离信号和插槽。

但是我的服务器没有识别出这个类的信号,它查找的是QTcpSocket,而不是TcpSocket。

我会把代码贴出来,也许你能更好地理解,因为我的英语不好。

tcpocket.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

tcpocket.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);
}

服务器.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

服务器.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)
{
...
}

错误:

QObject::connect:中没有这样的信号QTcpSocket::newConnection(TcpSocket*)。。\SOLEditorServer\server.cpp:45QObject::connect:(接收方名称:"服务器")

QObject::connect:中没有这样的信号QTcpSocket::lostConnection(TcpSocket*)。。\SOLEditorServer\server.cpp:46QObject::connect:(接收方名称:"服务器")

还有完整代码(服务器)

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

完整服务器.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

已修复!

修改:

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;

完成,现在只需使用connect()函数,如下所示:

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

你真的帮了我,很抱歉。祝你好运,如果有人和我有同样的问题(没有解决),请联系我!