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、路由、防火墙)
基本要素¶
工作原理:基于ICMP协议的回显请求/应答机制实现连通性检测:模块发送Echo包到目标主机;若目标主机存活且网络可达,将返回Echo-Reply包,以此验证双向连通性。
网络协议支持:Ping功能的实现依赖于底层网络协议栈对ICMP协议的完整支持。
网络接口配置:系统需正确配置网络接口参数(如IP地址、子网掩码和默认网关等),以确保网络数据包的正常收发。
高精度定时器:为准确测量RTT,嵌入式系统需提供高精度的硬件或软件定时器来计算时间差。
TTL(Time To Live,生存时间):控制数据包在网络中的最大路由跳数。每经过一个路由器,TTL值减1;当TTL递减至0时,数据包将被丢弃并返回ICMP Time Exceeded消息。
输入参数:
目标地址:目标主机的域名或IPv4/IPv6地址。
字节数:ICMP数据报文的字节数。
次数:单次Ping操作中发送Echo报文的次数。
时间:等待Echo Reply报文的最大时间阈值(毫秒)。
TTL:Echo报文在网络中的最大转发跳数。
输出结果:
字节数:接收到的应答报文大小。
TTL:应答报文的剩余生存时间。
RTT:从发送请求到接收应答的时间差。
远程IP地址:应答报文的源IP地址。
最终统计信息:包括发送包数,接收包数、丢包数、最小RTT,最大RTT,平均RTT等。
常见结果:
成功连接:正常接收到Reply报文。
主机不存在:显示“请求找不到主机”。
请求超时:Echo报文到达目标但Reply报文丢失。
无法访问目标主机:Echo报文在传输途中被终止。
故障排查步骤:
Ping 127.0.0.1:验证本地TCP/IP协议栈是否正常。
Ping [本机IP]:验证本地网卡及网络接口配置。
Ping [网关IP]:检查网络连接。
Ping [远端主机IP]:测试与外部网络的连通性。
流程概述¶
创建数据包:源主机创建一个包含ICMP报文的数据包。默认报文长度为56字节,报文中包含数据包标识符(通常为进程ID)、序列号和时间戳等信息。
发送数据包:将创建的数据包通过本地网络接口发送至目标主机,进入网络传输链路。
接收响应:目标主机接收到数据包后,若网络连接畅通,将构造并返回一个ICMP Echo Reply(回送应答)报文。该报文的标识符与序列号必须与原始请求报文保持一致。
解析结果:源主机接收到目标主机的回送应答报文后,匹配标识符与序列号完成报文配对,并根据时间戳计算RTT,随后输出诊断结果。
循环执行:根据设置的数据包发送次数,循环执行上述收发过程,达到指定次数后停止。
ICMP报文标准结构¶
Ping请求包(ICMP ECHO_REQUEST)结构¶
[IP头部][ICMP类型=8][ICMP代码=0][校验和][标识符][序列号][数据(时间戳+填充)]
IP头部(20字节)
包含源IP地址、目的IP地址、TTL等字段。
ICMP头部(8字节)
ICMP类型(Type):8(回显请求ECHO_REQUEST)。
ICMP代码(Code):0。
校验和(Checksum):用于验证ICMP头部和数据的完整性。
标识符(Identifier):用于匹配请求与响应报文。
序列号(Sequence Number):用于匹配请求和响应报文。
数据部分
默认为56字节,可配置。
通常包含用于计算RTT的时间戳信息和用于填充的固定字符串(如"ping")。
Ping应答包(ICMP ECHO_REPLY)结构¶
[IP头部][ICMP类型=0][ICMP代码=0][校验和][标识符][序列号][数据(与请求包相同)]
IP头部(20字节)
包含源IP地址(原始目的IP)、目的IP地址(原始源IP)、TTL等字段。
ICMP头部(8字节)
ICMP类型(Type):0(回显应答ECHO_REPLY)。
ICMP代码(Code):0。
校验和(Checksum):重新计算以匹配回应包。
标识符(Identifier):与请求包相同,用于报文配对。
序列号(Sequence Number):与请求包相同,用于报文配对。
数据部分:
与请求包的数据部分完全相同(包括时间戳和填充字节)。
补充说明¶
TTL字段:请求包的TTL通常设置为255,远端应答包的TTL取决于目标主机的操作系统(如BSD系统常设置为255,其他系统可能设置为30或60)。
校验和计算:ICMP头部和数据的校验和是整个ICMP消息(包括头部和数据)的16位补码和。
以下是Ping请求包和应答包的消息结构:
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 |
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 |
操作不允许 |
应用逻辑流程图¶
示例代码¶
完整示例代码请查看 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(参数无效) |
输入参数为空、参数设置超出范围或格式错误 |
|
QCM_PING_ERR_MEMORY(内存不足) |
系统内存分配失败,任务栈空间过小或堆内存耗尽 |
|
QCM_PING_ERR_SOCKET_NEW_FAILURE(创建Socket失败) |
网络栈未初始化或Socket资源耗尽 |
|
QCM_PING_ERR_SOCKET_BIND_FAILURE(Socket绑定失败) |
本地IP配置异常、端口冲突或系统权限/防火墙拦截 |
|
QCM_PING_ERR_SOCKET_WRITE_FAILURE(Socket写入失败) |
网络连接中断或缓冲区满 |
|
QCM_PING_ERR_SOCKET_READ_FAILURE(Socket读取失败) |
响应包丢失或读取超时 |
|
QCM_PING_ERR_PDP_ACTIVE_FAILURE(PDP上下文激活失败) |
SIM卡未就绪、网络未注册或APN配置错误 |
|
QCM_PING_ERR_DNS_FAILURE(DNS解析失败) |
域名无效、网络无DNS服务器或解析超时 |
|
QCM_PING_ERR_SOCKET_CONNECT_FAILURE(Socket连接失败) |
目标不可达、防火墙阻挡或路由问题 |
|
QCM_PING_ERR_TIMEOUT(操作超时) |
响应超时时间过短或网络延迟高 |
|
QCM_PING_ERR_OPERATION_NOT_ALLOWED(操作不允许) |
权限不足或模块未启用Ping功能 |
|
QCM_PING_ERR_UNKNOW(未知错误) |
未分类错误,可能为底层系统问题 |
- |
无错误但RTT高、丢包率高 |
网络拥塞、信号弱或目标服务器负载 |
|
回调未触发(无 QCM_PING_STATS/SUMMARY) |
任务/消息队列未正确初始化或阻塞 |
|