UDP Сервер-Клиентский Чат в C++/Qt

Я пытаюсь написать программу чата с использованием Qt. Он наполовину завершен, но у него есть некоторые проблемы.

Прежде всего, я получаю сообщение об ошибке, когда хочу отправить клиенту свое письменное сообщение в lineedit. Это QString, но writeDatagram только отправляет QByteArray, Я гуглил это и есть несколько способов конвертировать QString в QByteArray, но я ищу лучшее решение. Я думаю, что я должен использовать connectToHost(), но read() а также write() не работает

Вторая и главная проблема заключается в том, что я не могу непрерывно отправлять и получать сообщения! Очевидно, что этого еще не произошло, но я знаю, что с ним что-то не так, потому что я тестировал его на консоли Qt, и он там тоже не работал.

Я новичок в программировании графического интерфейса и сокетов, поэтому я много искал, прежде чем опубликовать эту тему.

Обновление: Моя первая проблема решена, но теперь UDP-пакеты не отправляются и не получают, не говоря уже о работе, как приложение чата.

Обновление: я выяснил, в чем была проблема, и я решил ее. Код нужно два QUdpSocket Объекты. Я также обновил код. Теперь он полностью функционален. Если у вас есть другие материалы, я бы с удовольствием их выслушал, иначе я получил бы ответ.

Сервер:

#include "schat.h"
#include "ui_schat.h"

schat::schat(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::schat)
{
    ui->setupUi(this);
    socketServerc=new QUdpSocket(this);
    socketServer=new QUdpSocket(this);
    socketServer->bind(QHostAddress::LocalHost, 8001);
    connect(socketServer,SIGNAL(readyRead()),this,SLOT(readPendingDatagrams()));

}

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

void schat::on_sendButton_clicked()
{


    QString word=ui->lineEdit->text();
    ui->textBrowser->append(word);
    QByteArray buffer;
    buffer=word.toUtf8();
    QHostAddress sender;
    quint16 senderPort;
    socketServerc->writeDatagram(buffer.data(), QHostAddress::LocalHost, 7000 );

}

void schat::readPendingDatagrams()
{
    while (socketServer->hasPendingDatagrams()) {
        QByteArray buffer;
        buffer.resize(socketServer->pendingDatagramSize());
        QHostAddress sender;
        quint16 senderPort;
        socketServer->readDatagram(buffer.data(), buffer.size(),&sender, &senderPort);
        ui->textBrowser->append(buffer.data());

    }

}

Клиент:

#include "uchat.h"
#include "ui_uchat.h"


uchat::uchat(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::uchat)
{
    ui->setupUi(this);
    clientSocket=new QUdpSocket(this);
    clientSocketc=new QUdpSocket(this);
    clientSocketc->bind(QHostAddress::LocalHost, 7000);
    connect(clientSocketc,SIGNAL(readyRead()),this,SLOT(readPendingDatagrams()));
}

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

void uchat::on_sendButton_clicked()
{
    QString word=ui->lineEdit->text();
    ui->textBrowser->append(word);
    QByteArray buffer;
    buffer.resize(clientSocket->pendingDatagramSize());
    QHostAddress sender;
    quint16 senderPort;
    buffer=word.toUtf8();
    clientSocket->writeDatagram(buffer.data(), QHostAddress::LocalHost, 8001 );
}
void uchat::readPendingDatagrams()
{
    while (clientSocketc->hasPendingDatagrams()) {
        QByteArray buffer;
        buffer.resize(clientSocketc->pendingDatagramSize());
        QHostAddress sender;
        quint16 senderPort;
        clientSocketc->readDatagram(buffer.data(), buffer.size(),&sender, &senderPort);
        ui->textBrowser->append(buffer.data());

    }

}

1 ответ

Решение

Преобразование QString в QByteArray действительно то, что нужно сделать. Причина в том, что пакеты UDP несут только серию байтов - но QString не однозначно представляет последовательность байтов, он представляет последовательность условных символов (или QChars). Таким образом, чтобы поместить QString в массив байтов, вы должны решить, в какое двоичное представление вы хотите его кодировать. Например, если вы хотите закодировать строку с использованием кодировки UTF8 (что я бы порекомендовал), вы бы использовали метод toStt8() QString, чтобы получить QByteArray, представляющий кодировку UTF8, а получатель использовал бы метод fromStt8() QString, чтобы повернуть полученные байты обратно в QString. Существуют и другие кодировки (ascii, latin1, local8Bit), но они могут не обрабатывать интернационализацию, как это делает UTF8.

Что касается вашей второй проблемы ("Я не могу получать и отправлять сообщения непрерывно"), вам нужно будет более четко и подробно описать, что происходит, а не то, что вы ожидали. Я не знаю, что означает "постоянно" в этом контексте.

Другие вопросы по тегам