Ping

Copyright © Quectel Wireless Solutions Co., Ltd. 2026. All rights reserved.


功能概述

Ping是一种基于ICMP(Internet Control Message Protocol,互联网控制报文协议)的网络诊断工具,主要用于测试主机间的网络连通性、测量RTT(Round-Trip Time,往返时间)和评估丢包率。

  • 核心机制:发送ICMP Echo_Request,等待目标主机返回ICMP Echo_Reply。

  • 在嵌入式/物联网场景中,Ping的常见用途包括:

    • 开机自检

    • 周期性心跳

    • 故障定位(DNS、路由、防火墙)

基本要素

  1. 工作原理:基于ICMP协议的回显请求/应答机制实现连通性检测:模块发送Echo包到目标主机;若目标主机存活且网络可达,将返回Echo-Reply包,以此验证双向连通性。

  2. 网络协议支持:Ping功能的实现依赖于底层网络协议栈对ICMP协议的完整支持。

  3. 网络接口配置:系统需正确配置网络接口参数(如IP地址、子网掩码和默认网关等),以确保网络数据包的正常收发。

  4. 高精度定时器:为准确测量RTT,嵌入式系统需提供高精度的硬件或软件定时器来计算时间差。

  5. TTL(Time To Live,生存时间):控制数据包在网络中的最大路由跳数。每经过一个路由器,TTL值减1;当TTL递减至0时,数据包将被丢弃并返回ICMP Time Exceeded消息。

  6. 输入参数

    • 目标地址:目标主机的域名或IPv4/IPv6地址。

    • 字节数:ICMP数据报文的字节数。

    • 次数:单次Ping操作中发送Echo报文的次数。

    • 时间:等待Echo Reply报文的最大时间阈值(毫秒)。

    • TTL:Echo报文在网络中的最大转发跳数。

  7. 输出结果

    • 字节数:接收到的应答报文大小。

    • TTL:应答报文的剩余生存时间。

    • RTT:从发送请求到接收应答的时间差。

    • 远程IP地址:应答报文的源IP地址。

    • 最终统计信息:包括发送包数,接收包数、丢包数、最小RTT,最大RTT,平均RTT等。

  8. 常见结果

    • 成功连接:正常接收到Reply报文。

    • 主机不存在:显示“请求找不到主机”。

    • 请求超时:Echo报文到达目标但Reply报文丢失。

    • 无法访问目标主机:Echo报文在传输途中被终止。

  9. 故障排查步骤

    • Ping 127.0.0.1:验证本地TCP/IP协议栈是否正常。

    • Ping [本机IP]:验证本地网卡及网络接口配置。

    • Ping [网关IP]:检查网络连接。

    • Ping [远端主机IP]:测试与外部网络的连通性。

流程概述

  1. 创建数据包:源主机创建一个包含ICMP报文的数据包。默认报文长度为56字节,报文中包含数据包标识符(通常为进程ID)、序列号和时间戳等信息。

  2. 发送数据包:将创建的数据包通过本地网络接口发送至目标主机,进入网络传输链路。

  3. 接收响应:目标主机接收到数据包后,若网络连接畅通,将构造并返回一个ICMP Echo Reply(回送应答)报文。该报文的标识符与序列号必须与原始请求报文保持一致。

  4. 解析结果:源主机接收到目标主机的回送应答报文后,匹配标识符与序列号完成报文配对,并根据时间戳计算RTT,随后输出诊断结果。

  5. 循环执行:根据设置的数据包发送次数,循环执行上述收发过程,达到指定次数后停止。

ICMP报文标准结构

Ping请求包(ICMP ECHO_REQUEST)结构

[IP头部][ICMP类型=8][ICMP代码=0][校验和][标识符][序列号][数据(时间戳+填充)]

  1. IP头部(20字节)

    • 包含源IP地址、目的IP地址、TTL等字段。

  2. ICMP头部(8字节)

    • ICMP类型(Type):8(回显请求ECHO_REQUEST)。

    • ICMP代码(Code):0。

    • 校验和(Checksum):用于验证ICMP头部和数据的完整性。

    • 标识符(Identifier):用于匹配请求与响应报文。

    • 序列号(Sequence Number):用于匹配请求和响应报文。

  3. 数据部分

    • 默认为56字节,可配置。

    • 通常包含用于计算RTT的时间戳信息和用于填充的固定字符串(如"ping")。

Ping应答包(ICMP ECHO_REPLY)结构

