鸿蒙新特性:@ohos.net.connection 网络连接诊断实验室实战 —— 网络检测、带宽查询与 DNS 解析
引言
网络是移动应用的命脉。在开发中,我们需要知道设备当前是否联网、连接的是 WiFi 还是蜂窝网络、带宽多少、DNS 解析是否正常。HarmonyOS NEXT 通过 @ohos.net.connection 模块将这些网络诊断能力统一暴露为简洁的同步与异步 API,大部分操作无需权限即可使用。
@ohos.net.connection 属于 @kit.NetworkKit,与 Android 的 ConnectivityManager 和 iOS 的 NWPathMonitor 定位类似,但 API 设计更加直接——核心检测全部同步返回,DNS 解析通过 Promise 异步完成,没有复杂的事件订阅机制。
本文将深入讲解 @ohos.net.connection 的网络状态检测、带宽查询、承载类型识别和 DNS 域名解析四大核心能力,并构建一个"网络连接诊断实验室"Demo,在一个页面中完成网络诊断的全部操作。
一、API 架构:同步检测 + 异步解析
1.1 核心设计理念
@ohos.net.connection 的 API 分为两层:同步层负责网络状态检测和能力查询——所有方法都带 Sync 后缀,直接返回结果,零延迟;异步层负责 DNS 域名解析——通过 Promise 返回解析结果,适合耗时网络操作。
import connection from '@ohos.net.connection';
// 同步:瞬间返回,无需 await
const hasNet = connection.hasDefaultNetSync(); // boolean
const netHandle = connection.getDefaultNetSync(); // NetHandle
const caps = connection.getNetCapabilitiesSync(netHandle); // NetCapabilities
// 异步:Promise 返回
connection.getAddressesByName('www.example.com')
.then((addrs) => { /* Array<NetAddress> */ })
.catch((e) => { /* Error */ });
这种"同步检测 + 异步解析"的双层设计非常务实:连接检测是高频操作(每次网络请求前都需要判断),同步 API 避免不必要的异步开销;DNS 解析本身涉及网络 I/O,异步 Promise 模型正合适。
1.2 hasDefaultNetSync —— 网络连接检测
hasDefaultNetSync() 是网络诊断中最基础的 API。它同步返回一个 boolean,表示当前是否存在默认数据网络。这个方法无参数、无权限要求,适合在任何地方调用。
private refreshNetState(): void {
try {
const hasNet = connection.hasDefaultNetSync();
this.isConnected = hasNet;
if (hasNet) {
// 有默认网络,进一步获取详细信息
const netHandle = connection.getDefaultNetSync();
const caps = connection.getNetCapabilitiesSync(netHandle);
// ... 读取带宽、承载类型等
} else {
// 无网络连接
this.bearerType = '无连接';
}
} catch (e) {
this.isConnected = false;
// 异常降级:假设无网络
}
}
关键点:
- 返回
true仅表示系统存在默认数据网络路由,不代表目标服务器可达 - 配合
@ohos.net.http使用时,hasDefaultNetSync()可以作为请求前的快速检查 - 必须在 try/catch 中调用,SDK 内部可能因系统服务异常而抛出错误
1.3 getDefaultNetSync —— 获取默认网络句柄
当 hasDefaultNetSync() 返回 true 时,可以通过 getDefaultNetSync() 获取当前默认网络的 NetHandle 对象。NetHandle 是一个不透明的网络句柄,本身没有可读属性,它的作用是为 getNetCapabilitiesSync() 提供参数。
const netHandle = connection.getDefaultNetSync();
// netHandle 是一个 NetHandle 对象,用于后续查询
const caps = connection.getNetCapabilitiesSync(netHandle);
NetHandle 的设计类似于文件描述符——它本身不暴露细节,但可以作为钥匙打开对应的能力信息。
1.4 getNetCapabilitiesSync —— 网络能力信息
getNetCapabilitiesSync(netHandle) 是网络诊断的核心 API。它接收一个 NetHandle,返回一个 NetCapabilities 对象,包含当前网络的完整能力描述:
| 属性 | 类型 | 说明 |
|---|---|---|
| linkDownBandwidthKbps | number | 下行带宽(kbps),可能为 0 或 undefined |
| linkUpBandwidthKbps | number | 上行带宽(kbps),可能为 0 或 undefined |
| bearerTypes | Array<number> | 承载类型数组,每个元素为 BearerType 枚举值 |
注意:linkDownBandwidthKbps 和 linkUpBandwidthKbps 的值取决于底层网络驱动是否提供了带宽信息。在模拟器或某些网络环境下,这两个值可能为 0 或 undefined,需要做防御性处理。
const caps = connection.getNetCapabilitiesSync(netHandle);
const downBw = caps.linkDownBandwidthKbps;
const upBw = caps.linkUpBandwidthKbps;
// 防御性处理:带宽值为空或 0 时显示占位符
this.downBand = (downBw !== undefined && downBw > 0) ?
(downBw / 1000).toFixed(1) + ' Mbps' : '--';
this.upBand = (upBw !== undefined && upBw > 0) ?
(upBw / 1000).toFixed(1) + ' Mbps' : '--';
1.5 bearerTypes —— 承载类型识别
bearerTypes 是 NetCapabilities 中最实用的字段。它返回一个数字数组,每个数字代表一种网络承载类型(BearerType 枚举):
| 值 | 承载类型 | 说明 |
|---|---|---|
| 0 | WiFi | IEEE 802.11 无线局域网 |
| 1 | 蜂窝网络 | 4G/5G 移动网络 |
| 2 | VPN | 虚拟专用网络 |
| 3 | 以太网 | 有线网络连接 |
一个网络连接可能同时具有多种承载类型(例如 VPN over WiFi)。在实际使用中,bearerTypes[0] 通常是主承载类型。
private bearerLabel(type: number): string {
if (type === 0) return 'WiFi';
if (type === 1) return '蜂窝网络';
if (type === 2) return 'VPN';
if (type === 3) return '以太网';
return '其他';
}
// 使用
const bt = caps.bearerTypes;
if (bt && bt.length > 0) {
this.bearerType = this.bearerLabel(bt[0] as number);
} else {
this.bearerType = '未知';
}
二、DNS 域名解析
2.1 getAddressesByName —— 异步 DNS 查询
getAddressesByName(host: string) 是 @ohos.net.connection 提供的 DNS 解析 API。它接收一个域名字符串,返回 Promise<Array<NetAddress>>。每个 NetAddress 对象包含三个字段:
| 属性 | 类型 | 说明 |
|---|---|---|
| address | string | IP 地址字符串(IPv4 或 IPv6 格式) |
| family | number | 协议族(1 = IPv4,2 = IPv6) |
| port | number | 端口号(DNS 查询中通常为 0) |
private resolveDNS(): void {
const host = this.dnsHost.trim();
if (host === '') {
this.addLog('请输入域名', 'error');
return;
}
this.dnsLoading = true;
this.dnsResult = '解析中...';
connection.getAddressesByName(host)
.then((addrs: Array<connection.NetAddress>) => {
this.dnsLoading = false;
if (addrs.length > 0) {
const ipList: string[] = [];
for (let i = 0; i < addrs.length; i++) {
ipList.push(addrs[i].address);
}
this.dnsResult = ipList.join('\n');
this.addLog('DNS: ' + host + ' → ' +
addrs.length.toString() + ' 个地址', 'success');
} else {
this.dnsResult = '未解析到地址';
this.addLog('DNS: ' + host + ' 无记录', 'system');
}
})
.catch((e: Error) => {
this.dnsLoading = false;
this.dnsResult = '解析失败: ' + e.message;
this.addLog('DNS 失败: ' + e.message, 'error');
});
}
DNS 解析的完整流程:
- 用户输入域名(如
www.example.com) - 调用
getAddressesByName(host)发起系统级 DNS 查询 - 系统返回所有解析到的 IP 地址(可能有多个,包括 IPv4 和 IPv6 地址)
- 遍历
NetAddress数组,提取address字段展示
2.2 DNS 解析的实际意义
在网络诊断场景中,DNS 解析是判断"网络是否真正可用"的重要依据。hasDefaultNetSync() 返回 true 只说明设备有网络连接,而 DNS 解析成功才说明 DNS 服务器可达、域名可以正常解析。这两个检查配合使用,可以准确定位网络问题:
hasDefaultNetSync()= false → 设备无网络连接,检查 WiFi/蜂窝开关hasDefaultNetSync()= true 但 DNS 解析失败 → 网络已连接但 DNS 不通,检查路由器/DNS 配置- 两者都正常 → 网络连通性良好


