的Qt的TCPSocket :: readyRead不triggerd在特定情况下
问题描述:
我写QT5一个简单的TCP服务器,其任务可以简化为:的Qt的TCPSocket :: readyRead不triggerd在特定情况下
监听连接端口
人后连接到它,从中读取一个字符串,然后打印字符串
关闭套接字,并监听下一个连接
服务器的代码是这样的:
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
waitForByttesWritten
但是,如果你写一个GUI您shold使用的信号。
首先呼叫connectToHost
后,等待connected 信号。然后你可以写你的数据。
之后,等待bytesWritten信号并确保bytes
参数等于由write
方法返回的值。当一切正常时,您可以关闭插座。
我想你应该在关闭客户端套接字之前添加http://doc.qt.io/qt-5/qiodevice.html#waitForBytesWritten方法调用。 – Macias