[IP头部][ICMP类型=0][ICMP代码=0][校验和][标识符][序列号][数据(与请求包相同)]

  1. IP头部(20字节)

    • 包含源IP地址(原始目的IP)、目的IP地址(原始源IP)、TTL等字段。

  2. ICMP头部(8字节)

    • ICMP类型(Type):0(回显应答ECHO_REPLY)。

    • ICMP代码(Code):0。

    • 校验和(Checksum):重新计算以匹配回应包。

    • 标识符(Identifier):与请求包相同,用于报文配对。

    • 序列号(Sequence Number):与请求包相同,用于报文配对。

  3. 数据部分

    • 与请求包的数据部分完全相同(包括时间戳和填充字节)。

补充说明

  • TTL字段:请求包的TTL通常设置为255,远端应答包的TTL取决于目标主机的操作系统(如BSD系统常设置为255,其他系统可能设置为30或60)。

  • 校验和计算:ICMP头部和数据的校验和是整个ICMP消息(包括头部和数据)的16位补码和。

以下是Ping请求包和应答包的消息结构:

../../../_images/image_NNTwbC6QzoRfwmxQ616crxCrnPc.webp

Ping API

头文件

qcm_ping_app.h

函数概览

函数

描述

qcm_ping_start()

启用Ping功能并根据配置信息设置发送的数据包

函数详解

qcm_ping_start

  • 功能描述
    启用Ping功能并根据配置信息设置发送的数据包。

  • 函数原型

qcm_ping_error_e  qcm_ping_start(qosa_int32_t cid,                                  
                                 qosa_int32_t sim_id,                                  
                                 const char *host,                                  
                                 qcm_ping_config_type *ping_options,                                  
                                 qcm_ping_event_cb cb_fun,                                  
                                 void *user_param);
  • 参数说明

参数名

输入/输出

类型

说明

cid

输入

qosa_int32_t

PDP Client ID

sim_id

输入

qosa_int32_t

SIM ID
0:SIM卡1
1:SIM卡2

host

输入

const char *

目标主机的域名或IPv4/IPv6地址

ping_options

输入

qcm_ping_config_type *

Ping的配置信息;详见 qcm_ping_config_type

cb_fun

输入

qcm_ping_event_cb

Ping事件的回调函数;详见 qcm_ping_event_cb

user_param

输入

void*

用户自定义参数

  • 返回值说明
    QCM_PING_OK:函数执行成功
    其他值:函数执行失败;详见 qcm_ping_error_e

qcm_ping_event_cb

  • 函数原型

typedef void (*qcm_ping_event_cb)(qcm_ping_event_type event_id, 
                                  qcm_ping_error_e evt_code, 
                                  qcm_ping_resp_t *resp_ptr, 
                                  void *user_param);
  • 参数说明

参数名

输入/输出

类型

说明

event_id

输入

qcm_ping_event_type

Ping返回的事件类型;详见 qcm_ping_event_type

evt_code

输入

qcm_ping_error_e

Ping事件的结果码;详见 qcm_ping_error_e

resp_ptr

输入

qcm_ping_resp_t *

Ping返回的响应信息;详见 qcm_ping_resp_t

user_param

输入

void*

用户自定义参数

  • 返回值说明

结构体定义

qcm_ping_config_type

Ping的配置信息结构体定义如下:

typedef struct
{
    qosa_uint32_t num_data_bytes;         
    qosa_uint32_t ping_response_time_out; 
    qosa_uint32_t num_pings;             
    qosa_uint32_t ttl;                  
} qcm_ping_config_type;

参数

类型

说明

num_data_bytes

qosa_uint32_t

Ping数据包大小;单位:字节

ping_response_time_out

qosa_uint32_t

等待PING响应的超时时间;单位:毫秒

num_pings

qosa_uint32_t

Ping的次数

ttl

qosa_uint32_t

Ping数据包的TTL

qcm_ping_resp_t

Ping返回的响应信息结构体定义如下:

 typedef struct
{
    union
    {
        qcm_ping_summary_type summary; 
        qcm_ping_stats_type   status;  
    } type;                           
} qcm_ping_resp_t;

参数

类型

说明

summary

qcm_ping_summary_type

Ping的汇总统计信息;详见 qcm_ping_summary_type

status

qcm_ping_stats_type

Ping的实时状态信息;详见 qcm_ping_stats_type

qcm_ping_summary_type

Ping的汇总统计信息结构体定义如下:

