You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android设备QNetwork接收UDP广播延迟异常问题求助

问题:华为Android设备接收局域网UDP广播延迟固定785秒

我需要在华为Android设备上接收同局域网内其他设备发送的UDP广播。发送端已通过局域网内电脑的tcpdump验证会立即发送UDP数据包,但Android端绑定的QUdpSocket要等待约785秒才会触发readReady信号,且每个数据包的延迟时长完全一致。

使用环境:Qt 6.4、IBM-jdk-11.0.17+8、SDK android-31、NDK25.1.8937393,设备为华为手机(更换不同版本的Qt、JDK、SDK和NDK后问题依旧)。

编译无任何错误或警告,怀疑是华为设备的防火墙限制,或是需要在AndroidManifest中添加特殊权限,求解决方案。

(注:发送端发送的UDP数据包包含发送时间,格式为"hh:mm:ss")


测试项目代码

UdpClient.pro

TEMPLATE     = app
QT          += widgets network
SOURCES      = main.cpp \
               UdpClient.cpp
HEADERS      = UdpClient.h
windows:TARGET = ../UdpClient

UdpClient.h

#pragma once
#include <QTextEdit>
class QUdpSocket;
class UdpClient : public QTextEdit {
Q_OBJECT
private:
    QUdpSocket* m_pudp;
public:
    UdpClient(QWidget* pwgt = 0);
private slots:
    void slotProcessDatagrams();
};

main.cpp

#include <QApplication>
#include "UdpClient.h"
int main(int argc, char** argv)
{
    QApplication app(argc, argv);
    UdpClient    client;
    client.show();
    return app.exec();
}

UdpClient.cpp

#include <QtNetwork>
#include <QtGui>
#include "UdpClient.h"
UdpClient::UdpClient(QWidget* pwgt /*=0*/) : QTextEdit(pwgt)
{
    setWindowTitle("UdpClient");
    m_pudp = new QUdpSocket(this);
    m_pudp->bind(QHostAddress::AnyIPv4, 49100, QUdpSocket::ShareAddress);
    connect(m_pudp, SIGNAL(readyRead()), SLOT(slotProcessDatagrams()));
    append("Test UDP bind:");
}
void UdpClient::slotProcessDatagrams()
{
    QByteArray baDatagram;
    do {
        baDatagram.resize(m_pudp->pendingDatagramSize());
        m_pudp->readDatagram(baDatagram.data(), baDatagram.size());
    } while(m_pudp->hasPendingDatagrams());
    QDateTime dateTime;
    QTime   Time;
    qint64   i_dTime;
    QTime   sentTime;
    dateTime = QDateTime::currentDateTime();
    Time = dateTime.time();
    sentTime = QTime::fromString(QString::fromUtf8(baDatagram) ,"hh:mm:ss");
    i_dTime = sentTime.secsTo(Time);
    append("R"+ QString::number(baDatagram.size()) + "b:" + Time.toString("hh:mm:ss") + "-" + QString(baDatagram) + "=" + QString::number(i_dTime));
}

解决方案

1. 补充AndroidManifest权限

在AndroidManifest.xml中添加必要的网络权限:

<!-- 基础网络访问权限 -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- 获取网络状态权限 -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- Android 10+ 访问局域网设备必需的位置权限 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

注意:Android 10及以上版本,ACCESS_FINE_LOCATION需要动态申请,否则无法正常接收局域网广播。

2. 调整QUdpSocket绑定参数

修改绑定代码,添加ReuseAddressHint参数,同时加入组播(如果是组播类广播):

// 更新绑定逻辑
m_pudp->bind(QHostAddress::AnyIPv4, 49100, QUdpSocket::ShareAddress | QUdpSocket::ReuseAddressHint);
// 加入对应组播地址(示例为通用组播地址,替换为实际地址)
m_pudp->joinMulticastGroup(QHostAddress("224.0.0.1"));

3. 关闭华为设备省电优化

华为的省电策略会限制后台应用的网络活动,导致UDP数据包被延迟:

  • 进入「设置」→「电池」→关闭「省电模式」
  • 进入「应用启动管理」,找到你的应用,设置为「允许后台活动」
  • 进入「电池优化」,将你的应用设为「不允许」

4. 解除华为网络拦截限制

检查华为自带的网络管理工具是否拦截了UDP端口:

  • 打开「手机管家」→「流量管理」→「应用联网」,确保应用允许WLAN联网
  • 进入「防火墙」(部分机型在手机管家/安全中心内),添加UDP 49100端口的放行规则

5. 确认广播地址正确性

发送端尽量使用局域网段的广播地址(如192.168.x.255),避免使用全局广播地址255.255.255.255,部分Android设备对全局广播支持有限。

6. 初始化Qt网络配置

在main.cpp中添加网络配置初始化代码,确保Qt网络模块在Android上正常工作:

#include <QNetworkConfigurationManager>

int main(int argc, char** argv)
{
    QApplication app(argc, argv);
    // 初始化网络配置
    QNetworkConfigurationManager manager;
    QNetworkConfiguration config = manager.defaultConfiguration();
    manager.setConfiguration(config);
    
    UdpClient    client;
    client.show();
    return app.exec();
}

内容的提问来源于stack exchange,提问作者ovzap

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 20:10:26