Проблема с одновременной обработкой запросов 2х и/или более клиентов.(QTcpServer/QTcpSockets/C++)

239
18 мая 2022, 18:50

у меня проблема с одновременной обработкой запросов 2х и/или более клиентов. когда подключаются 2 или более клиенты к моему серверу сервер принимает и обслуживает сокеты последнего в очереди клиента и у меня нет идей как эту проблему разрешить. P.S. я в первый раз работаю с TCP/IP протоколами. заголовки и исходники представлены ниже.

client.h

//.................client.h.....................
    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    #define PORT 5555
    #define HOST "127.0.0.1"
    #include <QMainWindow>
    #include <QTcpSocket>
    #include <QMessageBox>
    #include <QDebug>
    #include <QJsonDocument>
    #include <QJsonObject>
    #include <QJsonParseError>
    #include <QStandardItem>
    #include <QStandardItemModel>
    #include <QJsonArray>
    #include <QHostInfo>
    #include <QDateTime>
    
    QT_BEGIN_NAMESPACE
    namespace Ui { class MainWindow; }
    QT_END_NAMESPACE
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        MainWindow(QWidget *parent = nullptr);
        ~MainWindow();
        bool checkConnection(const QByteArray&);
        QTcpSocket *socket;
        QByteArray data;
        QJsonDocument doc;
        QJsonParseError docError;
        bool isConnected = false;
        QString username = QString();
    public slots:
        void sockReady();
        void sockDisc();
    
    private slots:
        void on_connectButton_clicked();
        void on_discButton_clicked();
    
        void on_saveButton_clicked();
    
        void on_sendBut_clicked();
    
    private:
        Ui::MainWindow *ui;
    };
    #endif // MAINWINDOW_H

client.cpp

//......................client.cpp........................
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    socket = new QTcpSocket(this);
    connect(socket, SIGNAL (readyRead()), this, SLOT(sockReady()));
    connect(socket, SIGNAL(disconnected()), this, SLOT(sockDisc()));
    ui->usernameLab->setText((this->username));

}
MainWindow::~MainWindow()
{
    delete ui;
}
void MainWindow::on_connectButton_clicked()
{
    if (!this->isConnected)
    {
        if (ui->nameEdit->text().size())
        {
            socket->connectToHost(HOST, PORT);//connecting to server
        }
        else {
            QMessageBox::critical(this, "ERROR", "Name can't be empty");
        }
    }
    else
    {
        QMessageBox::critical(this, "ERROR", "Connection failed");
        ui->connectButton->setStyleSheet("color:red");
        return;
    }
}
void MainWindow::sockDisc()
{
    socket->deleteLater();
}
void  MainWindow::sockReady()
{
    QByteArray message = socket->readAll();
    //working field
    if (this->checkConnection(message))
    {
        QMessageBox::information(this, "INFO", "Connection established");
    }
    else
    {
        QMessageBox::critical(this, "ERROR", socket->errorString());
    }
}
bool MainWindow::checkConnection(const QByteArray &message)
{
    QJsonDocument doc = QJsonDocument::fromJson(message);
    if (doc.object().value("type").toString() == "connected" &&
            doc.object().value("status").toString() == "yes")
    {
        this->isConnected = true;
        return 1;
    }
    this->isConnected = false;
    return 0;
}
void MainWindow::on_discButton_clicked()
{
    this->close();
}
void MainWindow::on_saveButton_clicked()
{
    if (ui->nameEdit->text().size())
    {
        ui->nameEdit->setEnabled(0);
        ui->saveButton->setEnabled(0);
        ui->nameLab->setText(ui->nameEdit->text());
        this->username = ui->nameLab->text();
        return;
    }
    else
    {
        QMessageBox::warning(this, "WARNING", "name is empty");
        return;
    }
}
void MainWindow::on_sendBut_clicked()
{
    QString name = this->username;
    QString ip_v4 = QHostInfo().hostName();
    QString message = ui->messageLine->text();
    QString date_time = QDateTime::currentDateTime().toString();
    QString  to_send ="{\"type\":\"send_message\",\"name\":\""+name+"\", \"message\":\""+message+"\", \"ip_v4\":\""+ip_v4+"\" , \"date_time\" :\""+date_time+"\"}";
    QByteArray to_send_array = QByteArray::fromStdString(to_send.toStdString());
    qDebug()<<"sent : "<< to_send_array;
    socket->write(to_send_array);
}

