HarmonyOS 鸿蒙Next支持发送 ICMP包的库吗

HarmonyOS 鸿蒙Next支持发送 ICMP包的库吗 我想实现一个tcp/ip类工具应用,比如实现ping 命令的 查看连通性,丢包等功能

7 回复

基于NetConnection实现ping工具:

ping工具是实用工具类应用的高频使用场景之一,可用于辅助用户实现简单的网络探测功能。
本示例基于native侧异步任务net_connection.hNetConn_ProbeResultInfo实现ping功能以及探测数据统计展示。

实现思路

  1. 输入待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);
   })
  1. 点击检测按钮,二次校验输入地址的合法性,校验通过后,调用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) {
  // 处理错误
}
  1. 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;
}
  1. 实际执行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


ohpm install @ohos-rs/ping

不知道是我不会用还是用不了,反正报错

cke_2399.png

cke_193.png

开发者你好,看下权限问题,在 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功能。具体步骤包括:

  1. 创建原始套接字:
import socket from '@ohos.net.socket';
let tcpSocket = socket.constructSocketInstance();
  1. 构造ICMP数据包(需自行实现ICMP头部结构和校验和计算)

  2. 通过send/sendto发送数据包

  3. 通过recv/recvfrom接收响应并解析

需要注意:

  • 需申请ohos.permission.INTERNET网络权限
  • ICMP协议需使用协议号1
  • 建议配合定时器实现超时和统计功能

这种方案可以完整实现ping工具的连通性检测、延迟统计和丢包率计算等功能。

回到顶部