Есть многопоточный сервер, который создает новую среду при подключении клиента. После отключения клиента, среда удаляется. Структура сервера: 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();
не успевает срабатывать. Скажите, в чем может быть проблема?
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Уважаемые, помогите пожалуйста! Мне нужно написать программу (мне хотя бы помощь) на С++Определить количество точек попадающих в фигуры 1 и 2 (радиус...
Здравствуйте, есть задание при помощи xor зашифровать и расшифровать массив double однобайтным ключомСложность возникла в том, как правильно...