的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不能触发,如果我把它放在这个函数中。有人可以解释吗?

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

+0

我想你应该在关闭客户端套接字之前添加http://doc.qt.io/qt-5/qiodevice.html#waitForBytesWritten方法调用。 – Macias

当你写的控制台应用程序,这是确定使用你的代码片段,其中一些修改,因为你没有对付阻塞GUI。只需使用以下方法:
waitForConnected
waitForByttesWritten

但是,如果你写一个GUI您shold使用的信号。
首先呼叫connectToHost后,等待connected 信号。然后你可以写你的数据。

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