通俗易懂玩QT:QUdpSocket学习

QT之QUdpSocket学习

最近,因为公司的业务需求,需要用到 socket 的 udp 通信协议,特意学习了一下,这里分享给大家。

一、QT 的 socket 家族

这里首先给大家介绍一下 QT 的 socket 家族,结构图大致如下图所示:
QT之socket家族

最主要的是 QAbstractSocket 类,它是 QUdpSocket 和 QTcpSocket 的父类,QTcpSocket 类又包含了两个子类 QSctpSocket 和 QSslSocket。

二、QUdpSocket 的使用

以下为使用步骤:

  1. 在 pro 或者 pri文件中引入QT 的 network 网络模块:
//修改之前
QT       += core gui
//修改之后
QT       += core gui network
  1. 在文件头部或者头文件中引入 QUdpSocket 模块:
#include<QUdpSocket>
  1. 定义两个 QUdpSocket 指针对象,并初始化:
QUdpSocket* send_udp = new QUdpSocket(this);
QUdpSocket* receive_udp = new QUdpSocket(this);
  1. 使用 udp 协议接收数据,用的 qDebug() 将接收到的数据打印到终端,这里提供两种方式:
    方法一:使用 receiveDatagram() 函数接收数据,接收到的中文数据需要解码,否则为16进制数据(该方法接收到的数据容错率极低,近乎为0)
//设置接收监听地址和端口,这里用的是本机ip
receive_udp -> bind(QHostAddress::LocalHost, 8088);
//绑定监听事件
connect(receive_udp, &QUdpSocket::readyRead, [this](){
	while (receive_udp -> hasPendingDatagrams()) {
		datagram = receive_udp -> receiveDatagram();
		QTextCodec *utf8 = QTextCodec::codecForName("UTF-8");
		qDebug() << utf8 -> toUnicode(datagram.data());
	}
});

方法二:使用 readDatagram() 和 pendingDatagramSize() 函数接收数据,接收到的数据无需解码即可使用(该方法接收到的数据容存在一定的容错率,虽然也能完全接受数据,但是在接收到的数据后方有时存在一些乱码信息)

//设置接收监听地址和端口,这里用的是本机ip
receive_udp -> bind(QHostAddress::LocalHost, 8088);
//绑定监听事件
connect(receive_udp, &QUdpSocket::readyRead, [this](){
	while (receive_udp -> hasPendingDatagrams()) {
		int size = int(receive_udp -> pendingDatagramSize());
		char* pBuffer = new char[size + 1];//分配报文大小的内存
		memset(pBuffer, 0, size + 1);
		receive_udp -> readDatagram(pBuffer, size);
		qDebug() << pBuffer;
	}
});

官方推荐使用用法:

void Server::initSocket() {
    udpSocket = new QUdpSocket(this);
    udpSocket -> bind(QHostAddress::LocalHost, 7755);

    connect(udpSocket, SIGNAL(readyRead()), this, SLOT(readPendingDatagrams()));
}

void Server::readPendingDatagrams() {
    while (udpSocket->hasPendingDatagrams()) {
        QByteArray datagram;
        //这里最好用 long 包含一下udpSocket -> pendingDatagramSize(),否则会有警告
        datagram.resize(udpSocket -> pendingDatagramSize());
        QHostAddress sender;
        quint16 senderPort;
        udpSocket -> readDatagram(datagram.data(), datagram.size(), &sender, &senderPort);
        processTheDatagram(datagram);
    }
}
  1. 使用 udp 协议发送数据:
QString s = "";//字符串的类型可以根据需要自行定义
//writeDatagram(const char * data, qint64 size, const QHostAddress & address, quint16 port)
//该方式发送数据,接收到的中文乱码且解码后少字
send_udp -> writeDatagram(s.toStdString().c_str(), s.length(), QHostAddress::LocalHost, 8088);
//writeDatagram(const QByteArray & datagram, const QHostAddress & host, quint16 port)
//需要发中文,建议使用以下方式
send_udp -> writeDatagram(s.toUtf8(), QHostAddress::LocalHost, 8088);
  1. 这里有一个写好的案例可以参考 BDYSocket.zip效果图1
    效果图2

三、注意事项

  1. 监听端口最好使用 1024 以上的,1024 以下的一般都是给系统用的;
  2. 发送中文数据用 QByteArray 类型数据,使用字符数组接收会乱码;
  3. 使用 receiveDatagram() 函数接收中文数据时,需要对数据进行解码,否则出来的是十六进制数据;
  4. 使用 UDP 协议收发数据注意一定要先开启接收监听,然后在发送数据,否则收不到数据的。

学习分享,一起成长!接触QT的时间不长,目前差不多有两个月了,有不足之处,欢迎大佬指出来,我会进行更正。有问题可以发送邮件至 mjzhutianxiu@163.com ,不定时上线查收。

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我是混子我怕谁

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值