QTcpSocket не получает данные, отправленные с сервера

#c #qt #sockets #server #qtwidgets

#c #qt #сокеты #сервер #qtwidgets

Вопрос:

У меня возникли проблемы с отправкой данных с сервера клиенту, использующему Qt. Всякий раз, когда я делаю это QTcpSocket::waitForBytesWritten() после вызова QTcpSocket::write(...) , он возвращает false.

Я пытался использовать bytesWritten сигнал, но он никогда не передается, предположительно потому, что никакие данные не могут быть записаны, и никакие данные не принимаются на стороне клиента.

writeData Метод — это то, что вызывается в MainWindow классе, но чтобы попытаться сузить причину проблемы, я перенес запись данных клиенту в newConnection метод.

Сообщение Connection received выводится в окно вывода. Я отправляю строку Some random data в newConnection методе клиенту для целей тестирования, но клиент ее не получает (код для вывода полученных данных на стороне клиента находится внутри Character::readData() метода).

Значение returnValue переменной равно true, и код возвращается в результате вызова client->waitForBytesWritten(-1) метода. client->errorString() выдает Unknown error , а затем печатается сообщение Bytes written (хотя, очевидно, ничего не написано, но я просто использую его как сообщение о состоянии).

Server.cpp

 #include "Server.h"

Server::Server(QObject *parent) : QObject(parent)
{
    server = new QTcpServer(this);

    qDebug() << connect(server, SIGNAL(newConnection()), SLOT(newConnection()));
    qDebug() << connect(server, SIGNAL(bytesWritten()), SLOT(bytesWritten()));

    qDebug() << "Listening:" << server->listen(QHostAddress::Any, 1451);

    server->waitForNewConnection(-1);
}

void Server::newConnection()
{
    qDebug("Connection received");

    client = server->nextPendingConnection();

    client->write("Some random datan");
    bool returnValue = client->flush();

    qDebug() << "Return value: " << returnValue;

    qDebug() << client->waitForBytesWritten(-1);

    qDebug() << "Error: " << client->errorString();

    qDebug() << "Bytes written";
}

void Server::bytesWritten(qint64 bytes)
{
    qDebug() << "Bytes written: " << QString::number(bytes);
}

void Server::writeData(std::string data)
{
    QByteArray byteArray = QByteArray(data.c_str());

    qDebug() << "Write data: " << QString::fromStdString(data);
    client->write(byteArray);
}
  

Client.cpp

 #include "Client.h"
#include "mainwindow.h"

Client::Client(QObject* parent) : QObject(parent)
{
    socket = new QTcpSocket(this);

    (void)QObject::connect(socket, SIGNAL(connected()), this, SLOT(connected()));
    qDebug() << "Connect signal" << QObject::connect(socket, SIGNAL(readyRead()), this, SLOT(readData()));
}

bool Client::connectToHost(QString host)
{
    socket->connectToHost(host, 1451);
    socket->waitForConnected();

    qDebug() << "Error: " << QString::number(socket->error() == QAbstractSocket::UnknownSocketError);

    return true;
}

void Client::connected()
{
    qDebug("Socket is connected");

    qDebug() << QString::number(socket->state() == QAbstractSocket::ConnectedState);
}

void Client::readData()
{
    qDebug("Read data");

    QTcpSocket* sender = static_cast<QTcpSocket*>(QObject::sender());
    QByteArray data = sender->readAll();

    std::string character = data.toStdString();

    qDebug() << "Character received: " << QString::fromStdString(character);

    MainWindow::characterReceived(character);
}
  

Комментарии:

1. Вы пробовали удалить client->flush() вызов? В этом не должно быть необходимости, и это может означать запись всех данных, что означает, что при client->waitForBytesWritten(-1) вызове больше не нужно записывать данные (хотя я не уверен, что waitForBytesWritten делает в этом случае). Можете ли вы также показать выходные данные от клиента.

2.Из документации "Note: This function may fail randomly on Windows. Consider using the event loop and the bytesWritten() signal if your software will run on Windows." .

3. @G.M. Я удалил client->flush() вызов, и теперь waitForBytesWritten вызов возвращается true . Что касается waitForBytesWritten вызова метода, я просто пробовал все, что мог, чтобы заставить это работать, даже если некоторые вещи могут показаться ненужными. Странно то, что сервер говорит Connection received , но затем говорит Error: Unknown error в моей строке отладки. И клиент находится в ConnectedState соответствии с отладкой (он распечатывает 1 , или true ), но он выдает UnknownSocketError