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網絡傳輸預告

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章