QTcpServer::incomingConnection(qintptr) 没有调用

Posted

技术标签:

【中文标题】QTcpServer::incomingConnection(qintptr) 没有调用【英文标题】:QTcpServer::incomingConnection(qintptr) not calling 【发布时间】:2016-08-22 17:14:43 【问题描述】:

我正在尝试使用QTcpSocket 和QTcpServer 制作客户端和服务器。

那么,服务器会发生什么。

    我运行服务器,它开始监听(成功[我自己检查]) 我运行客户端,输入127.0.0.1IP address30000port 客户说连接已建立 服务器不做任何事情,继续等待

我的部分程序:

//server-work.h
#ifndef SERVERWORK_H
#define SERVERWORK_H

#include <QtCore>
#include <QSqlError>
#include <QDebug>
#include <QSqlQuery>
#include <unistd.h>
#include <QtNetwork/QTcpServer>
#include <QtNetwork/QTcpSocket>
#include <QtSql/QSqlDatabase>
#include "lssclient.h"
class LSSClient;

class LTcpServer : public QTcpServer

    Q_OBJECT
public:

    class LTWorkWithClients : public QThread
    
        //Q_OBJECT
    public:
        LTcpServer* server;
        LTWorkWithClients(QObject* parent = 0, LTcpServer *server = 0):
            QThread(parent)
        
            this->server = server;
        

    protected:
        void run() 
            qDebug() << "started";
            server->workWithIncomingConnection();
        
    ;

    QSqlDatabase db; // clients in database

    LTWorkWithClients* t_workWithClients;
    QQueue<quintptr> clientsToBeAttached;
    QList<LSSClient*> clients;

    LResult workWithIncomingConnection  ();

    LResult serverInit          ();
    LResult createDatabase      ();

    static QTextStream& qStdout ();

    void incomingConnection(qintptr socketDescriptor) Q_DECL_OVERRIDE;

protected:

private:

;

#endif // SERVERWORK_H

我知道这个嵌套线程类是非常错误的方式来做这件事,但我没有太多时间来正确地做这件事

// server-work.cpp [PART]
LResult LTcpServer::serverInit()

    checkError;
    db = QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName("serverDB");

    if (!db.open()) 
        qDebug() << "Error opening database...";
        qDebug() << db.lastError().text();
        return LVError;
     else 
        qDebug() << "Database successfully opened";
    
    if(!this->listen(QHostAddress::Any, 30000))
        qDebug() << "Error starting listening...";
        return LVError;
     else 
        qDebug() << "Start listening successfully";
    
    t_workWithClients = new LTWorkWithClients(this, this);
    t_workWithClients->start();
    return LVSuccess;


void LTcpServer::incomingConnection(qintptr socketDescriptor)

    qDebug() << Q_FUNC_INFO << " new connection";
    clientsToBeAttached.enqueue(socketDescriptor);
    qDebug() << "here1";


LResult LTcpServer::workWithIncomingConnection()

    bool toExit = false;
    while (!toExit) 
        checkError;
        qDebug() << "1";
        if (clientsToBeAttached.length() != 0) 
            quintptr eachClientDescriptor = clientsToBeAttached.dequeue();
            qDebug() << "2";
            LSSClient* client = new LSSClient(this);
            client->server = this;
            client->socket->setSocketDescriptor(eachClientDescriptor);
            qDebug() << "3";
            client->registered = false;
            client->server = this;
            qDebug() << client->socket->localAddress();
            connect(client->socket, SIGNAL(readyRead()), client, SLOT(onSokReadyRead()));
            connect(client->socket, SIGNAL(connected()), client, SLOT(onSokConnected()));
            connect(client->socket, SIGNAL(disconnected()), client, SLOT(onSokDisconnected()));
            connect(client->socket, SIGNAL(error(QAbstractSocket::SocketError)),client, SLOT(onSokDisplayError(QAbstractSocket::SocketError)));
            clients.append(client);
        
        usleep(1000000);
    
    return LVSuccess;

所以,服务器每秒只写 1(仅此而已),但客户端说它已连接到服务器。

【问题讨论】:

我想说,首先你应该让它在没有任何额外线程的情况下工作。只有当它在主线程中工作时,你应该将对象移动到QThread(你不需要从QThread派生)。 我可以看到serverInit 是您创建线程的位置,您没有在此处调用它。 如果你想有一个单独的线程来处理你的连接,你真的做错了。以下是您当前设计的一些问题:1) clientsToBeAttachedserver 在两个线程中使用,没有任何同步机制。 2)您每 1 秒轮询一次以检查队列中是否有任何新连接的客户端。这是生产者/消费者问题的典型示例。看看这是如何在 Qt here 和 here 中完成的。 但您最好阅读Qt Threaded Fortune Example 以避免线程问题。另外,您确定要使用多线程吗?为什么不在你的 GUI 线程中运行所有东西呢? 问题是incomingConnecion 没有触发(没有qdebug 消息)。在我理解为什么incomingConnecion 不触发之前,我看不到线程战斗的感觉......另外,我尝试使用newConnection(没有传递给其他线程),它也没有触发......感谢eз链接,但我已经看过财富例子@Mike 【参考方案1】:

这种结构可能会有所帮助...

在您的 ltcpserver.h 文件中:

class LTcpServer : public QTcpServer

    Q_OBJECT
public:
    explicit LTcpServer(QObject * parent = 0);
    void incomingConnection(qintptr socketDescriptor) Q_DECL_OVERRIDE;
private:
    QThread *myThread;
;

在您的 ltcpserver.cpp 中:

LTcpServer::LTcpServer(QObject * parent) : QTcpServer(parent)

    if(this->listen(QHostAddress::Any,30000))
    
        qDebug() << "server started...";
    
    else
    
        qDebug() << "server could not be started...";
    
    myThread = new QThread();
    myThread->start();


void LTcpServer::incomingConnection(qintptr socketDescriptor)

    LSSClient * yourClient = new LSSClient(socketDescriptor);
    yourClient->moveToThread(myThread);
    clients->append(yourClient);

在你的 lssclient.h 中

class LSSClient: public QObject

    Q_OBJECT
public:
    explicit LSSClient(qintptr socketDescriptor,QObject * parent = 0);
private:
    void setupSocket(qintptr socketDescriptor);
    QTcpSocket * socket;
public slots:
    void readyRead();
    void disconnected();
;

在你的 lssclient.cpp 中

LSSClient::LSSClient(qintptr socketDescriptor,QObject * parent) : QObject(parent)

    setupSocket(qintptr socketDescriptor);


void LSSClient::setupSocket(qintptr socketDescriptor)

    socket = new QTcpSocket(this);
    socket->setSocketDescriptor(sDescriptor);
    connect(socket,SIGNAL(readyRead()),this,SLOT(readyRead()));
    connect(socket,SIGNAL(disconnected()),this,SLOT(disconnected()));


void LSSClient::readyRead()

    // do whatever you want here with incoming data


void LSSClient::disconnected()

    // do what happens to client when disconnected

【讨论】:

你测试了吗?传入的Connecion 签名就像我的一样...... 是的...你使用线程不好...更改已在线程中完成 但这对我有帮助吗?.. 这是incomingConnecion 不触发的真正原因吗? 无论如何,我会试试你的结构.. QThread 是什么意思?什么都不做的线程?还是只是举例? 据我了解,您想在另一个线程中与客户打交道(对吗?)

以上是关于QTcpServer::incomingConnection(qintptr) 没有调用的主要内容,如果未能解决你的问题,请参考以下文章