HarmonyOS 鸿蒙Next支持发送 ICMP包的库吗
HarmonyOS 鸿蒙Next支持发送 ICMP包的库吗 我想实现一个tcp/ip类工具应用,比如实现ping 命令的 查看连通性,丢包等功能
基于NetConnection实现ping工具:
ping工具是实用工具类应用的高频使用场景之一,可用于辅助用户实现简单的网络探测功能。
本示例基于native侧异步任务、net_connection.h和NetConn_ProbeResultInfo实现ping功能以及探测数据统计展示。
实现思路
- 输入待ping的域名或IP地址,对于输入的内容需要校验其是否为符合要求的域名或IP地址,非法输入需要进行提醒。
TextInput({ text: $$this.pingAddress, placeholder: $r('app.string.ping_input_placeholder') })
.onChange((value) => {
// 输入过程不进行检测
this.isValid = true;
this.pingAddress = value;
})
.onBlur(() => {
// 输入框失焦后检查输入内容的合法性
if (this.pingAddress === '') {
this.isValid = true;
return;
}
this.isValid = this.isValidAddress(this.pingAddress);
})
- 点击检测按钮,二次校验输入地址的合法性,校验通过后,调用native侧接口执行ping操作,并在回调中对探测结果进行处理和拼接展示。
// 二次校验
if (!this.isValidAddress(this.pingAddress)) {
this.isValid = false;
return;
}
try {
// 调用Native侧的接口实现ping功能
PingTool.nativePing(this.pingAddress, 2)
.then((result) => {
// 获取返回结果并解析,得到其中的各项数据
let parseResult = JSON.parse(result) as object;
let lossRate: number = parseResult['lossRate'];
let minDelay: number = parseResult['minDelay'];
let maxDelay: number = parseResult['maxDelay'];
let avgDelay: number = parseResult['avgDelay'];
let stdDelay: number = parseResult['stdDelay'];
// 拼接展示信息
this.pingMsg += util.format(CommonConstants.PING_MESSAGE_TEMPLATE, this.pingAddress, lossRate, minDelay,
maxDelay, avgDelay, stdDelay);
this.pingMsg += '\n\n';
}).catch((error: BusinessError) => {
this.pingMsg += `ping failed: ${error.code} ${error.message}`;
})
} catch (e) {
// 处理错误
}
- native侧接收地址和探测持续时间两个参数,使用Promise方式构建异步任务执行ping操作,在任务执行回调中执行ping操作,任务完成回调中处理返回数据。
static napi_value NativePing(napi_env env, napi_callback_info info) {
// 校验参数合法性,并读取地址参数和持续时间参数
// 创建异步任务,执行ping操作
napi_status createPromiseStatus;
napi_value promiseValue = nullptr;
napi_deferred deferred = nullptr;
createPromiseStatus = napi_create_promise(env, &deferred, &promiseValue);
auto callbackData = new CallbackData();
callbackData->deferred = deferred;
callbackData->arg_address = buffer;
callbackData->arg_duration = duration;
napi_status createResourceStatus;
napi_value resourceName = nullptr;
createResourceStatus = napi_create_string_utf8(env, "PingAsyncCallback", NAPI_AUTO_LENGTH, &resourceName);
napi_status createAsyncStatus;
// PingExecuteCB为任务执行回调,负责执行ping操作;PingCompleteCB为任务完成回调,用于处理返回值
createAsyncStatus = napi_create_async_work(env, nullptr, resourceName, PingExecuteCB, PingCompleteCB, callbackData, &callbackData->asyncWork);
if (napi_queue_async_work(env, callbackData->asyncWork) != napi_ok) {
ReleaseCallbackData(callbackData);
napi_delete_async_work(env, callbackData->asyncWork);
napi_throw_error(env, nullptr, "enqueue async work error");
return nullptr;
}
return promiseValue;
}
- 实际执行ping操作时,构建NetConn_ProbeResultInfo对象用于储存探测结果,并通过OH_NetConn_QueryProbeResult接口发出探测命令,探测完成后,取出结果数据并拼接为json字符串返回。
NetConn_ProbeResultInfo probeInfo;
probeInfo.lossRate = 0;
probeInfo.rtt[0] = 0;
probeInfo.rtt[1] = 0;
probeInfo.rtt[2] = 0;
probeInfo.rtt[3] = 0;
int32_t ret = OH_NetConn_QueryProbeResult(address, duration, &probeInfo);
// ret!=0时代表调用出错
if (ret != 0) {
OH_LOG_ERROR(LOG_APP, "query probe info error: ret = %{public}d", ret);
return nullptr;
}
// 成功调用后,获取返回结果中的丢包率,最小、最大、平均以及标准时延
uint8_t lossRate = probeInfo.lossRate;
uint32_t minDelay = probeInfo.rtt[0];
uint32_t maxDelay = probeInfo.rtt[1];
uint32_t avgDelay = probeInfo.rtt[2];
uint32_t stdDelay = probeInfo.rtt[3];
char *json = nullptr;
try {
std::ostringstream oss;
oss << "{\"lossRate\": " << static_cast<int>(lossRate) << ", \"minDelay\": " << minDelay
<< ", \"maxDelay\": " << maxDelay << ", \"avgDelay\": " << avgDelay << ", \"stdDelay\": " << stdDelay
<< "}";
std::string str = oss.str();
json = new char[str.size() + 1];
str.copy(json, str.size(), 0);
json[str.size()] = '\0';
} catch (const std::bad_alloc& e) {
// 处理异常
}
return json;
权限说明
使用Internet网络权限:ohos.permission.INTERNET。
参考文档
使用Node-API接口进行异步任务开发
net_connection.h
NetConn_ProbeResultInfo
更多关于HarmonyOS 鸿蒙Next支持发送 ICMP包的库吗的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
开发者你好,看下权限问题,在 module.json5 中确保声明网络权限,使用真机调试并确认网络是否可用。 或者你也可以基于NetConnection实现ping工具,参考新楼层回复。
开发者你好,参考以下方案:
【解决方案】
- 使用connection中的NetCap的字段’NET_CAPABILITY_VALIDATED’判断网络访问Internet的连通性是否被被网络管理成功验证,该能力由网络管理模块设置。
- 使用三方库[@ohos-rs/ping](https://ohpm.openharmony.cn/#/cn/detail/@ohos-rs%2Fping)检测ip地址/网址是否连通。
- 对于新完成连接的网络,由于网络正在进行连通性验证,此值可能无法反映真实的验证结果。对此,可以通过’NET_CAPABILITY_CHECKING_CONNECTIVITY’检查网络是否正在检测连通性。
- ping之后的网络相关数据可以通过OH_NetConn_QueryProbeResult查询网络探测结果获取。
- ping之后的网络相关数据通过OH_NetConn_QueryProbeResult不会超时返回,导致进程Block。可以通过OH_NetConn_QueryProbeResult的第2个参数duration(类型为int32_t)设置探测操作的超时时间,以毫秒(ms)为单位的超时阈值。未设置超时(传0)会导致永久阻塞。
必须有啊!
看这个库可以实现ping功能:[https://ohpm.openharmony.cn/#/cn/detail/@ohos-rs%2Fping](https://ohpm.openharmony.cn/#/cn/detail/@ohos-rs%2Fping)
HarmonyOS Next支持ICMP协议操作。系统提供了网络管理模块@ohos.net.connection,其中包含Socket API用于原始套接字操作,可构造和发送ICMP包。具体可通过createNCPSocket接口创建NETRAW类型的Socket,使用send接口发送自定义构造的ICMP数据包。接收响应需通过on(‘message’)监听接收数据。该能力需声明ohos.permission.INTERNET网络权限。
HarmonyOS Next目前提供了完整的网络编程能力,支持通过Socket API实现ICMP协议通信。您可以使用@ohos.net.socket模块创建原始套接字(SOCK_RAW)来构造和发送ICMP包,并通过接收响应实现ping功能。具体步骤包括:
- 创建原始套接字:
import socket from '@ohos.net.socket';
let tcpSocket = socket.constructSocketInstance();
-
构造ICMP数据包(需自行实现ICMP头部结构和校验和计算)
-
通过send/sendto发送数据包
-
通过recv/recvfrom接收响应并解析
需要注意:
- 需申请ohos.permission.INTERNET网络权限
- ICMP协议需使用协议号1
- 建议配合定时器实现超时和统计功能
这种方案可以完整实现ping工具的连通性检测、延迟统计和丢包率计算等功能。



