Получил концептуальную модель для работы с несколькими изменениями. Использовал ответ, заданный "sashoalm" в этом вопросе, для передачи данных с использованием QdataStream и использовал сигналы и слоты для циклического переключения между последовательностью чтения-записи для каждого типа запроса.
мой класс сервера выглядит следующим образом
tcpserver.h
#ifndef TCPSERVER_H
#define TCPSERVER_H
#include<qt5/QtNetwork/QTcpServer>
#include<qt5/QtNetwork/QTcpSocket>
#include<qt5/QtCore/QObject>
class TCPServer : public QObject
{
Q_OBJECT
public:
explicit TCPServer(QObject *parent = nullptr);
signals:
void dataReceived(QByteArray);
private slots:
void newConnection();
void disconnected();
void readyRead();
private:
QTcpServer *server;
QTcpSocket *socket;
QHash<QString, int> reverse_hash;
};
#endif // TCPSERVER_H
tcpserver.cpp
#include <iostream>
#include "tcpserver.h"
#include <qt5/QtCore/QDataStream>
#include <qt5/QtCore/QBuffer>
#include <qt5/QtCore/QString>
class BlockWriter
{
public:
BlockWriter(QIODevice *io)
{
buffer.open(QIODevice::WriteOnly);
this->io = io;
_stream.setVersion(QDataStream::Qt_4_8);
_stream.setDevice(&buffer);
_stream << quint64(0);
}
~BlockWriter()
{
_stream.device()->seek(0);
_stream << static_cast<quint64>(buffer.size());
io->write(buffer.buffer());
}
QDataStream &stream()
{
return _stream;
}
private:
QBuffer buffer;
QDataStream _stream;
QIODevice *io;
};
class BlockReader
{
public:
BlockReader(QIODevice *io)
{
buffer.open(QIODevice::ReadWrite);
_stream.setVersion(QDataStream::Qt_4_8);
_stream.setDevice(&buffer);
qint64 blockSize;
readMax(io, sizeof(blockSize));
buffer.seek(0);
_stream >> blockSize;
readMax(io, blockSize);
buffer.seek(sizeof(blockSize));
}
QDataStream& stream()
{
return _stream;
}
private:
void readMax(QIODevice *io, qint64 n)
{
while (buffer.size() < n) {
buffer.write(io->read(n - buffer.size()));
}
}
QBuffer buffer;
QDataStream _stream;
};
TCPServer::TCPServer(QObject *parent) : QObject(parent)
{
server = new QTcpServer(this);
connect(server, SIGNAL(newConnection()), SLOT(newConnection()));
qDebug() << "Listening:" << server->listen(QHostAddress::Any, 5404);
reverse_hash.insert("data1", 1);
reverse_hash.insert("data2", 2);
}
void TCPServer::newConnection()
{
while (server->hasPendingConnections())
{
qDebug()<<"incoming connection!";
socket = server->nextPendingConnection();
connect(socket, SIGNAL(readyRead()), SLOT(readyRead()));
connect(socket, SIGNAL(disconnected()), SLOT(disconnected()));
}
}
void TCPServer::disconnected()
{
qDebug() << "disconnected!";
disconnect(socket, SIGNAL(readyRead()));
disconnect(socket, SIGNAL(disconnected()));
socket->deleteLater();
}
void TCPServer::readyRead()
{
qDebug() << "Read!";
QString data;
BlockReader(socket).stream() >> data;
qDebug() <<"received data request: " << data;
switch(reverse_hash.value(data))
{
case 1: //call sequence to respond to request.(write to data)
qDebug() << "responding go data1 request!";
break;
case 2://call sequence to respond to request.(write to data)
qDebug() << "responding go data2 request!";
break;
}
BlockWriter(socket).stream()<<data;
socket->flush();
}
мой класс GUI клиента выглядит следующим образом
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QtNetwork>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
QTcpSocket *socket;
QHash<int, QString> hash;
int current_slot, starting_slot, ending_slot;
signals:
void dataSet();
public slots:
void connectToHost();
void connected();
void disconnected();
void setDatatoGet();
void getData();
//bool writeData(QByteArray data);
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <iostream>
class BlockWriter
{
public:
BlockWriter(QIODevice *io)
{
buffer.open(QIODevice::WriteOnly);
this->io = io;
_stream.setVersion(QDataStream::Qt_4_8);
_stream.setDevice(&buffer);
_stream << quint64(0);
}
~BlockWriter()
{
_stream.device()->seek(0);
_stream << static_cast<quint64>(buffer.size());
io->write(buffer.buffer());
}
QDataStream &stream()
{
return _stream;
}
private:
QBuffer buffer;
QDataStream _stream;
QIODevice *io;
};
class BlockReader
{
public:
BlockReader(QIODevice *io)
{
buffer.open(QIODevice::ReadWrite);
_stream.setVersion(QDataStream::Qt_4_8);
_stream.setDevice(&buffer);
qint64 blockSize;
readMax(io, sizeof(blockSize));
buffer.seek(0);
_stream >> blockSize;
readMax(io, blockSize);
buffer.seek(sizeof(blockSize));
}
QDataStream& stream()
{
return _stream;
}
private:
void readMax(QIODevice *io, qint64 n)
{
while (buffer.size() < n) {
buffer.write(io->read(n - buffer.size()));
}
}
QBuffer buffer;
QDataStream _stream;
};
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
starting_slot = 1;
current_slot = starting_slot;
ending_slot = 2;
ui->setupUi(this);
ui->status_label->setStyleSheet("background-color:red;");
ui->receive_btn->setEnabled(false);
socket = new QTcpSocket(this);
connectToHost();
connect(ui->conn_btn, SIGNAL(clicked()), this, SLOT(connectToHost()));
connect(ui->receive_btn, SIGNAL(clicked()), this, SLOT(setDatatoGet()));
connect(this, SIGNAL(dataSet()), this , SLOT(setDatatoGet()));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::connectToHost()
{
socket->deleteLater();
socket = new QTcpSocket(this);
socket->connectToHost(QHostAddress("192.168.0.127"), 5404);
connect(socket, SIGNAL(connected()), this, SLOT(connected()));
connect(socket, SIGNAL(disconnected()), this, SLOT(disconnected()));
//ADD to hash table
hash.insert(1, "data1");
hash.insert(2, "data2");
}
void MainWindow::connected()
{
ui->status_label->setStyleSheet("background-color:green;");
ui->receive_btn->setEnabled(true);
connect(socket, SIGNAL(readyRead()),this, SLOT(getData()));
}
void MainWindow::disconnected()
{
ui->status_label->setStyleSheet("background-color:red;");
ui->receive_btn->setEnabled(false);
disconnect(socket, SIGNAL(readyRead()),this, SLOT(getData()));
}
void MainWindow::setDatatoGet()
{
if(current_slot == ending_slot + 1)
{
current_slot = starting_slot;
}
qDebug() <<"calling request data slot " << current_slot;
BlockWriter(socket).stream() << hash.value(current_slot);
socket->flush();
current_slot++;
}
void MainWindow::getData()
{
QString data;
BlockReader(socket).stream() >> data;
//qDebug() <<"received response, current received data is for slot "<< data <<"and current number is" << current_slot;
switch (current_slot - 1)
{
case 1:
//display in respective label
qDebug() << "display data1 to label!";
break;
case 2:
//display in respective label
qDebug() << "display data2 to label!";
break;
}
emit dataSet();
}