...ниже часть самого сервера где нужно разрешить проблему... server.h

//............server.h...............
#ifndef MYSERVER_H
#define MYSERVER_H
#define PORT 5555
#define HOST "127.0.0.1"
#include <QTcpSocket>
#include <QTcpServer>
#include <QHostAddress>
#include <iostream>
#include <QJsonObject>
#include <QJsonParseError>
#include <QFile>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>
#include <QDir>
#include <map>
using namespace std;
class myserver : public QTcpServer
{
    Q_OBJECT;
public:
    myserver();
    ~myserver();
    qintptr sockDescriptor = 0;
    QTcpSocket* socket;
    QTcpServer* server = new QTcpServer(this);
    map <qintptr, QTcpSocket*> sockets;
    QByteArray data;
    QJsonDocument doc;
    QJsonParseError docError;
    QSqlDatabase DB;
public slots:
    void startServer();
    void incomingConnection(qintptr socketDescriptor);
    void sockReady();
    void sockDisc();

};
#endif // MYSERVER_H

server.cpp

//......server.cpp.......
#include "myserver.h"
using namespace std;
myserver::myserver()
{
}
myserver::~myserver()
{
// "{\"type\":\"select\", \"params\":\"workers\"}"
//"{\"type\":\"select\", \"params\":\"workers\"}"
}
void myserver::startServer()
{
    if (this->listen(QHostAddress::Any,PORT ))
    {
        DB = QSqlDatabase::addDatabase("QSQLITE");
        DB.setDatabaseName(QDir::homePath()+"/server/serverDB/users");

        if (DB.open()){
            qDebug()<<"***server**working***";//if server is listening to network
            qDebug()<<"***database**working***";
        }
        else
        {
            qDebug()<< "***database**not**working***";
        }
    }
}
void myserver::incomingConnection(qintptr socketDescriptor)
{
    socket = new QTcpSocket(this);
    socket->setSocketDescriptor(int(socketDescriptor));
    connect(socket, SIGNAL(readyRead()), this, SLOT(sockReady()));
    connect(socket, SIGNAL (disconnected()), this, SLOT(sockDisc()));
    sockets.insert(std::pair<qintptr, QTcpSocket*>(socketDescriptor, socket));
    qDebug()<<"New socket descriptor is"<<socketDescriptor;
    qDebug()<< "CLIENT CONNECTED";
    socket->write("{\"type\":\"connected\",\"status\":\"yes\"}");
}
void myserver::sockReady()
{
    //QTcpSocket *socket  = new QTcpSocket(this);
    QByteArray to_get_array = socket->readAll();
    QJsonDocument to_get_doc = QJsonDocument::fromJson(to_get_array);
    qDebug()<< "....sockready....";
    
    //qDebug()<< "searching key is "<<QTcpServer::nextPendingConnection()->socketDescriptor();
    QTcpServer::addPendingConnection(socket);
    for (auto it = sockets.cbegin(); it != sockets.cend(); it++)
    {
        qDebug()<< it->first<<"\t"<<it->second<<"\n";
    }
    socket = sockets.find(QTcpServer::nextPendingConnection()->socketDescriptor())->second;
    if (to_get_doc.object().value("type") == "send_message")
    {
        qDebug() << to_get_doc;
    }
}
void myserver::sockDisc()
{
    qDebug()<< "Disconnected";
    socket->deleteLater();
}
READ ALSO
Выбивает программу с ошибкой -1073741819

Выбивает программу с ошибкой -1073741819

В общем есть два класса, один для хранения, другой для добавления строк в базу данныхПолный код программы:

190
cUrl запрос с конкретного интерфейса

cUrl запрос с конкретного интерфейса

Имеется ОС Linux, libcurl 768

199
Профилирование gprof

Профилирование gprof

Помогите разобратьсяКуча мануалов по gprof - но они не понятные

228
Смена знака с + на - в цикле С++

Смена знака с + на - в цикле С++

Я новичок в программировании,нужно написать цикл в котором сумма будет считаться как 1-1/2+1/3-1/4+1/5-1/6 и тд,не совсем понимаю как менять знак с + на - в цикле

273