如何在Qt 5.2中传递QTcpSocket到QRunnable
How to pass a QTcpSocket to a QRunnable in Qt 5.2
我试图通过使用QRunnable和QThreadPool而不是每个连接1个线程,以可扩展的方式使用Qt 5.2编写tcp服务器。
我遇到的问题是,在QRunnable::run中创建的套接字在我创建它并设置它的套接字描述符时具有连接状态,但是调用readAll()响应readyRead信号产生空缓冲区,即使我知道我发送了一些数据。
我尝试将套接字从主线程传递到QRunnable的两种方式是:
1)从QTcpServer::nextPendingConnection获取QTcpSocket,并将socket描述符传递给QRunnable。
2)覆盖QTcpServer::incomingConnection并从那里获得套接字描述符并将其传递给QRunnable。
两者都给出相同的结果,接收到套接字readyread信号,但readAll返回空缓冲区。
感谢RobbieE纠正了我的误解。下面是一个如何使用QRunnables和QThreadpool编写Tcp Server的工作示例。我是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.rn";
QThread::sleep(5);
qDebug() << "...rn";
}
//qDebug() << "OnReadReady";
}
相关文章:
- QTcpSocket在不阻塞GUI的情况下重新连接到服务器
- 如何使用 QDatastream 通过 QTcpSocket 发送 QSqlQueryModel?
- QTcpSocket emulate netcat 'conversation'
- QTcpSocket 在 RemoteHostClosedError 后重新连接到服务器时无法传输数据
- Qt信号和插槽如果从QRunnable或其他线程调用,则不起作用
- QTcpServer/QTcpSocket:使用 QDataStream 与直接发送 UTF-8 数据
- QTcpSocket 到 QTcpSocket 在同一对象中
- 当发生套接字错误时,作为QWebSocket基础的QTcpSocket(或QSslSocket)是否会自行销毁
- 错误: C2065: "QTcpSocket" : 未声明的标识符
- QTcpSocket:消息不是从另一个线程发送的
- QTcpSocket 发送的数据比想要的多 - Qt/C++
- 如何将请求的客户端连接的 IP 与 QTcpSocket 类中识别的 IP 之一进行比较?
- 如何使用QTcpSocket读取超过8192字节?
- Python 3 套接字和 QTcpsocket (c++) 之间的通信失败
- QTCPSocket(Qt-C++)中的音频文件逐字节传输
- 如何将用户输入从控制台传递到不同线程中的对象 -> QTcpsocket
- QTcpSocket and TCP padding
- QTcpSocket 或 QSslSocket 是否会自动创建用于读取/写入的线程?
- QTcpSocket -退出QRunnable时指定的句柄无效
- 如何在Qt 5.2中传递QTcpSocket到QRunnable