QTcpSocket RemoteHostClosedError после получения ответа

319
25 ноября 2017, 10:47

Есть многопоточный сервер, который создает новую среду при подключении клиента. После отключения клиента, среда удаляется. Структура сервера: MyServer унаследованный от QTcpServer. В конструкторе создается QThreadPool, в методе incomingConnection(qintptr socketDescriptor) создается класс MyTask, наследник QRunnable, и передается в QThreadPool. Метод run():

void MyTask::run()
{
    Core core(descriptor, exit);
    core.exec();
}

В классе Core выполняются все основные действия.

core.cpp:

#define CHUNK 2048
Core::Core(qintptr handle, bool *exit, QObject *parent)
    : QEventLoop(parent), descriptor(handle)
{
    socket = new QTcpSocket(this);
    socket->setSocketOption(QAbstractSocket::KeepAliveOption, 64);
    socket->setSocketDescriptor(descriptor);
    //Подключаем сигналы сокета к слотам
    connect(socket, &QTcpSocket::readyRead, this, &Core::onReadyRead);
    connect(socket, &QTcpSocket::disconnected, this, &Core::onDisconnected);
}
void Core::sendMessage(const QJsonValue &object)
{
    //Формируется стандартная шапка ответа сервера клиенту
    //В параметр value передается объект с ответом под каждую комманду
    QJsonObject message;
    message.insert("ans", "ok");
    message.insert("command", command);
    message.insert("value", object);
    QJsonDocument doc(message);
    auto data = doc.toJson(QJsonDocument::Compact);
    while(!data.isEmpty()){
        socket->write(data.left(CHUNK));
        data.remove(0, CHUNK);
        if(!socket->waitForBytesWritten(10000)){
            socket->disconnectFromHost();
            quit();
        }
    }
}

На стороне клиента происходит следующие:

client.cpp:

MyDialog::MyDialog(QTcpSocket *socket, QWidget *parent) : QDialog(parent), socket(socket)
{
    connect(this->socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(onError(QAbstractSocket::SocketError)));
}
void MyDialog::onError(QAbstractSocket::SocketError)
{
    qDebug() << QTime::currentTime();
    QMessageBox::warning(this, "Ошибка соединения", socket->errorString());
    socket->disconnectFromHost();
    errorStatus = true;
}
void &MyDialog::sendMessage(const QJsonDocument &doc)
{
    errorStatus = false;
    socket->connectToHost(ip, port, QIODevice::ReadWrite, QAbstractSocket::IPv4Protocol);
    if(!socket->waitForConnected(5000)){
        root = QJsonValue();
        errorStatus = true;
        return root;
    }
    socket->write(doc.toJson(QJsonDocument::Compact));
    QByteArray messageData;
    while(1){
        if(!socket->waitForReadyRead(5000)){
            break;
        }else{
            messageData.append(socket->readAll());
        }
    }
    socket->disconnectFromHost();
    ans = QJsonDocument::fromJson(messageData);
}

Когда отправляю запрос на сервер, сервер обрабатывает данные и отправляет ответ обратно клиенту. Но после получения ответа от сервера сразу выскакивает ошибка RemoteHostClosedErrorв клиенте. Т.е. метод socket->disconnectFromHost(); не успевает срабатывать. Скажите, в чем может быть проблема?

READ ALSO
Попадает ли точка в закрашенную область [требует правки]

Попадает ли точка в закрашенную область [требует правки]

Уважаемые, помогите пожалуйста! Мне нужно написать программу (мне хотя бы помощь) на С++Определить количество точек попадающих в фигуры 1 и 2 (радиус...

220
XOR шифрование типа double

XOR шифрование типа double

Здравствуйте, есть задание при помощи xor зашифровать и расшифровать массив double однобайтным ключомСложность возникла в том, как правильно...

246