Sorry, your browser cannot access this site
This page requires browser support (enable) JavaScript
Learn more >

Gray-Ice

个人博客兼个人网站

先看效果图:

使用QUdpSocket需要在项目的.pro文件里加上:

1
QT += network

QUdpSocket通信的步骤如下: 绑定端口,收消息/发消息。
那么看代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#include "serverwidget.h"
#include "ui_serverwidget.h"

ServerWidget::ServerWidget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::ServerWidget)
, socket(nullptr)
{
ui->setupUi(this);
// socket是一个QUdpSocket类型的指针
socket = new QUdpSocket(this);
// 设置绑定9997端口
socket->bind((quint16)8887);
setWindowTitle("port 8887");
// 当有数据可读取时,触发readyRead信号,然后转到自定义的dealmsg槽函数
connect(socket, &QUdpSocket::readyRead, this, &ServerWidget::dealmsg);
// 当发送信息按钮的clicked事件触发时,转到自定义的sendmsg槽函数
connect(ui->sendButton, &QPushButton::clicked, this, &ServerWidget::sendmsg);
}

ServerWidget::~ServerWidget()
{
delete ui;
}

void ServerWidget::dealmsg()
{
// 定义buffer用来读取数据
char buffer[1024];
// 用0填充buffer
memset(buffer, 0, 1024);
// QHostAddress类型的变量ip和quint16类型的变量port分别用来接收ip地址和端口号。
QHostAddress ip;
quint16 port;
// readDatagram如果成功返回一个大小的值,如果失败返回-1
auto mlen = socket->readDatagram(buffer, 1024, &ip, &port);
// 判断是否读取成功
if(mlen > 0)
{
// 格式化字符串
QString qs = QString("[%1:%2]:%3").arg(ip.toString()).arg(port).arg(buffer);
// 展示字符串
ui->textEdit->append(qs);
}
else
ui->textEdit->append("Read a shit.");
}

void ServerWidget::sendmsg()
{
// 获取用户输入的ip(这几行变量名都起的比较随意,所以请仔细看注释)
QString qs = ui->ipLine->text();
// 用QString类型的ip初始化QHostAddress对象
QHostAddress qh(qs);
// 获取用户输入的端口号
quint16 port = ui->portLine->text().toUInt();
// 获取用户输入的内容
QString msg = ui->textEdit_2->toPlainText();
// 向指定ip发送内容。第一个参数是转化成QByteArray的QString
// 返回发送成功的字节。如果发送失败,返回-1
auto result = socket->writeDatagram(msg.toUtf8(), qh, port);
if(result < 0)
ui->textEdit->append("Send Error.");
else
ui->textEdit->append("Send Success.");
}

然后这是头文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#ifndef SERVERWIDGET_H
#define SERVERWIDGET_H

#include <QWidget>
#include <QHostAddress>
#include <QUdpSocket>

QT_BEGIN_NAMESPACE
namespace Ui { class ServerWidget; }
QT_END_NAMESPACE

class ServerWidget : public QWidget
{
Q_OBJECT

public:
ServerWidget(QWidget *parent = nullptr);
~ServerWidget();
void dealmsg();
void sendmsg();

private:
Ui::ServerWidget *ui;
QUdpSocket* socket; // udp socket
};
#endif // SERVERWIDGET_H

写完之后如何做到效果图中的效果呢?先运行一个程序,该程序的端口号为8887,然后修改代码,把端口号改成8888,就能实现效果图中的效果了。
然后是关于组播与广播了。想要广播的话用户直接输入255.255.255.255再指定ip即可。
组播的话有点麻烦,需要改一下绑定:

1
2
3
4
// 任意ip地址。本地端口为8887
socket->bind(QHostAddress::AnyIPv4, (quint16)8887);
// 加入组播组244.0.0.1
socket->joinMulticastGroup(QHostAddress("244.0.0.1"));

然后用户把ip指定为244.0.0.1,端口指定为要接收这个信息的端口即可。假如ip指定了244.0.0.1,端口指定为8888,那么所有绑定了8888端口且加入了244.0.0.1组的UDP套接字都会收到消息。
若是想要离开组的话,使用这段代码:

1
socket->leaveMulticastGroup(QHostAddress("244.0.0.1"));

本篇完。

评论



愿火焰指引你