typedef struct
{
    qosa_uint32_t min_rtt;        
    qosa_uint32_t max_rtt;        
    qosa_uint32_t avg_rtt;       
    qosa_uint32_t num_pkts_sent;  
    qosa_uint32_t num_pkts_recvd;
    qosa_uint32_t num_pkts_lost;
} qcm_ping_summary_type;

参数

类型

说明

min_rtt

qosa_uint32_t

RTT的最小值;单位:毫秒

max_rtt

qosa_uint32_t

RTT的最大值;单位:毫秒

avg_rtt

qosa_uint32_t

RTT的平均值;单位:毫秒

num_pkts_sent

qosa_uint32_t

已发送数据包数量

num_pkts_recvd

qosa_uint32_t

已接收回应包数量

num_pkts_lost

qosa_uint32_t

丢失的数据包数量

qcm_ping_stats_type

Ping的实时状态信息结构体定义如下:

typedef struct
{
    qosa_uint32_t ping_rtt;                                      
    qosa_uint32_t ping_size;                                    
    qosa_uint32_t ping_ttl;                                      
    char          resolved_ip_addr[CONFIG_QOSA_INET6_ADDRSTRLEN]; 
} qcm_ping_stats_type;

参数

类型

说明

ping_rtt

qosa_uint32_t

RTT值

ping_size

qosa_uint32_t

Ping数据包的大小;单位:字节

ping_ttl

qosa_uint32_t

Ping数据包的TTL值

resolved_ip_addr

char

Ping目标主机IP地址

枚举定义

qcm_ping_event_type

Ping返回的事件类型枚举定义如下:

typedef enum
{
    QCM_PING_STATS = 1,   
    QCM_PING_SUMMARY = 2, 
} qcm_ping_event_type;

成员

说明

QCM_PING_STATS

单次的Ping结果

QCM_PING_SUMMARY

Ping的统计信息

qcm_ping_error_e

Ping事件的结果码枚举定义如下:

typedef enum
{
    QCM_PING_OK = 0,
    QCM_PING_SEND_END = 1,
    QCM_PING_ERR_UNKNOW = (QOSA_COMPONENT_PING << 16) | 550,                 
    QCM_PING_ERR_INVALID_PARAM = (QOSA_COMPONENT_PING << 16) | 552,        
    QCM_PING_ERR_MEMORY = (QOSA_COMPONENT_PING << 16) | 553,                
    QCM_PING_ERR_SOCKET_NEW_FAILURE = (QOSA_COMPONENT_PING << 16) | 554,   
    QCM_PING_ERR_SOCKET_BIND_FAILURE = (QOSA_COMPONENT_PING << 16) | 556,   
    QCM_PING_ERR_SOCKET_WRITE_FAILURE = (QOSA_COMPONENT_PING << 16) | 558, 
    QCM_PING_ERR_SOCKET_READ_FAILURE = (QOSA_COMPONENT_PING << 16) | 559,   
    QCM_PING_ERR_PDP_ACTIVE_FAILURE = (QOSA_COMPONENT_PING << 16) | 561,   
    QCM_PING_ERR_DNS_FAILURE = (QOSA_COMPONENT_PING << 16) | 565,           
    QCM_PING_ERR_SOCKET_CONNECT_FAILURE = (QOSA_COMPONENT_PING << 16) | 566, 
    QCM_PING_ERR_TIMEOUT = (QOSA_COMPONENT_PING << 16) | 569,               
    QCM_PING_ERR_OPERATION_NOT_ALLOWED = (QOSA_COMPONENT_PING << 16) | 572, 
} qcm_ping_error_e;

成员

说明

QCM_PING_OK

函数执行成功

QCM_PING_SEND_END

数据包发送结束

QCM_PING_ERR_UNKNOW

未知错误

QCM_PING_ERR_INVALID_PARAM

参数无效

QCM_PING_ERR_MEMORY

内存不足

QCM_PING_ERR_SOCKET_NEW_FAILURE

创建Socket失败

QCM_PING_ERR_SOCKET_BIND_FAILURE

Socket绑定失败

QCM_PING_ERR_SOCKET_WRITE_FAILURE

Socket写入失败

QCM_PING_ERR_SOCKET_READ_FAILURE

Socket读取失败

QCM_PING_ERR_PDP_ACTIVE_FAILURE

PDP上下文激活失败

QCM_PING_ERR_DNS_FAILURE

DNS解析失败

QCM_PING_ERR_SOCKET_CONNECT_FAILURE

