C ++ / Qt中的UDP服务器 - 客户端聊天

时间:2013-11-21 15:53:10

标签: c++ qt sockets udp qudpsocket

我正在尝试使用Qt编写聊天程序。它完成了一半,但它有一些问题。

首先,当我想将我的书面消息以lineedit发送给客户端时,我收到错误。这是QString,但writeDatagram只发送QByteArray。我用谷歌搜索了它,并且有一些方法可以将QString转换为QByteArray,但我正在寻找更好的解决方案。 我想我应该使用connectToHost(),但read()write()不起作用。

第二个主要问题是我不能连续发送和接收消息!显然这个还没有发生,但我知道它有问题,因为我已经在Qt控制台上测试了它,它也没有在那里工作。

我是GUI和Socket编程的新手,所以在发布这个主题之前我已经搜索了很多。

更新:我的第一个问题解决了,但现在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 个答案:

答案 0 :(得分:2)

将QString转换为QByteArray确实是要做的事情。原因是UDP数据包只携带一系列字节 - 但QString并不明确地表示字节序列,它代表一系列概念字符(a.k.a. QChars)。因此,为了将QString放入一个字节数组中,您必须决定要将其编码为哪个二进制表示。例如,如果你想使用UTF8编码(我建议)对字符串进行编码,你可以使用QString的toUtf8()方法来获取表示UTF8编码的QByteArray,接收器将使用QString的fromUtf8()方法来转换收到的字节返回QString。还有其他编码(ascii,latin1,local8Bit),但它们可能不像UTF8那样处理国际化。

至于你的第二个问题(“我不能连续发送和接收消息”),你将不得不更明确地描述发生了什么以及你预期会发生什么。我不知道在这种情况下“连续”意味着什么。