测试环境:linux操作系统电脑一台,Windows操作系统电脑一台,QT
Windows下QT实现UDP加入组播
QUdpSocket udpSocket;
QHostAddress groupAddress("范围内组播IP");
//绑定本地IP
udpSocket.bind(QHostAddress::AnyIPv4, 6888);
//加入组播组
udpSocket.joinMulticastGroup(groupAddress);
注意:
在IPv4网络中,组播IP地址范围是224.0.0.0到239.255.255.255,其中第一个字节的范围是224到239。
QHostAddress::AnyIPv4是将udpSocket绑定到本地所有可用的IPv4地址上的端口6888,需要绑定固定IP的的可以将QHostAddress::AnyIPv4替换成自己电脑已有的IP。
Linux下QT实现UDP加入组播
QUdpSocket *udpSocket;
//组播地址
QHostAddress MulticastAddr1(multicastAddr);
//组播端口
quint16 MulticastPort1 = multicastPort;
//绑定组播IP
udpSocket->bind(MulticastAddr1,MulticastPort1,QUdpSocket::ShareAddress);
//加入组播1
udpSocket->joinMulticastGroup(MulticastAddr1);
注意:
很多小伙伴,可能再实现开始可能会先绑定自身的IP,再加入组播组可能会导致收不到组播数据的情况,当你使用bind函数将套接字绑定到固定的IP地址时,该套接字只会接收目标IP为该固定IP的数据包。它不会接收其他IP地址发送的数据包,包括组播地址。
而当您直接使用joinMulticastGroup函数将套接字加入到组播组时,系统会自动将套接字绑定到相应的组播IP地址和端口上,以接收来自该组播地址的数据包。
换句话说,如果在绑定固定的IP之后再尝试接收组播数据,那么套接字只能接收该固定IP的数据包,而无法接收组播地址的数据包。
因此,在Linux中要接收组播数据,应该直接将套接字绑定到组播地址和相应的端口,而不是先绑定固定IP再加入组播组。这样才能接收到来自组播地址的数据包。
UDP数据接收实现
while(true)
{
//判断UDP套接字是否有待处理的数据报的函数
if (udpSocket->hasPendingDatagrams())
{
//定义一个QByteArray对象receiveData,用于存储接收到的数据报
QByteArray receiveData;
//调整receiveData的大小,使其与接收缓冲区中待处理数据报的大小相匹配。这段代码通过udpSocket->pendingDatagramSize()函数获取待处理数据报的大小,并将receiveData的大小设置为相同
receiveData.resize(udpSocket->pendingDatagramSize());
//使用readDatagram()函数从UDP套接字中读取数据报,并将其存储到receiveData中。这段代码将数据报的内容读取到receiveData.data()所指向的内存位置,数据报的大小为receiveData.size()。同时,该代码还提供了两个引用参数(地址和端口)用于返回数据报的发送方地址和端口信息
udpSocket->readDatagram(receiveData.data(), receiveData.size(),&senderAddr, &senderPort);
//这里由于自身需要,将receiveData的数据转换为const uint8_t类型的指针receiveBuffer。constData()函数返回const char类型指向receiveData数据的指针,并通过reinterpret_cast将其转换为const uint8_t*类型的指针。
const uint8_t* receiveBuffer = reinterpret_cast<const uint8_t*>(receiveData.constData());
size_t receiveBufferSize = receiveData.size();
}
}
注意:
1.这里小伙伴可以不使用while(true)的方式,可以使用触发事件,当有数据时才进行接收数据处理,我主要是图个快(这样特别耗费资源)。
2.发送数据的时候要注意发送的端口要和自身绑定的组播端口一致,不然也接收不到数据。
3.注意之前使用QHostAddress::AnyIPv4绑定的小伙伴需要注意,检查自己发送UDP数据的时候绑定的IP是否和目标IP在同一网段,不然可能会出现,调用发送IP与目的IP不在同一网段(建议禁用自己的无线网卡和虚拟网卡,在有线网卡上配置对应的IP)。
Linux配置路由:
在配置组播通信时建议先添加组播路由,不然依然可能收不到仍和数据:
路由配置指令:
sudo ip route add <组播地址>/<前缀地址长度> dev <网络接口>
例如:配置224.111.111.100
sudo ip route add 224.111.111.100/32 dev enp1s0
路由查询指令:
ip route
检查配置路由配置成功后,就可以开始调试啦!!