@sounddiibo

Почему не отправляются сообщения QTcpSocket Qt 5.12.12?

Пишу клиент-серверное приложение, пытаюсь реализовать обычный чат. При подключении к серверу, может отправлять сообщения только последний подключившийся к нему, все остальные клиенты этого сделать не могут. лог ошибки qDebug() << "Bytes less than 2 error", это необходимо исправить.

мое предположение:
//socket = std::make_shared(sender());

в этой строчке, в server.cpp блокируется доступ к QTcpSocket, почему это происходит и как это обойти?

server.cpp

#include "server.h"

#include <QDataStream>

Server::Server() {
    if(this->listen(QHostAddress::Any, 2323)) {
        qDebug() << "Server started";
    } else {
        qDebug() << "Server starting error";
    }

    sizeofBlock = 0;
}

void Server::incomingConnection(qintptr handle) {
    socket = std::make_shared<QTcpSocket>();
    socket->setSocketDescriptor(handle);
    connect(&*socket, &QTcpSocket::readyRead, this, &Server::slotReadyRead);

    sockets.push_back(socket);
    qDebug() << "Client connected";
}

void Server::slotReadyRead() {
    socket = std::make_shared<QTcpSocket>(sender());

    QDataStream in_socket(&*socket);
    in_socket.setVersion(QDataStream::Qt_5_12);

    if(in_socket.status() == QDataStream::Ok) {
        qDebug() << "Reading...";
        while(true) {
            if(sizeofBlock == 0) {
                qDebug() << "Size of the block 0 error";

                if(socket->bytesAvailable() < 2) {
                    qDebug() << "Bytes less than 2 error";
                }

                in_socket >> sizeofBlock;
                qDebug() << "Next block size of " << sizeofBlock;
            }

            if(socket->bytesAvailable() < sizeofBlock) {
                qDebug() << "Bytes in the block not full";
            }

            QString str = nullptr;
            QTime time{};
            in_socket >> time >> str;
            sizeofBlock = 0;

            qDebug() << str;
            sendToClient(str);
            break;
        }
    } else {
        qDebug() << "Datastream error";
    }
}

void Server::sendToClient(QString text) {
    data.clear();
    QDataStream out_socket(&data, QIODevice::WriteOnly);
    out_socket.setVersion(QDataStream::Qt_5_12);

    out_socket <<qint16(0) << QTime::currentTime() << text;
    out_socket.device()->seek(0);
    out_socket << qint16(data.size() - sizeof(qint16));

    for(int i = 0; i < sockets.size(); i++) {
        sockets[i]->write(data);
    }
}


mainwindow.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, &QTcpSocket::readyRead, this, &MainWindow::slotReadyRead);
    connect(socket, &QTcpSocket::disconnected, socket, &QTcpSocket::deleteLater);

    sizeofBlock = 0;
}

MainWindow::~MainWindow()
{
    delete ui;
}


void MainWindow::on_pushButton_clicked()
{
    socket->connectToHost("127.0.0.1", 2323);
}

void MainWindow::sendMessageToServer(QString msg)
{
    data.clear();
    QDataStream out_socket(&data, QIODevice::WriteOnly);
    out_socket.setVersion(QDataStream::Qt_5_12);
    out_socket <<qint16(0) << QTime::currentTime() << msg;
    out_socket.device()->seek(0);
    out_socket << qint16(data.size() - sizeof(qint16));
    socket->write(data);
    ui->lineEdit->clear();
}

void MainWindow::slotReadyRead()
{
    QDataStream in_socket(socket);
    in_socket.setVersion(QDataStream::Qt_5_12);
    if(in_socket.status() == QDataStream::Ok) {
        while(true) {
            if(sizeofBlock == 0 && socket->bytesAvailable() > 2) {
                in_socket >> sizeofBlock;
            } else break;

            if(socket->bytesAvailable() < sizeofBlock) break;

            QString str = nullptr;
            QTime time{};
            in_socket >> time >> str;
            sizeofBlock = 0;
            ui->textBrowser->append(time.toString() + " " + str);
        }
    } else {
        qDebug() << "Data stream status error";
    }
}


void MainWindow::on_pushButton_2_clicked()
{
    sendMessageToServer(ui->lineEdit->text());
}


void MainWindow::on_lineEdit_returnPressed()
{
    sendMessageToServer(ui->lineEdit->text());
}
  • Вопрос задан
  • 42 просмотра
Пригласить эксперта
Ответы на вопрос 1
Gremlin92
@Gremlin92
Целеустремленный
У вас массив сокетов, а где перебор их в цикле на стороне сервера? Именно поэтому активен только последний клиент
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы