这个工程是由这篇文章修改而来。
界面布局如下:
没有涉及到很复杂的控件,都是一些基本常用的控件。
一样的套路:
因为涉及到网络,所以我们需要在工程文件中加入QT+=network,这些工程需要设置的代码,在文章开头提到的那篇文章已经写的很清楚了,这里就不再继续讲了。
现在主要来看工程代码:
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QUdpSocket>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
void localhost_ip_get(void);
QUdpSocket *udp_server;
QString receive_buff;
QHostAddress client_address;
quint16 client_port = 0;
private:
Ui::MainWindow *ui;
private slots:
void udp_server_receive_data(void);
void on_listen_pushButton_clicked();
void on_send_pushButton_clicked();
void on_clear_send_buff_pushButton_clicked();
void on_clear_receive_buff_pushButton_clicked();
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QNetworkInterface>
#include <QMessageBox>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
//设置标题
this->setWindowTitle("UDP_SERVER");
localhost_ip_get();
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::localhost_ip_get()
{
udp_server = new QUdpSocket(this);
ui->udp_server_ip_textEdit->setText(QNetworkInterface().allAddresses().at(1).toString());//获取本地IP
}
void MainWindow::udp_server_receive_data()
{
QByteArray datagram;
while( udp_server->hasPendingDatagrams())
{
//数据不为空
datagram.resize( udp_server->pendingDatagramSize() );
//接收数据报
udp_server->readDatagram(datagram.data(),datagram.size(), &client_address, &client_port);
//label->setText(datagram);
QString ip_addr_temp = client_address.toString();//"::ffff:192.168.124.11"
QString ip_addr;
int i = 0;
//填充ip地址
for(i = 7; ip_addr_temp[i] != '\0'; i ++ )
{
ip_addr[i-7] = ip_addr_temp[i];
}
//<receive ip:port>:data
receive_buff += QString("<receive ") + ip_addr + QString(":") + QString::number(client_port) + QString(">:") + datagram.data();
//显示区
ui->receive_buff_textBrowser->setText(receive_buff);
}
}
void MainWindow::on_listen_pushButton_clicked()
{
//readyRead:每当有数据报来时发送这个信号
if(ui->listen_pushButton->text() == "监听")
{
ui->listen_pushButton->setText("断开");
//获取端口号
QString port_buff = ui->udp_server_port_textEdit->document()->toPlainText();
quint16 port_val = (quint16 )port_buff.toInt();
udp_server->bind(port_val,QUdpSocket::ShareAddress);
connect(udp_server,SIGNAL(readyRead()),this,SLOT(udp_server_receive_data()));
}
else
{
ui->listen_pushButton->setText("监听");
udp_server->close();
}
}
void MainWindow::on_send_pushButton_clicked()
{
//获取填写的数据
QString send_buff = ui->send_buff_textEdit->document()->toPlainText();
//获取要发送的客户端ip和端口号
QString client_addr_buff = ui->udp_client_ip_textEdit->document()->toPlainText();
QString client_port_buff = ui->udp_client_port_textEdit->document()->toPlainText();
if(client_addr_buff == "" || client_port_buff == "")
{
QMessageBox::information(nullptr, "Error", "IP或端口号内容不能为空");
return;
}
if(send_buff == "")
{
QMessageBox::information(nullptr, "Error", "内容不能为空");
return;
}
//发送数据
udp_server->writeDatagram(send_buff.toLatin1(),send_buff.size(),QHostAddress(client_addr_buff),client_port_buff.toInt());
}
void MainWindow::on_clear_send_buff_pushButton_clicked()
{
ui->send_buff_textEdit->clear();
}
void MainWindow::on_clear_receive_buff_pushButton_clicked()
{
ui->receive_buff_textBrowser->clear();
}
测试结果:
因为对于UDP程序来说,是没有具体的客户端和服务器角色来说的,所以我们打开一个UDP程序,是既可以扮演客户端和服务器的。
那么,我们执行程序,肯定也是可以完成自发自收的。
实验现象如下;
然后点击监听,然后在数据发送区中填写要发送的数据,然后点击发送,就可以在数据接受区中显示发送的数据了,
自发自收和使用通信猫发送的示意截图:
显示的数据格式为IP +PORT,可以根据自己的喜好进行修改即可。