Qt+VS实现UDP通信,QUdpSocket使用实例,两个程序之间实现通信,超完整

0.前言

学了半年c++,断断续续学习了一段时间的QT,终于能靠自己写出通过UDP协议实现两个进程互发信息的小程序了。本项目由两个工程组成,运行时,两个工程同时运行。姑且称为程序A和程序B,两端都可以实现收发(解决了中文乱码的问题)。(有空再补充udp通信的原理吧)

1.配置环境

我用的VS2013+QT5.5(其他版本均可)

2.新建工程

新建两个工程,选择Qt Application或者Qt GUI Application,基类选择QDialog,qmake模块选项勾上Network。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.程序A

main.cpp

#include "practice11.h"
#include <QtWidgets/QApplication>
int main(int argc, char *argv[])
{
    
    
 QApplication a(argc, argv);
 practice11 w;
 w.show();
 return a.exec();
}

practice11.h

#ifndef PRACTICE11_H
#define PRACTICE11_H

#include <QtWidgets/QDialog>
#include "ui_practice11.h"
#include <QDialog>
#include <QPushButton>
#include <QGridLayout>
#include <QUdpSocket>
#include <QTextEdit>
class practice11 : public QDialog
{
    
    
	 Q_OBJECT
 public:
	 practice11(QWidget *parent = 0);
	 ~practice11();
 private:
	Ui::practice11Class ui;
	QPushButton* p1;
	QPushButton* clearDataBtn2;
	QPushButton* sendDataBtn3;
	QPushButton* exitButton;
	QPushButton* p4;
	QTextEdit* textEdit;
	QUdpSocket* udpSocket; 
 private slots:
	 int OnClick();
	 void send();
	 void recv();
	 void clearText();
};
#endif // PRACTICE11_H

practice11.cpp

#include "practice11.h"
practice11::practice11(QWidget *parent)
: QDialog(parent)
{
    
    
	 ui.setupUi(this);
	 p1 = new QPushButton(this);
	 p1->setText(QString::fromLocal8Bit("这个按钮没有什么用"));
	 clearDataBtn2 = new QPushButton(this);
	 clearDataBtn2->setText(QString::fromLocal8Bit("清空文本框"));
	 sendDataBtn3 = new QPushButton(this);
	 sendDataBtn3->setText(QString::fromLocal8Bit("发送"));
	 p4 = new QPushButton(this);
	 p4->setText("hello World!");
	 p4->setStyleSheet(QString("QPushButton{background-color:rgb(255, 110, 0)} QPushButton:hover{background-color:rgb(200, 205, 70)} QPushButton:pressed{background-color:rgb(0, 90, 255)}"));
	 exitButton = new QPushButton(this);
	 exitButton->setText(QString::fromLocal8Bit("退出"));
	 textEdit = new QTextEdit(this);
	 QVBoxLayout* playout = new QVBoxLayout(this);
	 playout->addStretch();
	 playout->addWidget(p1);
	 playout->addWidget(clearDataBtn2);
	 playout->addWidget(sendDataBtn3);
	 playout->addWidget(p4);
	 playout->addWidget(textEdit);
	 playout->addWidget(exitButton);
	 this->setLayout(playout);
	 setFixedSize(600, 600);
	 connect(p4, SIGNAL(clicked()), this, SLOT(OnClick()));
	 udpSocket = new QUdpSocket(this);
	 udpSocket->bind(QHostAddress::LocalHost, 1000);
	 connect(udpSocket, SIGNAL(readyRead()), this, SLOT(recv()));
	 connect(sendDataBtn3, SIGNAL(clicked()), this, SLOT(send()));
	 connect(exitButton, SIGNAL(clicked()), this, SLOT(close()));
	 connect(clearDataBtn2, SIGNAL(clicked()), this, SLOT(clearText()));
}
practice11::~practice11(){
    
    }
int practice11::OnClick()
{
    
    
    QString str = "hello world!";  
    textEdit->append(str);
    return 0;
}
void practice11::send()
{
    
    
    QString str = textEdit->toPlainText();
    udpSocket->writeDatagram(qPrintable(str), QHostAddress::LocalHost, 1001);
}
void practice11::recv()
{
    
    
    QByteArray receive_data;
    receive_data.resize(udpSocket->pendingDatagramSize());//获取udp缓冲池里的数据大小
    udpSocket->readDatagram(receive_data.data(), receive_data.size(), 0, 0);
    textEdit->append(QString::fromLocal8Bit(receive_data.data()));
}
void practice11::clearText()
{
    
    
    textEdit->clear();
}

4.程序B

main.cpp

#include "practical2.h"
#include <QtWidgets/QApplication>
int main(int argc, char *argv[])
{
    
    
 QApplication a(argc, argv);
 practical2 w;
 w.show();
 return a.exec();
}