三、实战 Demo:网络连接诊断实验室
3.1 页面设计
"网络连接诊断实验室"页面分为五个功能区域:
-
连接状态卡片:最上方展示当前网络连接状态(绿色圆点 + "已连接"或红色圆点 + “未连接”),右侧显示承载类型标签(WiFi / 蜂窝网络 / VPN / 以太网)。下方三栏卡片分别展示下行带宽、上行带宽和承载类型。
-
网络操作区:两个按钮——"刷新网络状态"重新读取当前网络信息,"检测连接"调用
hasDefaultNetSync()并在日志中输出结果。 -
DNS 域名解析区:文本输入框 + "解析"按钮,下方三个预设域名快捷按钮(example.com、baidu.com、github.com),点击后自动填入域名并执行解析。解析结果显示在底部灰色代码框中,支持多行展示。
-
API 能力说明区:以灰色文字展示核心 API 的方法签名和功能说明,帮助开发者快速了解模块能力。
-
操作日志区:按时间倒序记录所有操作,不同类别(success / error / system)使用不同颜色标记。
3.2 核心实现
数据模型:
interface ConnLog {
time: string;
msg: string;
category: string;
}
@State isConnected: boolean = false;
@State bearerType: string = '--';
@State downBand: string = '--';
@State upBand: string = '--';
@State dnsHost: string = 'www.example.com';
@State dnsResult: string = '--';
@State dnsLoading: boolean = false;
@State logs: ConnLog[] = [];
状态设计要点:
isConnected控制连接状态的 UI 颜色和文字bearerType在三种场景下取值不同:正常连接时显示承载标签,无连接时显示"无连接",异常时显示"–"dnsLoading同时控制按钮文字和禁用状态,防止重复点击logs使用ConnLog接口统一日志格式,包含时间戳、消息内容和分类
日志系统:
private addLog(msg: string, category: string): void {
const now = new Date();
const ts = now.getHours().toString().padStart(2, '0') + ':' +
now.getMinutes().toString().padStart(2, '0') + ':' +
now.getSeconds().toString().padStart(2, '0');
const entry: ConnLog = { time: ts, msg: msg, category: category };
const newLogs: ConnLog[] = [entry];
this.logs = newLogs.concat(this.logs).slice(0, 30);
}
日志采用"新在前、旧在后"的顺序(newLogs.concat(this.logs)),最多保留 30 条记录。时间格式化为 HH:MM:SS 并补零对齐。
日志颜色函数:
private logColor(cat: string): string {
if (cat === 'success') return '#10B981';
if (cat === 'error') return '#EF4444';
return '#64748B';
}
统计卡片 Builder:
@Builder
statCard(label: string, value: string, color: string) {
Column() {
Text(label)
.fontSize(10).fontColor('#94A3B8').margin({ bottom: 4 })
Text(value)
.fontSize(13).fontColor(color)
.fontWeight(FontWeight.Bold).fontFamily('monospace')
}
.alignItems(HorizontalAlign.Center)
.layoutWeight(1)
.padding({ top: 8, bottom: 8 })
.backgroundColor('#F8FAFC').borderRadius(8)
.border({ width: 1, color: '#E2E8F0' })
.margin({ right: 8 })
}
3.3 交互方式
Demo 提供三个核心交互点:
-
刷新网络状态:单击按钮后重新执行
refreshNetState(),读取最新的网络连接状态、带宽数据和承载类型。适合在切换 WiFi / 移动网络后验证。 -
检测连接:直接调用
hasDefaultNetSync()并输出结果到日志。这是一个最轻量的网络检查操作。 -
DNS 域名解析:输入域名后点击"解析"按钮,或点击预设域名快捷按钮(example.com / baidu.com / github.com)直接触发解析。解析过程中按钮变为灰色"解析中…"并禁用,防止重复提交。解析结果按行展示所有 IP 地址。
四、实际应用场景
4.1 网络请求前的连通性检查
在发起 HTTP 请求前,先用 hasDefaultNetSync() 判断网络状态,避免无网络时发起注定失败的请求:
function safeHttpRequest(url: string): void {
if (!connection.hasDefaultNetSync()) {
console.error('无网络连接,取消请求');
return;
}
// 发起 HTTP 请求
const httpRequest = http.createHttp();
httpRequest.request(url);
}
4.2 根据网络类型调整策略
通过 bearerTypes 判断当前网络类型,在 WiFi 下预加载高清资源,在蜂窝网络下使用低质量资源:
function shouldPreloadHD(): boolean {
try {
const netHandle = connection.getDefaultNetSync();
const caps = connection.getNetCapabilitiesSync(netHandle);
const bt = caps.bearerTypes;
// 仅 WiFi 或以太网下预加载高清资源
return bt && bt.length > 0 && (bt[0] === 0 || bt[0] === 3);
} catch (e) {
return false; // 异常时保守策略:不预加载
}
}
4.3 网络诊断工具
构建一个完整的网络诊断函数,依次检查连接状态、网络类型、DNS 解析:
interface NetDiagnosis {
connected: boolean;
bearerType: string;
dnsResolved: boolean;
dnsAddresses: string[];
}
async function runNetDiagnosis(host: string): Promise<NetDiagnosis> {
const result: NetDiagnosis = {
connected: false,
bearerType: '未知',
dnsResolved: false,
dnsAddresses: []
};
try {
result.connected = connection.hasDefaultNetSync();
if (result.connected) {
const handle = connection.getDefaultNetSync();
const caps = connection.getNetCapabilitiesSync(handle);
if (caps.bearerTypes && caps.bearerTypes.length > 0) {
result.bearerType = ['WiFi', '蜂窝网络', 'VPN', '以太网'][caps.bearerTypes[0]] || '其他';
}
const addrs = await connection.getAddressesByName(host);
result.dnsResolved = addrs.length > 0;
for (let i = 0; i < addrs.length; i++) {
result.dnsAddresses.push(addrs[i].address);
}
}
} catch (e) {
// 诊断失败,返回默认值
}
return result;
}
五、与 @ohos.net.http 的协作关系
@ohos.net.connection 和 @ohos.net.http 同属 @kit.NetworkKit,两者职责分明、配合紧密:
| 模块 | 职责 | 典型 API |
|---|---|---|
| @ohos.net.connection | 网络状态检测、能力查询、DNS 解析 | hasDefaultNetSync, getNetCapabilitiesSync, getAddressesByName |
| @ohos.net.http | HTTP 请求发送、响应处理 | createHttp, request, HttpResponse |
协作模式:
// 1. 先检测网络状态
if (!connection.hasDefaultNetSync()) {
showToast('网络未连接');
return;
}
// 2. 可选:根据网络类型调整请求策略
const caps = connection.getNetCapabilitiesSync(connection.getDefaultNetSync());
// 3. 发起 HTTP 请求
const req = http.createHttp();
req.request('https://api.example.com/data', {
method: http.RequestMethod.GET,
connectTimeout: caps.bearerTypes?.[0] === 1 ? 15000 : 5000 // 蜂窝网络给更长超时
});
六、ArkTS 使用注意事项
6.1 API 版本差异
@ohos.net.connection 在 API 24 中提供的是精简版 API。实际可用的 API 包括:
hasDefaultNetSync()— 同步检测getDefaultNetSync()— 获取默认网络句柄getNetCapabilitiesSync(netHandle)— 获取网络能力getAddressesByName(host)— DNS 解析(异步 Promise)
文档中可能提到的 connection.on('netCapabilitiesChange') 和 connection.off('netCapabilitiesChange') 事件订阅机制在当前 SDK 版本中不可用。如果需要持续监听网络状态变化,应通过定时轮询 hasDefaultNetSync() 来实现。
6.2 带宽值的防御性处理
linkDownBandwidthKbps 和 linkUpBandwidthKbps 在以下情况下可能为 0 或 undefined:
- 模拟器环境
- 部分 VPN 连接
- 驱动未提供带宽信息
代码必须做空值判断:
const bw = caps.linkDownBandwidthKbps;
const display = (bw !== undefined && bw > 0) ?
(bw / 1000).toFixed(1) + ' Mbps' : '--';
6.3 权限说明
hasDefaultNetSync()和getDefaultNetSync()无权限要求getNetCapabilitiesSync()的带宽属性需要ohos.permission.GET_NETWORK_INFO权限(缺省声明不影响编译)getAddressesByName()需要ohos.permission.INTERNET权限
七、总结
@ohos.net.connection 是 HarmonyOS NEXT 中检测网络连接状态和执行 DNS 解析的核心模块。通过本文的学习,你应该已经掌握:
- 同步检测模型:
hasDefaultNetSync()无参数无权限,直接返回 boolean,完成最基础的网络连通性判断 - 网络能力查询:
getDefaultNetSync()+getNetCapabilitiesSync()组合获取完整网络能力信息,包括带宽(linkDownBandwidthKbps/linkUpBandwidthKbps)和承载类型(bearerTypes:WiFi/蜂窝/VPN/以太网) - DNS 域名解析:
getAddressesByName(host)异步 Promise 返回Array<NetAddress>,支持 IPv4/IPv6 多地址解析 - 防御性编程:带宽值可能为空或 0,承载类型数组可能为空——所有网络数据都需要做空值判断
- 与 http 模块协作:connection 负责检测网络状态和类型,http 负责发起请求——两者同属
@kit.NetworkKit,形成完整的网络通信栈
@ohos.net.connection 的最佳使用模式可以总结为:
请求前用 hasDefaultNetSync 快速判断,需要详情时用 getNetCapabilitiesSync 查询能力,怀疑 DNS 问题时用 getAddressesByName 验证解析。所有 API 同步为主、异步为辅——简洁高效。
网络连接状态是应用通信的基础。虽然 @ohos.net.connection 的 API 数量不多,但它与 @ohos.net.http 的组合覆盖了从网络检测到数据通信的完整链路。在应用架构中为网络诊断保留一个标准化的检查流程,是所有网络相关应用的必修课。
@ohos.net.connection 属于 @kit.NetworkKit,是 HarmonyOS NEXT 网络通信能力的基础模块。它的同步 API 零开销、异步 DNS 解析简洁高效,相比 Android 的 ConnectivityManager 回调模式和 iOS 的 NWPathMonitor 异步监听,@ohos.net.connection 的同步优先设计更符合"先检测、再请求"的直觉编程模型。
更多推荐



所有评论(0)