组播地址
组播需要使用组播地址,在IPv4 中它的范围从 224.0.0.0 到 239.255.255.255,并被划分为局部链接多播地址、预留多播地址和管理权限多播地址三类,如下图:
UDP组播通信流程
1.初始化 QUdpSocket *s_udpsSocket;
工程.pro文件中加入 QT += network
2.绑定本地Ipv4 IP地址、端口号:bind();
3.绑定QUdpSocket 信号槽函数 :readyRead();
4.加入UDP组播组 joinMulticastGroup();
5.数据发送:writeDatagram();
6.数据接收:readDatagram();
7.离开组播组:leaveMulticastGroup();
8.关闭UDP连接:abort();
实现过程
加入组播:
//组播地址
static QHostAddress mcast_addr("239.0.0.1");
static quint16 listen_port=8080;
static quint16 send_port=8081;
void UdpTestDemo::on_open_port_button_clicked()
{
bool ok;
if(1 == time)
{
ui->open_port_button->setText("打开端口");
if(this->s_udpsSocket->state() == QAbstractSocket::BoundState)
{
this-> s_udpsSocket->leaveMulticastGroup(mcast_addr);//加入组播组ip
this->s_udpsSocket->abort();
ui->open_port_button->setText("打开端口");
}
time=0;
}
else
{
time=1;
ui->open_port_button->setText("关闭端口");
if(!this->s_udpsSocket)
this->s_udpsSocket = new QUdpSocket();
QString ip=ui->Ip_addr_dis->currentText();
ok=this->s_udpsSocket->bind(QHostAddress(ip),listen_port,QUdpSocket::ShareAddress|QUdpSocket::ReuseAddressHint);
if(ok)//绑定所有ip来接收组播组信息
{
this-> s_udpsSocket->setSocketOption(QAbstractSocket::ReceiveBufferSizeSocketOption,1024*1024*8);//设置缓冲区
this-> s_udpsSocket->setSocketOption(QAbstractSocket::MulticastLoopbackOption,1);
this->s_udpsSocket->joinMulticastGroup(QHostAddress(mcast_addr));//加入组播组ip
connect(s_udpsSocket,SIGNAL(readyRead()),this,SLOT(RecvData()));
// QMessageBox::information(NULL, "端口绑定提示", "绑定端口成功 ");
if(this->s_udpsSocket->state() == QAbstractSocket::BoundState)
{
qInfo() << "加入组播组成功!";
}
}
else
{
// QMessageBox::information(NULL, "端口绑定提示", "绑定端口失败 ");
messageBox->setWindowTitle("端口绑定提示");
messageBox->setText("绑定端口失败");
messageBox->show();
}
}
}
数据接收:
void UdpTestDemo::RecvData()
{
//数据报到来,readyRead()信号被产生,此时hasPendingDatagrams()函数返回真(true)。
//调用pendingDatagramSize()获取第一个数据报的长度(size),readDatagram()读取数据报内容
while (s->s_udpsSocket->hasPendingDatagrams())
{
this->datagram_rec.resize(s->s_udpsSocket->pendingDatagramSize());
s->s_udpsSocket->readDatagram(this->datagram_rec.data(),datagram_rec.size());
qDebug()<<"receive data:"+this->datagram_rec<<endl;
}
}
数据发送:
this->s_udpsSocket->writeDatagram( str.toUtf8(),mcast_addr,send_port);
退出组播,关闭连接:
if(s_udpsSocket)
{
if( s->s_udpsSocket->state() == QAbstractSocket::BoundState)
{
s->s_udpsSocket->leaveMulticastGroup(mcast_addr);
s->s_udpsSocket->abort();}
}