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

时间:2017-08-25 18:02:08

标签: c++ qt sockets tcp network-programming

我在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。有人可以解释一下吗?

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

1 个答案:

答案 0 :(得分:0)

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

但是,如果您编写GUI,请使用信号 首先在致电connectToHost后,等待connected 信号。然后你可以写你的数据。

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