一、根据NETDEV_FLAG_INTERNET_UP
位判断
static bool is_conncected(void)
{
struct netdev *dev = RT_NULL;
dev = netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);
if (dev == RT_NULL)
{
printf("wait netdev internet up...");
return false;
}
else
{
printf("local ip is:%d.%d.%d.%d", ((( dev->ip_addr.addr) >> 0) & 0xFF), ((( dev->ip_addr.addr) >> 8) & 0xFF),
((( dev->ip_addr.addr) >> 16) & 0xFF), ((( dev->ip_addr.addr) >> 24) & 0xFF));
return true;
}
}
二、如果开启dhcp根据是否获取到ip判断
bool is_connected()
{
struct netdev *dev = RT_NULL;
struct netif *netif = netif_list; // 获取第一个网络接口
if (netif && netif_is_up(netif))
{ // 检查接口是否已初始化并启动
struct dhcp *dhcp = netif_dhcp_data(netif); // 获取 DHCP 数据结构
if (dhcp && dhcp->state == 10)
{ // 检查 DHCP 是否绑定到 IP 地址
log_i("network is connected and ip address is obtained!");
return true;
}
else
{
log_w("network is up but no ip address!");
return false;
}
}
else
{
log_w("network interface is not up!");
return false;
}
}
三、通过ping命令检测
以下是一个基于RT-Thread和LwIP的Ping网络连接检测代码示例,用于检查设备是否成功连接互联网:
代码实现
#include <rtthread.h>
#include <lwip/netdb.h>
#include <lwip/sockets.h>
#include <lwip/icmp.h>
#include <lwip/inet.h>
#include <lwip/ip.h>
#define PING_DATA_SIZE 32
#define PING_DELAY RT_TICK_PER_SECOND
static struct rt_semaphore ping_sem;
static rt_uint32_t ping_time;
static void ping_timeout(void *arg)
{
rt_sem_release(&ping_sem);
}
static void ping_recv(int s, struct sockaddr_in *addr)
{
char buf[64];
int fromlen = sizeof(*addr);
int len;
while ((len = lwip_recvfrom(s, buf, sizeof(buf), 0,
(struct sockaddr *)addr, (socklen_t *)&fromlen)) > 0)
{
struct ip_hdr *iphdr = (struct ip_hdr *)buf;
struct icmp_echo_hdr *iecho = (struct icmp_echo_hdr *)(buf + (IPH_HL(iphdr) * 4));
if (iecho->id == PING_ID && iecho->seqno == htons(ping_time))
{
rt_sem_release(&ping_sem);
break;
}
}
}
static int ping(int s, const char *host)
{
int timeout = PING_DELAY;
struct sockaddr_in addr;
struct hostent *hptr;
struct rt_timer ping_timer;
addr.sin_family = AF_INET;
addr.sin_port = 0;
if ((hptr = lwip_gethostbyname(host)) == NULL)
{
return -RT_ERROR;
}
addr.sin_addr.s_addr = *(rt_uint32_t *)hptr->h_addr_list[0];
rt_timer_init(&ping_timer, "ping_timeout", ping_timeout, RT_NULL,
timeout, RT_TIMER_FLAG_ONE_SHOT);
rt_timer_start(&ping_timer);
rt_sem_init(&ping_sem, "ping_sem", 0, RT_IPC_FLAG_FIFO);
for (ping_time = 0; ping_time < PING_DATA_SIZE; ping_time++)
{
struct icmp_echo_hdr *iecho;
char buf[PING_DATA_SIZE + sizeof(struct icmp_echo_hdr)];
iecho = (struct icmp_echo_hdr *)buf;
ICMPH_TYPE_SET(iecho, ICMP_ECHO);
ICMPH_CODE_SET(iecho, 0);
iecho->chksum = 0;
iecho->id = PING_ID;
iecho->seqno = htons(ping_time);
rt_memset(&buf[sizeof(struct icmp_echo_hdr)], 0x00, PING_DATA_SIZE);
iecho->chksum = inet_chksum(iecho, sizeof(struct icmp_echo_hdr) + PING_DATA_SIZE);
if (lwip_sendto(s, buf, sizeof(buf), 0, (struct sockaddr *)&addr, sizeof(addr)) <= 0)
{
rt_timer_stop(&ping_timer);
rt_sem_detach(&ping_sem);
return -RT_ERROR;
}
if (rt_sem_take(&ping_sem, timeout) == RT_EOK)
{
rt_timer_stop(&ping_timer);
rt_sem_detach(&ping_sem);
return RT_EOK;
}
}
rt_timer_stop(&ping_timer);
rt_sem_detach(&ping_sem);
return -RT_ERROR;
}
int ping_network(void)
{
int s;
int ret;
s = lwip_socket(AF_INET, SOCK_RAW, IP_PROTO_ICMP);
if (s < 0)
{
rt_kprintf("create socket failed\n");
return -1;
}
ret = ping(s, "8.8.8.8"); // Ping Google DNS服务器
lwip_close(s);
if (ret == RT_EOK)
{
rt_kprintf("ping 8.8.8.8 success!\n");
return 0;
}
else
{
rt_kprintf("ping 8.8.8.8 failed!\n");
return -1;
}
}
MSH_CMD_EXPORT(ping_network, Ping test network connection);
代码说明
- 代码创建了一个ICMP RAW socket用于发送和接收Ping包
- 使用Google的DNS服务器8.8.8.8作为Ping目标
- 实现了Ping的超时处理和响应接收
- 通过信号量同步Ping的发送和接收过程
- 结果会通过串口输出显示Ping是否成功
使用说明
- 在RT-Thread的env工具中确保已开启LwIP组件
- 将代码添加到项目中并编译
- 在FinSH命令行中执行
ping_network
命令 - 成功连接互联网时会显示"ping 8.8.8.8 success!"
注意事项
- 需要网络接口已正确初始化并能访问互联网
- 某些网络环境可能屏蔽ICMP包,这种情况下即使网络连通Ping也会失败
- 可以根据需要修改Ping的目标地址
常见问题处理
若ping命令不可用,需检查:
- 网络协议栈(LwIP)是否正确初始化
- 网络接口(如ETH或WIFI)是否正常连接
- DNS配置是否正确(对于域名ping测试)
网络连接成功后,ping测试可作为基础的网络状态检测手段,配合其他网络工具如ifconfig、netstat等全面诊断网络问题。