最近,因为公司的业务需求,需要用到 socket 的 udp 通信协议,特意学习了一下,这里分享给大家。
这里首先给大家介绍一下 QT 的 socket 家族,结构图大致如下图所示:
最主要的是 QAbstractSocket 类,它是 QUdpSocket 和 QTcpSocket 的父类,QTcpSocket 类又包含了两个子类 QSctpSocket 和 QSslSocket。
以下为使用步骤:
//修改之前
QT += core gui
//修改之后
QT += core gui network
#include
QUdpSocket* send_udp = new QUdpSocket(this);
QUdpSocket* receive_udp = new QUdpSocket(this);
//设置接收监听地址和端口,这里用的是本机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);
}
}
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);
学习分享,一起成长!接触QT的时间不长,目前差不多有两个月了,有不足之处,欢迎大佬指出来,我会进行更正。有问题可以发送邮件至 [email protected] ,不定时上线查收。