Socket连接失败

QCM_PING_ERR_TIMEOUT

操作超时

QCM_PING_ERR_OPERATION_NOT_ALLOWED

操作不允许

应用逻辑流程图

../../../_images/board_FhLEwJMojh0B6Mb7ZDpcP50yn4b.jpg

示例代码

完整示例代码请查看 https://github.com/UniRTOS/UniRTOS-Doc-Examples/blob/main/network/network_protocol/ping/ping_demo.c

Ping功能配置建议

参数

推荐值

说明

num_data_bytes

32~1472

过大的载荷可能导致数据包超出网络MTU限制,从而引发分片或丢弃

num_pings

4~10

平衡测试耗时与统计结果准确性

ping_response_time_out

1000~5000

2000毫秒适用于大多数网络情景

ttl

32~255

64适用于大多数网络情景

常见问题排查指南

错误码/问题)

可能原因

建议解决方案

QCM_PING_ERR_INVALID_PARAM(参数无效)

输入参数为空、参数设置超出范围或格式错误

  • 完整初始化 ping_options 结构体
  • 校验 host 字符串非空
  • 限制 sim_id 仅为0/1、cid≥ 1、num_pings≥ 1
  • 载荷长度控制在MTU范围内

QCM_PING_ERR_MEMORY(内存不足)

系统内存分配失败,任务栈空间过小或堆内存耗尽

  • 优化代码内存使用
  • 增加任务栈大小(如 UNIR_PING_DEMO_TASK_STACK_SIZE
  • 检查系统整体负载

QCM_PING_ERR_SOCKET_NEW_FAILURE(创建Socket失败)

网络栈未初始化或Socket资源耗尽

  • 确保PDP上下文已激活
  • 重启网络功能
  • 检查系统Socket限制

QCM_PING_ERR_SOCKET_BIND_FAILURE(Socket绑定失败)

本地IP配置异常、端口冲突或系统权限/防火墙拦截

  • 验证本地IP配置正确性
  • 避免使用保留端口
  • 检查防火墙规则。

QCM_PING_ERR_SOCKET_WRITE_FAILURE(Socket写入失败)

网络连接中断或缓冲区满

  • 检查网络信号强度
  • 增加重试机制
  • 先Ping网关确认本地链路通畅再测试外网

QCM_PING_ERR_SOCKET_READ_FAILURE(Socket读取失败)

响应包丢失或读取超时

  • 调大 ping_response_time_out 超时时间
  • 检查网络稳定性
  • 抓取日志定位报文丢失节点

QCM_PING_ERR_PDP_ACTIVE_FAILURE(PDP上下文激活失败)

SIM卡未就绪、网络未注册或APN配置错误

  • 确认SIM卡已正常插入并有效
  • 通过AT命令确认模块成功注网
  • 配置正确APN

QCM_PING_ERR_DNS_FAILURE(DNS解析失败)

域名无效、网络无DNS服务器或解析超时

  • 使用IP地址代替域名测试
  • 检查DNS服务器设置
  • 先Ping公网IP(如8.8.8.8)确认外网连通

QCM_PING_ERR_SOCKET_CONNECT_FAILURE(Socket连接失败)

目标不可达、防火墙阻挡或路由问题

  • 使用traceroute工具诊断路由
  • 检查防火墙/ACL规则
  • 切换网络接口

QCM_PING_ERR_TIMEOUT(操作超时)

响应超时时间过短或网络延迟高

  • ping_response_time_out 调至1000毫秒以上
  • 减少 num_data_bytes
  • 优化网络环境

QCM_PING_ERR_OPERATION_NOT_ALLOWED(操作不允许)

权限不足或模块未启用Ping功能

  • 检查系统权限
  • 确保 qcm_ping_app.h 等库已正确集成
  • 重启设备

QCM_PING_ERR_UNKNOW(未知错误)

未分类错误,可能为底层系统问题

-

无错误但RTT高、丢包率高

网络拥塞、信号弱或目标服务器负载

  • 减少 num_pings,降低网络占用
  • 切换到有线网络
  • 分析 qcm_ping_summary_type 统计信息

回调未触发(无 QCM_PING_STATS/SUMMARY

任务/消息队列未正确初始化或阻塞

  • 确认回调函数已正确注册
  • 确认应用任务上下文正常且未被长时间阻塞
  • 若使用异步流程,确认主循环或事件处理逻辑可以正常接收并处理Ping结果通知