QT QTcpServer无法及时连接

时间:2016-03-30 18:36:29

标签: c++ qt networking tcp

我正在创建一个简单的程序,它将“连接”到自身然后发送数据。它启动QTcpServer然后等待任何传入连接。我有一个单独的函数,它将依次尝试在localhost和我决定的端口上连接到此服务器。这在我在命令提示符下打开Telnet时有效,但现在在我的实际程序中。这是我使用的代码(有些是来自其他来源的代码段)

MainWindow.cpp:

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    server = new QTcpServer(this);
    //Initialize and start the server
    connect(server, SIGNAL(newConnection()), this, SLOT(newConnection()));
    if (!server->listen(QHostAddress::Any, 3665))
    {
        qDebug() << "Server failed to start!";
    }
    else
    {
        qDebug() << "Server started";
    }
    //Try to connect to the server
    connectToServer("127.0.0.1", qint16(3665));
}

MainWindow::~MainWindow()
{
    delete server;
    delete ui;
}

void MainWindow::connectToServer(QString host, qint16 port)
{
    qDebug() << "Connecting to " + host + " at port " + QString::number(port);
    QTcpSocket socket;
    socket.connectToHost(host, port);
    if (!socket.waitForConnected(5000))
    {
        qDebug() << socket.errorString();
    }
    while (socket.bytesAvailable() < (int)sizeof(quint16))
    {
        if (!socket.waitForReadyRead(5000))
        {
            qDebug() << socket.errorString();
        }
    }
    quint16 blockSize;
    QDataStream in(&socket);
    in.setVersion(QDataStream::Qt_5_5);
    in >> blockSize;
    while (socket.bytesAvailable() < blockSize)
    {
        if (!socket.waitForReadyRead(5000))
        {
            qDebug() << socket.errorString();
        }
    }
    QString fortune;
    in >> fortune;
    qDebug() << fortune;
}

void MainWindow::newConnection()
{
    qDebug() << "A connection has been found.";
    QTcpSocket *socket = server->nextPendingConnection();

    socket->write("hello client\r\n");
    socket->flush();
    socket->waitForBytesWritten(5000);
    socket->close();
}

1 个答案:

答案 0 :(得分:2)

问题的根源很可能是由waitFor方法引起的伪同步混乱。摆脱它们。此外,您无法保证在readyRead上收到多少字节:在某些情况下,一次接收一个字节,或者实际上是任意数量的字节,包括比您预期的更多的字节,这是完全正常的。 。你的代码必须应付这一点。

This就是这种方法的一个例子 - 它可以异步地执行您想要的操作。 That是另一个示例,展示了如何利用易于阅读的声明性语法来利用状态机来编写异步通信代码。