使用QtUdpSocket的简单交流c / s应用

时间:2019-03-23 10:07:55

标签: c++ qt

我是Qt的初学者,我想使用QUdpSocket编写没有GUI的服务器应用程序,我已经编写了客户端GUI应用程序和服务器GUI应用程序,它们运行良好,但是没有GUI的服务器无法正常工作

我尝试使用while(true)循环使应用程序运行,因为我认为在代码“ return a.exec()”之后,该应用程序将停止。但是我的服务器应用程序无法正常工作。

这是我的代码: 带有GUI的客户端:

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    socket=new QUdpSocket(this);
    //click pushbutton send message to server
    connect(this->ui->pushButton,SIGNAL(clicked()),this,SLOT(send()));
}

Widget::~Widget()
{
    delete ui;
}
//send message
void Widget::send()
{
    QByteArray msg="client2:hello world"; 
    socket->writeDatagram(msg.data(),msg.size(),QHostAddress::LocalHost,6666);
}

客户端应用程序和带有GUI应用程序的服务器可以正常工作。但是,当我尝试制作不带GUI的服务器应用程序时,我发现服务器无法从客户端获取消息。 这是我的不带GUI的server.cpp:

#include "server.h"

Server::Server(QObject *parent) : QObject(parent)
{
    socket=new QUdpSocket(this);
    array=new QByteArray();
    socket->bind(QHostAddress::LocalHost,6666,QAbstractSocket::DontShareAddress);
    socket->open(QIODevice::ReadWrite); //without this line, the app will show:
//'QIOBevice::read(QUdpSocket):device not open',but it still can get the message from client.
    connect(socket,SIGNAL(readyRead()),this,SLOT(printMsg()));
}

void Server::printMsg()
{
    if(socket->hasPendingDatagrams()) //I forgot this line before.
    {
        array->resize(socket->pendingDatagramSize());
        socket->readDatagram(array->data(),array->size());
        socket->readAll();
        qDebug()<<"yesyesyes";
    }
}

我尝试了很多次,我认为问题出在我的main.cpp中:

#include <QCoreApplication>
#include "server.h"
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    Server s;

    return a.exec();//after a.exec(),the app is still working!!!
}

在GUI应用程序中,如果我不关闭窗口,则服务器应用程序将始终运行,并且可以理解SIGNAL和SLOT。但是在控制台应用程序中,该应用程序运行很快并且无法运行从客户端获取消息(无法显示消息)。

1 个答案:

答案 0 :(得分:0)

您的主体中不应包含while(true),否则,实际上是冻结了线程和Qt应用程序。这正是app.exec();的目的,它将在您的应用程序关闭时返回(更多详细信息here

如果您的应用程序(带有或不带有GUI)在调用app.exec()之后关闭,则归因于以下情况之一:

  • 您正在手动关闭它,例如与qApp->quit();
  • 您正在强制退出,例如与exit(1);
  • 致命错误或异常会提前终止您的应用程序