首页 文章

如何在Qt 5.2中将QTcpSocket传递给QRunnable

提问于
浏览
0

我试图通过使用QRunnable和QThreadPool而不是每个连接1个线程,以可扩展的方式使用Qt 5.2编写tcp服务器 .

我遇到的问题是在QRunnable :: run中创建的套接字在创建它时设置了连接状态并设置了它的套接字描述符,但调用readAll()以响应readyRead信号会产生一个空缓冲区,即使我知道我发了一些数据 .

我尝试将套接字从主线程传递到QRunnable的两种方法是:

1)从QTcpServer :: nextPendingConnection获取QTcpSocket并将套接字描述符传递给QRunnable .

2)覆盖QTcpServer :: incomingConnection并从那里获取套接字描述符并将其传递给QRunnable .

两者都给出相同的结果,接收套接字readyread信号但readAll返回一个空缓冲区 .

任何帮助将非常感谢 .

1 回答

  • 2

    感谢RobbieE纠正我的误解 . 以下是如何编写使用QRunnables和QThreadpool的Tcp服务器的工作示例 . 我是Qt的新手所以欢迎任何批评/改进/讨论 . 代码不是 生产环境 质量,只是编写可伸缩tcp服务器的简单示例 .

    #include <QCoreApplication>
    #include "server.h"
    
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
        Server server;
        if(server.Start())
        {
            qDebug() << "Server started"   ;
        }
        else
        {
            qDebug() << "Server Failed to start"   ;
        }
    
        return a.exec();
    }
    

    server.h

    #ifndef SERVER_H
    #define SERVER_H
    
    #include <QObject>
    #include <QTcpServer>
    #include <QTcpSocket>
    
    
    class Server : public QObject
    {
        Q_OBJECT
    public:
        explicit Server(QObject *parent = 0);
    
        bool Start();
    
    signals:
    
    public slots:
        void onNewConnection();
    
    
    private:
        QTcpServer* m_pServer;
    
    };
    
    #endif // SERVER_H
    

    server.cpp

    #include "server.h"
    #include "myrunnable.h"
    #include <QThreadPool>
    
    Server::Server(QObject *parent) :
        QObject(parent)
    {
        m_pServer = new QTcpServer(this);
    }
    
    
    bool Server::Start()
    {
          bool bOK = true;
          if(m_pServer->listen(QHostAddress::Any,1971))
          {
              connect(m_pServer,SIGNAL(newConnection()),this,SLOT(onNewConnection()));
          }
          else
          {
              qDebug() << "Failed to start listening";
              bOK = false;
          }
          return bOK;
    }
    
    void Server::onNewConnection()
    {
        qDebug() << "onNewConnection";
        QTcpSocket* pSocket = m_pServer->nextPendingConnection();
        qintptr descriptor =  pSocket->socketDescriptor();
        MyRunnable* pRunnable = new MyRunnable();
        pRunnable->setAutoDelete(true);
        pRunnable->setDescriptor(descriptor);
        QThreadPool::globalInstance()->start(pRunnable);
    
    }
    

    myrunnable.h

    #ifndef MYRUNNABLE_H
    #define MYRUNNABLE_H
    
    #include <QObject>
    #include <QTcpSocket>
    #include <QRunnable>
    #include <QEventLoop>
    
    class MyRunnable : public QObject, public QRunnable
    {
        Q_OBJECT
    public:
        explicit MyRunnable(QObject *parent = 0);
        ~MyRunnable();
        void run();
        void setDescriptor(qintptr descriptor);
    
    signals:
    
    public slots:
        void onConnected();
        void onDisconnect();
        void onReadyRead();
    
    
    
    private:
        qintptr m_socketDecriptor;
        QTcpSocket* m_pSocket;
        QEventLoop* m_pEventLoop;
    };
    
    #endif // MYRUNNABLE_H
    

    myrunnable.cpp

    #include "myrunnable.h"
    #include <QEventLoop>
    #include <QThread>
    
    MyRunnable::MyRunnable(QObject *parent) :
        QObject(parent),m_pSocket(0)
    {
    
    }
    
    MyRunnable::~MyRunnable()
    {
        qDebug() << "MyRunnable destructor called";
    }
    
    void MyRunnable::run()
    {
        m_pEventLoop = new QEventLoop();
        m_pSocket = new QTcpSocket();
        if(m_pSocket->setSocketDescriptor(m_socketDecriptor))
        {
            connect(m_pSocket,SIGNAL(connected()),this,SLOT(onConnected()),Qt::QueuedConnection);
            connect(m_pSocket,SIGNAL(disconnected()),this,SLOT(onDisconnect()),Qt::QueuedConnection);
            connect(m_pSocket,SIGNAL(readyRead()),this,SLOT(onReadyRead()),Qt::QueuedConnection);
        }
    
        m_pEventLoop->exec();
        delete m_pSocket;
        delete m_pEventLoop;
    }
    
    void MyRunnable::setDescriptor(qintptr descriptor)
    {
        m_socketDecriptor = descriptor;
    }
    
    void MyRunnable::onConnected()
    {
        qDebug() << "Connected";
    }
    
    void MyRunnable::onDisconnect()
    {
        qDebug() << "Disconnected";
        //m_pEventLoop->disconnect();
        m_pEventLoop->exit();
    
    }
    
    void MyRunnable::onReadyRead()
    {
        qDebug() << m_pSocket->readAll();
        for(int i=0;i<4;i++)
        {
            qDebug() << "Sleeping for 5 seconds to simulate work being done.\r\n";
            QThread::sleep(5);
            qDebug() << "...\r\n";
        }
    
        //qDebug() << "OnReadReady";
    
    }
    

相关问题