我正在制作两个应用程序:一个是服务器,一个是客户端。服务器使用QTcpServer和QThread来监听客户端。客户端使用QThread与服务器建立连接。 服务器和客户端成功连接,但问题是它们之间如何进行数据通信。在服务器端,当连接新客户端时,我放置了一行,使用 socket->write("hello") 向客户端发送数据,但客户端没有收到它。 “没有收到”的推测是基于在客户端调用 QDebug 时没有编写任何内容。 另外,我想问如何使客户端线程始终准备好从服务器接收数据,但有时可以在使用 PushButton 时用于将数据发送到服务器。 任何帮助将不胜感激。
客户端 main.cpp(使用小部件)
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "tcpthread.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
TcpThread *tcpThread = new TcpThread(this);
connect(tcpThread, SIGNAL(finished()), tcpThread, SLOT(deleteLater()));
tcpThread->start();
}
客户端tcpthread.h
#ifndef TCPTHREAD_H
#define TCPTHREAD_H
#include <QThread>
#include <QTcpSocket>
class TcpThread : public QThread
{
Q_OBJECT
public:
explicit TcpThread(QObject *parent = 0);
void run();
signals:
void error(QTcpSocket::SocketError socketError);
public slots:
void readyRead();
void disconnected();
private:
void processMessage(QByteArray message);
QTcpSocket *socket;
qintptr socketDescriptor;
QByteArray data;
};
#endif // TCPTHREAD_H
客户端tcpthread.cpp
#include "tcpthread.h"
TcpThread::TcpThread(QObject *parent) :
QThread(parent)
{
}
void TcpThread::run()
{
qDebug() << "Thread started";
socket = new QTcpSocket();
connect(socket, SIGNAL(readyRead()), this, SLOT(readyRead()), Qt::DirectConnection);
connect(socket, SIGNAL(disconnected()), this, SLOT(disconnected()));
socket->connectToHost("127.0.0.1",1234);
exec();
}
void TcpThread::readyRead()
{
data = socket->readAll();
while(!data.contains('\n'))
{
socket->waitForReadyRead();
data += socket->readAll();
}
int bytes = data.indexOf('\n')+1;
QByteArray message = data.left(bytes);
data = data.mid(bytes);
qDebug() << socketDescriptor << " : " << message;
processMessage(message);
}
void TcpThread::disconnected()
{
qDebug() << socketDescriptor << " disconnected";
socket->deleteLater();
exit(0);
}
void TcpThread::processMessage(QByteArray message)
{
qDebug() << message << " processed";
}
服务器端main.cpp
#include "tcpserver.h"
#include <QCoreApplication>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
TcpServer tcpServer;
tcpServer.startServer();
return a.exec();
}
服务器端tcpthread.h
#ifndef TCPTHREAD_H
#define TCPTHREAD_H
#include <QThread>
#include <QTcpSocket>
#include <QDebug>
class TcpThread : public QThread
{
Q_OBJECT
public:
explicit TcpThread(qintptr ID, QObject *parent = 0);
void run();
signals:
void error(QTcpSocket::SocketError socketError);
public slots:
void readyRead();
void disconnected();
private:
void processMessage(QByteArray message);
QTcpSocket *socket;
qintptr socketDescriptor;
QByteArray data;
};
#endif // TCPTHREAD_H
服务器端tcpthread.cpp #include“tcpthread.h”
TcpThread::TcpThread(qintptr ID, QObject *parent) :
QThread(parent)
{
this->socketDescriptor = ID;
}
void TcpThread::run()
{
qDebug() << "Thread started";
socket = new QTcpSocket();
if(!socket->setSocketDescriptor(this->socketDescriptor))
{
emit error(socket->error());
return;
}
connect(socket, SIGNAL(readyRead()), this, SLOT(readyRead()), Qt::DirectConnection);
connect(socket, SIGNAL(disconnected()), this, SLOT(disconnected()));
qDebug() << socketDescriptor << " connected";
socket->write("hello");
exec();
}
void TcpThread::readyRead()
{
data = socket->readAll();
while(!data.contains('\n'))
{
socket->waitForReadyRead();
data += socket->readAll();
}
int bytes = data.indexOf('\n')+1;
QByteArray message = data.left(bytes);
data = data.mid(bytes);
qDebug() << socketDescriptor << " : " << message;
processMessage(message);
//socket->write(data);
}
void TcpThread::disconnected()
{
qDebug() << socketDescriptor << " disconnected";
socket->deleteLater();
exit(0);
}
void TcpThread::processMessage(QByteArray message)
{
qDebug() << message << " processed";
}
void TcpThread::readyRead()
{
data = socket->readAll();
while(!data.contains('\n'))
{
socket->waitForReadyRead();
data += socket->readAll();
}
int bytes = data.indexOf('\n')+1;
QByteArray message = data.left(bytes);
data = data.mid(bytes);
qDebug() << socketDescriptor << " : " << message;
processMessage(message);
//socket->write(data);
}
在 TcpThread 的 readRead() 槽中,您无法调用 waitForReadyRead()。
来自 https://doc.qt.io/qt-6/qiodevice.html#readyRead:
readyRead() 不是递归发出的;如果你重新进入事件循环 或者在连接到readyRead()的槽内调用waitForReadyRead() 信号,该信号不会被重新发送(尽管 waitForReadyRead() 可能仍返回 true)。