Пишу клиент-серверное приложение, пытаюсь реализовать обычный чат. При подключении к серверу, может отправлять сообщения только последний подключившийся к нему, все остальные клиенты этого сделать не могут. лог ошибки 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());
}