在 Qt 中实现 UDP 组播,可以使用
QUdpSocket
类进行发送和接收。
创建发送端
实现步骤:
- 创建一个
QUdpSocket
对象。 - 设置组播地址和端口。
- 使用
writeDatagram
方法发送数据到组播地址。
发送端代码示例:
#include <QCoreApplication>
#include <QUdpSocket>
#include <QHostAddress>
#include <QTimer>
class MulticastSender : public QObject {
Q_OBJECT
public:
MulticastSender(QObject *parent = nullptr) : QObject(parent) {
udpSocket = new QUdpSocket(this);
multicastAddress = QHostAddress("224.0.0.1"); // 组播地址
port = 45454; // 组播端口
// 定时发送数据
QTimer *timer = new QTimer(this);
connect(timer, &QTimer::timeout, this, &MulticastSender::sendMessage);
timer->start(1000); // 每秒发送一次
}
private slots:
void sendMessage() {
QByteArray datagram = "Hello, Multicast!";
udpSocket->writeDatagram(datagram, multicastAddress, port);
qDebug() << "Sent: " << datagram;
}
private:
QUdpSocket *udpSocket;
QHostAddress multicastAddress;
quint16 port;
};
int main(int argc, char *argv[]) {
QCoreApplication app(agrc, argv);
MulticastSender sender;
return app.exec();
}
创建接收端
实现步骤:
- 创建一个
QUdpSocket
对象并绑定到指定端口。 - 使用
joinMulticastGroup
方法加入组播组。 - 监听
readyRead
信号,当有数据到来时,使用readDatagram
读取数据。
接收端代码示例:
#include <QCoreApplication>
#include <QUdpSocket>
#include <QHostAddress>
class MulticastReceiver : public QObject {
Q_OBJECT
public:
MulticastReceiver(QObject *parent = nullptr) : QObject(parent) {
udpSocket = new QUdpSocket(this);
port = 45454; // 组播端口
// 绑定端口并加入组播组
if(udpSocket->bind(QHostAddress::AnyIPv4, port, QUdpSocket::ShareAddress)) {
qDebug() << "Bound to port" << port;
QHostAddress multicastAddress("244.0.0.1");
if(udpsocket->joinMulticastGroup(multicastAddress)) {
qDebug() << "Joined multicast group" << multicastAddress.toString();
} else {
qWarning() << "Failed to join multicast group";
}
} else {
qWarning() << "Failed to bind socket";
}
connect(udpSocket, &QUdpSocket::readyRead, this, &MulticastReceiver::processPendingDatagrams);
}
private slots:
void processPendingDatagrams() {
while(udpSocket->hasPendingDatagrams()) {
QByteArray datagram;
datagram.resize(udpSocket->pendingDatagramSize());
QHostAddress sender;
quint16 senderPort;
udpSocket->readDatagram(datagram.data(), datagram.size(), &sender, &senderPort);
qDebug() << "Received:" << datagram << "from" << sender.toString() << ":" << senderPort;
}
}
private:
QUdpSocket *udpSocket;
quint16 port;
};
int main(int argc, char *argv[]) {
QCoreApplication app(argc, argv);
MulticastReceiver receiver;
return app.exec();
}
注意事项
- 组播地址范围:
- IPv4 的有效范围是
224.0.0.0
到239.255.255.255
。 - 避免使用
224.0.0.x
,因为它是保留范围。
- 网络接口:
- 如果有多个网络接口(如 Wi-FI 和以太网),需要显式指定接口。
- 使用
setMulticastInterface
方法指定网络接口:
udpSocket->setMulticastInterface(QNetworkInterface::interfaceFromName("eth0"));
- TTL 配置:
- 默认情况下,组播包的 TTL 是 1,仅限本地网络。
- 修改 TTL 方法:
udpSocket->setSocketOption(QAbstractSocket::MulticastTtlOption, 5);
- 防火墙与路由器:
- 确保防火墙和路由器允许组播流量。
- 调试工具:
- 使用 Wireshark 抓包工具验证组播包是否成功发送和接收。
使用线程实现UDP组播请看后续文章。