赞
踩
QUdpSocket * udp_p = new QUdpSocket(this);
- udp_p->bind(src_port);
- udp_p->open(QIODevice::OpenModeFlag::ReadWrite);
bind传入的端口为远程端口
- connect(udp_p, &QUdpSocket::readyRead, this, &UdpComm::DoRecv);
- connect(udp_p, &QUdpSocket::disconnected, this, &UdpComm::DoOnDisconnected);
- connect(udp_p, QOverload<QAbstractSocket::SocketError>::of(&QAbstractSocket::error),
- this, &UdpComm::DoError);
其中DoRecv DoOnDisconnected DoError 我们自己定义的槽函数,当收到数据或者断开连接或者发生错误会触发这三个函数的调用,我们可以在这几个函数处理我们的业务逻辑
- QHostAddress addr(des_ip_);
- res = udp_p->writeDatagram(data, len, addr, des_port_);
- void UdpComm::DoRecv() {
- QByteArray *datagram;
- QHostAddress host;
- quint16 port = 0;
-
- if(udp_p == nullptr )
- {
- qDebug() << "DoRecv error udp_p is null" <<endl;
- return;
- }
-
- if( udp_p->isOpen() == false)
- {
- qDebug() << "DoRecv error udp_p is not open" <<endl;
- return;
- }
-
- datagram = new QByteArray();
- datagram->resize(static_cast<int>(udp_p->pendingDatagramSize()));
-
- qint64 res;
- res = udp_p->readDatagram(datagram->data(),datagram->size(), &host, &port);
-
- if (res < 0) {
- emit onError(ErrorRecv, QString::number(res));
- } else {
- QHostAddress ipv4(host.toIPv4Address());
- received_client_ip_ = ipv4.toString();
- received_client_port_ = port;
- emit onRecv(datagram, received_client_ip_, received_client_port_);
- }
-
- delete datagram;
- }
-
- void UdpComm::DoError(QAbstractSocket::SocketError se) {
- Q_UNUSED(se)
- QString error_str = "unknown error";
- if(udp_p != nullptr) {
- error_str = udp_p->errorString();
- }
- emit onError(ErrorConnection, error_str);
- }
这个方法我们调用 readDatagram方法来接收数据,并且获取发送的IP和地址
QUdpSocket * udp_p = new QUdpSocket(this);
-
- if(!udp_p->bind(local_ip.isEmpty() ? QHostAddress::Any : QHostAddress(local_ip), des_port_))
- {
- QString error = QString("Create socket failed! %1").arg(udp_p->errorString());
- qDebug() << error <<endl;
- udp_p->deleteLater();
- }
- udp_p->open(QIODevice::OpenModeFlag::ReadWrite);udp_p->open(QIODevice::OpenModeFlag::ReadWrite);
绑定端口需要传入参数,第一个参数是本机设备的IP地址,第二个参数是目标地址的端口。
注意:这里第一个IP一定要填写本机的IP,由于电脑端可能会有多个iP的情况,例如虚拟IP 或者 WiFiIP之类的,对于某些IP,广播之后肯能不成功或者接收不到数据,所以可能需要用户在界面上选择本机IP并且进行多次尝试不同的本机IP进行广播。
下面是获取本机IP的方法
- //获取本机IP
- QList<QHostAddress> hostAddressList = QNetworkInterface::allAddresses();
- foreach (QHostAddress address, hostAddressList)
- {
- if (!address.isLoopback() && !address.isMulticast() && address.protocol() == QAbstractSocket::IPv4Protocol) {
- qDebug() << "本机IP " << address.toString() <<endl;
- ui->local_ip->addItem(address.toString());
- }
-
- }
我在这里获取到了本机IP之后加入了选择框可供用户选择,尝试发送广播
- connect(udp_p, &QUdpSocket::readyRead, this, &UdpComm::DoRecv);
- connect(udp_p, &QUdpSocket::disconnected, this, &UdpComm::DoOnDisconnected);
- connect(udp_p, QOverload<QAbstractSocket::SocketError>::of(&QAbstractSocket::error),
- this, &UdpComm::DoError);
- QHostAddress addr(des_ip_);
- res = udp_p->writeDatagram(data, len, addr, des_port_);
注意这里发送的地址一般写死:255.255.255.255 端口就写你要广播的目标端口。当然如果你知道你要广播的地址属于哪个网段,你也可以广播到这个网段.例如:192.168.10.255
- void UdpComm::DoRecv() {
- QByteArray *datagram;
- QHostAddress host;
- quint16 port = 0;
-
- if(udp_p == nullptr )
- {
- qDebug() << "DoRecv error udp_p is null" <<endl;
- return;
- }
-
- if( udp_p->isOpen() == false)
- {
- qDebug() << "DoRecv error udp_p is not open" <<endl;
- return;
- }
-
- datagram = new QByteArray();
- datagram->resize(static_cast<int>(udp_p->pendingDatagramSize()));
-
- qint64 res;
- res = udp_p->readDatagram(datagram->data(),datagram->size(), &host, &port);
-
- if (res < 0) {
- emit onError(ErrorRecv, QString::number(res));
- } else {
- QHostAddress ipv4(host.toIPv4Address());
- received_client_ip_ = ipv4.toString();
- received_client_port_ = port;
- emit onRecv(datagram, received_client_ip_, received_client_port_);
- }
-
- delete datagram;
- }
-
- void UdpComm::DoError(QAbstractSocket::SocketError se) {
- Q_UNUSED(se)
- QString error_str = "unknown error";
- if(udp_p != nullptr) {
- error_str = udp_p->errorString();
- }
- emit onError(ErrorConnection, error_str);
- }
通过上面可以看出正常UDP通信和发送广播有以下区别
1,广播的时候建立连接的时候需要绑定本机的IP,正常通信不需要
2,广播的时候发送给目标地址是固定的 ,一般是255.255.255.255
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。