首页 文章

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

提问于
浏览
2

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

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

我会发布代码,也许你会更好理解,因为我的英语不好 .

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:没有这样的信号QTcpSocket :: newConnection(TcpSocket *)在.. \ SOLEditorServer \ server.cpp:45 QObject :: connect :(接收者名称:'Server')QObject :: connect:没有这样的信号QTcpSocket :: .. :: SOLEditorServer \ server.cpp中的lostConnection(TcpSocket *):46 QObject :: connect :(接收者名称:'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);*/
}

完整的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 回答

  • 0

    固定!

    修改:

    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*)));
    

    你真的帮了我,对不起 . 祝你好运,如果有人遇到同样的问题(没解决),请联系我!

相关问题