practice2.h

#ifndef PRACTICAL2_H
#define PRACTICAL2_H
#include <QtWidgets/QDialog>
#include "ui_practical2.h"
#include <QPushButton>
#include <QUdpSocket>
#include <QTextEdit>
#include <QGridLayout>
class practical2 : public QDialog
{
    
    
 Q_OBJECT
public:
 practical2();
 ~practical2();
private:
 QPushButton* recvBtn1;
 QPushButton* sendBtn2;
 QPushButton* exitBtn3;
 QPushButton* clearRecvTextBtn4;
 QPushButton* clearSendTextBtn5;
 QTextEdit* recvTextEdit;
 QTextEdit* sendTextEdit;
 QUdpSocket* udpSocket;
private:
 Ui::practical2Class ui;
public slots:
 void udpRecive();
 void udpSend();
 void clearRecvText();
 void clearSendText();
};
#endif // PRACTICAL2_H

practice.cpp

#include "practical2.h"
practical2::practical2()
{
    
    
 ui.setupUi(this);
 recvBtn1 = new QPushButton(this);//创建对象时加上(this),析构函数里就不用加上delete QPushButton;这是因为,在这种写法下,QPushButton成了其父对象ui的子对象,父对象析构时,子对象会自动被先行析构。
 recvBtn1->setText(QString::fromLocal8Bit("接收数据"));
 sendBtn2 = new QPushButton(this);
 sendBtn2->setText(QString::fromLocal8Bit("发送数据"));
 exitBtn3 = new QPushButton(this);
 exitBtn3->setText(QString::fromLocal8Bit("退出"));
 clearRecvTextBtn4 = new QPushButton(this);
 clearRecvTextBtn4->setText(QString::fromLocal8Bit("清除接收文本框的内容"));
 clearSendTextBtn5 = new QPushButton(this);
 clearSendTextBtn5->setText(QString::fromLocal8Bit("清除发送文本框的内容"));
 recvTextEdit = new QTextEdit(this);
 sendTextEdit = new QTextEdit(this);
 QGridLayout* layout = new QGridLayout(this);
 layout->addWidget(recvBtn1, 0, 0, 1, 1);
 layout->addWidget(clearRecvTextBtn4, 0, 1, 1, 1);
 layout->addWidget(recvTextEdit, 1, 0, 1, 2);
 layout->addWidget(sendBtn2, 2, 0, 1, 1);
 layout->addWidget(clearSendTextBtn5, 2, 1, 1, 1);
 layout->addWidget(sendTextEdit, 3, 0, 1, 2);
 layout->addWidget(exitBtn3, 4, 0, 1, 2);
 setFixedSize(600, 600);
 udpSocket = new QUdpSocket(this);
 udpSocket->bind(QHostAddress::LocalHost, 1001);//绑定程序B的ip地址以及端口号
 connect(udpSocket, SIGNAL(readyRead()), this, SLOT(udpRecive()));//注意不要写成readRead()
 connect(sendBtn2, SIGNAL(clicked()), this, SLOT(udpSend()));
 connect(exitBtn3, SIGNAL(clicked()), this, SLOT(close()));
 connect(clearRecvTextBtn4, SIGNAL(clicked()), this, SLOT(clearRecvText()));
 connect(clearSendTextBtn5, SIGNAL(clicked()), this, SLOT(clearSendText()));
}
practical2::~practical2(){
    
    }
void practical2::udpRecive()
{
    
    
 QByteArray receive_data;
 receive_data.resize(udpSocket->pendingDatagramSize());
 udpSocket->readDatagram(receive_data.data(), receive_data.size(), 0, 0);
 recvTextEdit->append(QString::fromLocal8Bit(receive_data.data()));
}
void practical2::udpSend()
{
    
    
 QString str = sendTextEdit->toPlainText();
 udpSocket->writeDatagram(qPrintable(str), QHostAddress::LocalHost, 1000);//填写程序A的ip地址以及端口号
 //udpSocket->writeDatagram(qPrintable(str), str.size(),QHostAddress::LocalHost, 1000);//写成这个样子会出现中文字符传送时只能传送一部分字符的现象
}
void practical2::clearRecvText()
{
    
    
 recvTextEdit->clear();
}
void practical2::clearSendText()
{
    
    
 sendTextEdit->clear();
}

5.效果

practice11发送和接收文本框共用同一个了。
在这里插入图片描述

在这里插入图片描述

6.项目下载路径

https://download.csdn.net/download/weixin_40162095/12549203

7.图片UDP网络传输预告

最近忙别的东西了,很难再继续这个项目了

8.视频UDP网络传输预告

最近忙别的东西了,很难再继续这个项目了

猜你喜欢

转载自blog.csdn.net/weixin_40162095/article/details/106945845