QTcpsocket 写服务器程序时,需要定时向客户端发送监控数据,同时需要响应客户端请求。
问题是: QTcpSocket 只能在同一个线程中使用,定时器会在主线程中运行
解决方案:在定时器中发送信号给封装的客户端数据处理socket,并在线程中将该信号与socket中的操作相连接。
//clientsocket.h
#ifndef CLIENTSOCKET_H
#define CLIENTSOCKET_H
#include <QTcpSocket>
#include <QTimer>
class ClientSocket : public QTcpSocket
{
Q_OBJECT
public:
ClientSocket(QObject *parent);
~ClientSocket();
signals:
void sigReadData(const QString &data);
public slots:
void slotTimeOut();
void slotReadyRead();
void slotWriteData(const QString& data);
private:
QTimer* _timer;
};
#endif // CLIENTSOCKET_H
// clientSocket.cpp
#include "clientsocket.h"
#include <QDebug>
ClientSocket::ClientSocket(QObject *parent)
: QTcpSocket(parent)
{
connect(this, &QAbstractSocket::readyRead, this, &ClientSocket::slotReadyRead);
//_timer = new QTimer(this);
//connect(_timer, &QTimer::timeout, this, &ClientSocket::slotTimeOut);
//_timer->start(2000);
}
ClientSocket::~ClientSocket()
{
}
void ClientSocket::slotReadyRead()
{
QString recv = readAll();
emit sigReadData(recv);
}
void ClientSocket::slotTimeOut()
{
write(QByteArray(this->objectName().toStdString().c_str()));
}
void ClientSocket::slotWriteData(const QString& data)
{
write(data.toStdString().c_str());
flush();
}
//serverListener.h
#ifndef SERVERLISTENER_H
#define SERVERLISTENER_H
#include <QTcpServer>
#include <QTimer>
#include "clientsocket.h"
class ServerListener : public QTcpServer
{
Q_OBJECT
public:
ServerListener(QObject *parent);
~ServerListener();
virtual void incomingConnection(qintptr handle);
signals:
void sigWriteData(const QString& data);
public slots:
void slotReadData(const QString& data);
void slotSendMMIDataTimeOut();
private:
ClientSocket *_clientSock;
QTimer* _timer;
};
#endif // SERVERLISTENER_H
//serverListener.cpp
#include "serverlistener.h"
#include <QThread>
#include <QDebug>
ServerListener::ServerListener(QObject *parent)
: QTcpServer(parent)
{
}
ServerListener::~ServerListener()
{
}
void ServerListener::incomingConnection(qintptr handle)
{
_clientSock = new ClientSocket(0x00);
_clientSock->setSocketDescriptor(handle);
QThread *thread = new QThread(this);
_clientSock->moveToThread(thread);
_timer = new QTimer(this);
connect(_clientSock, &ClientSocket::sigReadData, this, &ServerListener::slotReadData);
connect(this, &ServerListener::sigWriteData, _clientSock, &ClientSocket::slotWriteData);
connect(_timer, &QTimer::timeout, this, &ServerListener::slotSendMMIDataTimeOut);
_timer->start(2000);
thread->start();
}
void ServerListener::slotReadData(const QString& data)
{
qDebug() << data;
}
void ServerListener::slotSendMMIDataTimeOut()
{
QString data = QString::fromLocal8Bit("Ryan data");
//_clientSock->write(data.toStdString().c_str()); //如果在这里的话,就会报错
emit ServerListener::sigWriteData(data);
}
//main.cpp
#include "serverlistener.h"
#include <QtCore/QCoreApplication>
#include <QHostAddress>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
ServerListener listener(0x00);
listener.listen(QHostAddress::Any, 6000);
return a.exec();
}