Qt TcpSocket::readyRead 在特定情况下未触发

Qt TcpSocket::readyRead not triggerd in in a particular situation

本文关键字:readyRead TcpSocket Qt 在特定情况下      更新时间:2023-10-16

我在Qt5中编写了一个简单的TCP服务器,其任务可以简化为:

  • 侦听端口上的连接

  • 有人连接到它后,从中读取一个字符串,然后打印该字符串

  • 关闭套接字并侦听下一个连接

服务器的代码是这样的:

class Server:public QObject
{
Q_OBJECT
public:
QTcpServer* TcpServer;
QTcpSocket* TcpSocket;
void Start();
public slots:
void OnConnection();
};

void Server::Start()
{
TcpServer = new QTcpServer();
TcpServer->listen(QHostAddress::Any, 9999);
connect(TcpServer, &QTcpServer::newConnection, this, &Server::OnConnection);
}

void Server::OnConnection()
{
qDebug() << "connected";
TcpSocket = TcpServer->nextPendingConnection();
connect(TcpSocket, &QTcpSocket::readyRead, this, [=]()
{
qDebug() << "received:" << TcpSocket->readAll();
TcpSocket->close();
});
}

然后,我有客户端的以下代码片段:

QTcpSocket socket;
socket.connectToHost(QHostAddress::LocalHost, 9999);
auto x = QString("Some information").toUtf8();
socket.write(x);
socket.close();

如果我仅在控制台应用程序中运行它,或者在我的项目中运行它,则此代码片段工作正常:

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w; // main window of my application
w.show();
QTcpSocket socket;
socket.connectToHost(QHostAddress::LocalHost, 9999);
auto x = QString("Some information").toUtf8();
socket.write(x);
socket.close();
return a.exec();
}

这是让我感到困惑的部分:

在主窗口中,有一个QPushButton,它的clicked信号连接到一个插槽,在这个插槽中我将调用一个包含代码片段的函数。该函数主要处理设置主窗口的布局(我用了QStackedWidget(,当代码片段被执行时,它的工作方式不同。

从服务器的日志中,我认为套接字可以连接到服务器,但是无法触发QTcpSocket::readyRead,因此服务器始终在等待数据,即使代码片段中的所有五行都已执行。(在我提供的代码中,服务器的日志将只有"连接",没有以下数据。

我不知道为什么如果我把它放在这个函数中,服务器QTcpSocket::readyRead就无法触发。有人可以解释一下吗?

感谢您阅读我的问题:-(

编写控制台应用程序时,可以使用代码段进行一些修改,因为您不必处理阻塞 GUI。只需使用以下方法:
waitForConnected
waitForByttesWrite

但是,如果你编写GUI,你应该使用信号。
首先呼叫connectToHost后,等待已连接 信号。然后,您可以写入数据。

之后等待 bytesWrite 信号并确保bytes参数等于write方法返回的值。一切正常后,您可以关闭插座。