mykvbps 发表于 2024-4-6 14:53

请教:QTcpsocket 多线程字符成员变量访问为空问题

学习 QTcpsocket 遇到个奇怪的问题,简略代码如下,出问题的位置就在注释处:

1. QTcpsocket 客户端对象:class TcpSocket : public QTcpSocket
{
    Q_OBJECT
public:
    TcpSocket(int socketdesc, QTcpSocket* parent = NULL);
    ~TcpSocket();

private slots:
    void ReadAndParseData();
    void SocketErr(QAbstractSocket::SocketError socketError);
    void finished();

private:
    TcpSocket* socket;

QString m_sUser = "";
    QString sIp="";
    quint16 sPort=0;

    void SendErrorInfo(QString info, QString lastError);
    void SendOK();

signals:
    void sigSocketToTcpServer(QString);
void sigSocketPushInfoToTcpServer(QJsonObject);
};

TcpSocket::TcpSocket(int sock, QTcpSocket* parent) : QTcpSocket(parent)
{
    this->setSocketDescriptor(sock);
    connect(this, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(SocketErr(QAbstractSocket::SocketError)));
}

TcpSocket::~TcpSocket()
{
    qDebug() << "TcpSocket Exited.";
}

void TcpSocket::ReadAndParseData()
{
    socket = (TcpSocket*)sender();


while (socket->bytesAvailable() > 0)
      residueData.append(socket->readAll());

    QJsonParseError* error = new QJsonParseError;
    QJsonDocument jDoc = QJsonDocument::fromJson(residueData, error);
    QJsonObject recvObj = jDoc.object();

sIp = socket->peerAddress().toString();
sPort = socket->peerPort();
m_sUser = recvObj.value("User").toString();// 此处保存来访用户的用户名
    //......
}

2. QTcpServer 对象,客户端接入多线程管理
class TcpServer : public QTcpServer
{
    Q_OBJECT
public:
    TcpServer(const std::string& ip, int port, QTcpServer* parent = NULL);
    ~TcpServer();

protected:
    void incomingConnection(qintptr socketDescriptor);

private slots:
    void SocketDisconn();
    void pushUpdate(QJsonObject jsonPushMsg);
    void receiveIpUser(QString sIp, QString sUser);

private:
    QList<TcpSocket*> m_socketList;

signals:
    void sigTcpServerTohyTableServer(QString);
};

TcpServer::TcpServer(const std::string& ip, int port, QTcpServer* parent) : QTcpServer(parent) {
    bool bsucc;
    if (ip.empty())
      bsucc = this->listen(QHostAddress::AnyIPv4, port);
    else
      bsucc = this->listen(QHostAddress(ip.c_str()), port);
   
    if (bsucc) {
      emit sigTcpServerTohyTableServer(QStringLiteral("服务器启动成功……"));
      qDebug() << QStringLiteral("服务器启动成功……");
    }
    else{
      emit sigTcpServerTohyTableServer(QStringLiteral("服务器启动失败!"));
      qDebug() << QStringLiteral("服务器启动失败!");
    }
}

TcpServer::~TcpServer() {
    QList<TcpSocket*>::iterator it = m_socketList.begin();
    for (; it != m_socketList.end(); ) {
      TcpSocket* sock = *it;
      it = m_socketList.erase(it);
      sock->deleteLater();
      sock = NULL;
    }
    m_socketList.clear();
    this->close();
}


void TcpServer::incomingConnection(qintptr socketDescriptor) {
    TcpSocket* socket = new TcpSocket(socketDescriptor);
    m_socketList.append(socket);// 客户端池

    connect(socket, SIGNAL(readyRead()), socket, SLOT(ReadAndParseData()));
    connect(socket, SIGNAL(sigSocketToTcpServer(QString)), this, SIGNAL(sigTcpServerTohyTableServer(QString)));
    connect(socket, SIGNAL(sigSocketPushInfoToTcpServer(QJsonObject)), this, SLOT(pushUpdate(QJsonObject)));

    QThread* thread = new QThread();
    connect(thread, SIGNAL(finished()), socket, SLOT(finished()));
    connect(socket, SIGNAL(disconnected()), thread, SLOT(quit()));

    socket->moveToThread(thread);
    thread->start();
    emit newConnection();
}

void TcpServer::pushUpdate(QJsonObject jsonPushMsg)
{
    for (int i = 0; i < m_socketList.size(); ++i)// 在客户端池中轮询 TcpSocket 对象
    {
      QString sockUser = m_socketList.at(i)->m_sUser;   // 此处读取 TcpSocket 对象的 QString 成员变量总是为空
      //......
    }
}


业余玩家,还请各位大佬不吝赐教:loveliness:

mykvbps 发表于 2024-4-6 14:56

代码中示例是 QString,试过 char*, QByteArray,都有这个问题{:1_925:}

mykvbps 发表于 2024-4-8 15:34

测试发现,int 类似也有问题,应该是多线程处理的关系,具体原因不知 {:1_908:}
页: [1]
查看完整版本: 请教:QTcpsocket 多线程字符成员变量访问为空问题