STM32+rt-thread判断是否联网

news2025/6/12 23:15:10

一、根据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);

代码说明

  1. 代码创建了一个ICMP RAW socket用于发送和接收Ping包
  2. 使用Google的DNS服务器8.8.8.8作为Ping目标
  3. 实现了Ping的超时处理和响应接收
  4. 通过信号量同步Ping的发送和接收过程
  5. 结果会通过串口输出显示Ping是否成功

使用说明

  1. 在RT-Thread的env工具中确保已开启LwIP组件
  2. 将代码添加到项目中并编译
  3. 在FinSH命令行中执行ping_network命令
  4. 成功连接互联网时会显示"ping 8.8.8.8 success!"

注意事项

  1. 需要网络接口已正确初始化并能访问互联网
  2. 某些网络环境可能屏蔽ICMP包,这种情况下即使网络连通Ping也会失败
  3. 可以根据需要修改Ping的目标地址

常见问题处理

若ping命令不可用,需检查:

  • 网络协议栈(LwIP)是否正确初始化
  • 网络接口(如ETH或WIFI)是否正常连接
  • DNS配置是否正确(对于域名ping测试)

网络连接成功后,ping测试可作为基础的网络状态检测手段,配合其他网络工具如ifconfig、netstat等全面诊断网络问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2407821.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于Flask实现的医疗保险欺诈识别监测模型

基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施&#xff0c;由雇主和个人按一定比例缴纳保险费&#xff0c;建立社会医疗保险基金&#xff0c;支付雇员医疗费用的一种医疗保险制度&#xff0c; 它是促进社会文明和进步的…

SCAU期末笔记 - 数据分析与数据挖掘题库解析

这门怎么题库答案不全啊日 来简单学一下子来 一、选择题&#xff08;可多选&#xff09; 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘&#xff1a;专注于发现数据中…

vscode(仍待补充)

写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh&#xff1f; debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…

解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八

现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet&#xff0c;点击确认后如下提示 最终上报fail 解决方法 内核升级导致&#xff0c;需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…

(二)TensorRT-LLM | 模型导出(v0.20.0rc3)

0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述&#xff0c;后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作&#xff0c;其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…

CMake基础:构建流程详解

目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…

visual studio 2022更改主题为深色

visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中&#xff0c;选择 环境 -> 常规 &#xff0c;将其中的颜色主题改成深色 点击确定&#xff0c;更改完成

关于nvm与node.js

1 安装nvm 安装过程中手动修改 nvm的安装路径&#xff0c; 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解&#xff0c;但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后&#xff0c;通常在该文件中会出现以下配置&…

使用分级同态加密防御梯度泄漏

抽象 联邦学习 &#xff08;FL&#xff09; 支持跨分布式客户端进行协作模型训练&#xff0c;而无需共享原始数据&#xff0c;这使其成为在互联和自动驾驶汽车 &#xff08;CAV&#xff09; 等领域保护隐私的机器学习的一种很有前途的方法。然而&#xff0c;最近的研究表明&…

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端

&#x1f31f; 什么是 MCP&#xff1f; 模型控制协议 (MCP) 是一种创新的协议&#xff0c;旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议&#xff0c;它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…

iPhone密码忘记了办?iPhoneUnlocker,iPhone解锁工具Aiseesoft iPhone Unlocker 高级注册版​分享

平时用 iPhone 的时候&#xff0c;难免会碰到解锁的麻烦事。比如密码忘了、人脸识别 / 指纹识别突然不灵&#xff0c;或者买了二手 iPhone 却被原来的 iCloud 账号锁住&#xff0c;这时候就需要靠谱的解锁工具来帮忙了。Aiseesoft iPhone Unlocker 就是专门解决这些问题的软件&…

【网络安全产品大调研系列】2. 体验漏洞扫描

前言 2023 年漏洞扫描服务市场规模预计为 3.06&#xff08;十亿美元&#xff09;。漏洞扫描服务市场行业预计将从 2024 年的 3.48&#xff08;十亿美元&#xff09;增长到 2032 年的 9.54&#xff08;十亿美元&#xff09;。预测期内漏洞扫描服务市场 CAGR&#xff08;增长率&…

DAY 47

三、通道注意力 3.1 通道注意力的定义 # 新增&#xff1a;通道注意力模块&#xff08;SE模块&#xff09; class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…

Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)

目录 1.TCP的连接管理机制&#xff08;1&#xff09;三次握手①握手过程②对握手过程的理解 &#xff08;2&#xff09;四次挥手&#xff08;3&#xff09;握手和挥手的触发&#xff08;4&#xff09;状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…

UE5 学习系列(三)创建和移动物体

这篇博客是该系列的第三篇&#xff0c;是在之前两篇博客的基础上展开&#xff0c;主要介绍如何在操作界面中创建和拖动物体&#xff0c;这篇博客跟随的视频链接如下&#xff1a; B 站视频&#xff1a;s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…

【JVM】- 内存结构

引言 JVM&#xff1a;Java Virtual Machine 定义&#xff1a;Java虚拟机&#xff0c;Java二进制字节码的运行环境好处&#xff1a; 一次编写&#xff0c;到处运行自动内存管理&#xff0c;垃圾回收的功能数组下标越界检查&#xff08;会抛异常&#xff0c;不会覆盖到其他代码…

聊聊 Pulsar:Producer 源码解析

一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台&#xff0c;以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中&#xff0c;Producer&#xff08;生产者&#xff09; 是连接客户端应用与消息队列的第一步。生产者…

渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止

<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet&#xff1a; https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…

UDP(Echoserver)

网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法&#xff1a;netstat [选项] 功能&#xff1a;查看网络状态 常用选项&#xff1a; n 拒绝显示别名&#…

YSYX学习记录(八)

C语言&#xff0c;练习0&#xff1a; 先创建一个文件夹&#xff0c;我用的是物理机&#xff1a; 安装build-essential 练习1&#xff1a; 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件&#xff0c;随机修改或删除一部分&#xff0c;之后…