W5100S-EVB-PICO主动PING主机IP检测连通性(十)

前言

        上一章节我们用我们开发板在UDP组播模式下进行数据回环测试,本章我们用开发板去主动ping主机IP地址来检测与该主机之间网络的连通性。

什么是PING?

        PING是一种命令, 是用来探测主机到主机之间是否可通信,如果不能ping到某台主机,表明不能和这台主机建立连接。ping 使用的是ICMP协议,它发送icmp回送请求消息给目的主机。ICMP协议规定:目的主机必须返回ICMP回送应答消息给源主机。如果源主机在一定时间内收到应答,则认为主机可达。可以理解为ping命令是ICMP的一种形式,而ICMP属于网络层协议,因而ping也工作在网络层。

连接方式

  • 开发板直连主机
  • 开发板和主机都接在路由器LAN口

PING测试

        我们的W5100S以太网芯片,既可以通过一个socket端口开启IPRAW模式自己组包(ICMP报文)对目标IP进行ping测试,从而在软件上实现ping功能,也可以通过配置SOCKET-less命令相关寄存器,通过SOCKET-less命令直接在硬件上实现ping功能,省去了在软件上组包、解析数据包的烦恼,而且不占用socket端口,非常方便和易于实现。下面我们通过这两种方式分别进行ping测试:

1. 相关代码

1. 通过IPRAW模式实现(软件)

        我们打开库文件PING文件夹里的ping.c文件,我们主要用到这几个函数:ping_auto()、ping_request()、ping_reply()、do_ping()等,ping_request()和ping_reply()主要是ping请求的组包和收到ping回复的数据包解析,用到的数据转换和处理大家自行查看,这里我们主要看下ping_auto()函数,它通过在一个循环里构建一个状态机来对socket状态进行轮询,做出对应处理,如果端口关闭状态,就设置对应端口协议为ICMP协议,然后以IPRAW模式打开;进入IPRAW模式后,发送ping请求,然后判断是否收到或超时,收到就进行解析,之后跳出,超时则跳出,当请求数和回复数相等且为4次时结束大循环,然后将它再封装成do_ping()方便直接调用,如下所示:

/* Ping the Internet automatically. */
void ping_auto(uint8_t sn, uint8_t *addr)
{int32_t len = 0;uint8_t cnt = 0;uint8_t i;for (i = 0; i < 10; i++){if (req == rep && req == 4)break;switch (getSn_SR(sn)){case SOCK_IPRAW:ping_request(sn, addr);req++;while (1){if ((len = getSn_RX_RSR(sn)) > 0){ping_reply(sn, addr, len);sleep_ms(50);rep++;break;}else if (cnt > 200){printf("Request Time out.\r\n");cnt = 0;break;}else{cnt++;sleep_ms(50);}}break;case SOCK_CLOSED:close(sn);setSn_PROTO(sn, IPPROTO_ICMP);if (socket(sn, Sn_MR_IPRAW, 3000, 0) != 0){}while (getSn_SR(sn) != SOCK_IPRAW);sleep_ms(2000);default:break;}
#ifdef PING_DEBUGif (rep != 0){printf(" Ping Request = %d, PING_Reply = %d\r\n", req, rep);if (rep == req)printf(" PING SUCCESS\r\n ");elseprintf(" REPLY_ERROR\r\n ");}
#endif// if(rep==4)break;}
}/* ping response. */
uint8_t ping_request(uint8_t sn, uint8_t *addr)
{uint16_t i;int32_t t;ping_reply_received = 0;PingRequest.Type = PING_REQUEST;    /*Ping-Request*/PingRequest.Code = CODE_ZERO;       /*总是 '0'*/PingRequest.ID = htons(RandomID++); /*设置ping响应ID为随机的整型变量*/PingRequest.SeqNum = htons(RandomSeqNum++);for (i = 0; i < BUF_LEN; i++){PingRequest.Data[i] = (i) % 8;}PingRequest.CheckSum = 0;PingRequest.CheckSum = htons(checksum((uint8_t *)&PingRequest, sizeof(PingRequest)));t = sendto(sn, (uint8_t *)&PingRequest, sizeof(PingRequest), addr, 3000);if (t == 0){printf("\r\n Fail to send ping-reply packet  r\n");}else{printf(" 正在 Ping: %d.%d.%d.%d  \r\n", (addr[0]), (addr[1]), (addr[2]), (addr[3]));}return 0;
}/* Resolving ping reply. */
uint8_t ping_reply(uint8_t s, uint8_t *addr, uint16_t rlen)
{uint16_t tmp_checksum;uint16_t len;uint16_t i;uint8_t data_buf[128];uint16_t port = 3000;PINGMSGR PingReply;len = recvfrom(s, (uint8_t *)data_buf, rlen, addr, &port); /*从目的端接收数据*/if (data_buf[0] == PING_REPLY){PingReply.Type = data_buf[0];PingReply.Code = data_buf[1];PingReply.CheckSum = (data_buf[3] << 8) + data_buf[2];PingReply.ID = (data_buf[5] << 8) + data_buf[4];PingReply.SeqNum = (data_buf[7] << 8) + data_buf[6];for (i = 0; i < len - 8; i++){PingReply.Data[i] = data_buf[8 + i];}tmp_checksum = ~checksum(data_buf, len); /*检查ping回复的次数*/if (tmp_checksum != 0xffff)printf("tmp_checksum = %x\r\n", tmp_checksum);else{printf(" 来自 %d.%d.%d.%d 的回复: ID=%x 字节=%d \r\n",(addr[0]), (addr[1]), (addr[2]), (addr[3]), htons(PingReply.ID), (rlen + 6));ping_reply_received = 1; /*当退出ping回复循环时,设置ping回复标志为1*/}}else if (data_buf[0] == PING_REQUEST){PingReply.Code = data_buf[1];PingReply.Type = data_buf[2];PingReply.CheckSum = (data_buf[3] << 8) + data_buf[2];PingReply.ID = (data_buf[5] << 8) + data_buf[4];PingReply.SeqNum = (data_buf[7] << 8) + data_buf[6];for (i = 0; i < len - 8; i++){PingReply.Data[i] = data_buf[8 + i];}tmp_checksum = PingReply.CheckSum; /*检查ping回复次数*/PingReply.CheckSum = 0;if (tmp_checksum != PingReply.CheckSum){printf(" \n CheckSum is in correct %x shold be %x \n", (tmp_checksum), htons(PingReply.CheckSum));}else{}printf("  Request from %d.%d.%d.%d  ID:%x SeqNum:%x  :data size %d bytes\r\n",(addr[0]), (addr[1]), (addr[2]), (addr[3]), (PingReply.ID), (PingReply.SeqNum), (rlen + 6));ping_reply_received = 1; /* 当退出ping回复循环时,设置ping回复标志为1  */}else{printf(" Unkonwn msg. \n");}return 0;
}void do_ping(uint8_t sn, uint8_t *ip)
{if (req < 4){printf("------------------PING test start-----------------------\r\n");sleep_ms(1000);ping_auto(sn, ip);}else if (req == 4)close(sn);
}

2. 通过SOCKET-less命令实现(硬件)

我们找到SLping()函数,它需要我们传入两个参数:ping测试远程IP地址和ping测试次数,然后我们配置相应的SOCKET-less重传时间、重传次数、远程IP地址、中断屏蔽寄存器,然后根据传入的参数值设置ping次数,传入的值为0则将其设置为数据类型的最大值;接着在for循环里面,设置ping序列号和ID,并开启ping请求发送命令,用Switch状态机轮询中断寄存器,根据中断置位情况进行相应处理,这里分为超时和收到ping应答两个状态(情况),最后统计请求和应答成功、失败数后,进入阻塞;如下所示:

/*** socket-less ping* remote_ip:  ping ip address* ping_count: ping times, if its 0,always request to the max :65535 times.*/
void SLping(uint8_t *remote_ip, uint16_t ping_count)
{uint16_t i;static uint16_t succ_count = 0;setSLRTR(5000); // 5000 * 100us = 500mssetSLRCR(2);setSLPIPR(remote_ip);setSLIMR(0x05);if (ping_count == 0)ping_count = 65535;for (i = 0; i < ping_count; i++){printf("Ping the %d.%d.%d.%d \r\n", remote_ip[0], remote_ip[1], remote_ip[2], remote_ip[3]);setPINGSEQR(RandomSeqNum);setPINGIDR(RandomID);setSLCR(0X01);  // pingsleep_ms(2000); // waitswitch (getSLIR() & 0x07){case PING_INT:printf("Reply from %d.%d.%d.%d : ID: %x SeqNum: %x.\r\n", remote_ip[0], remote_ip[1], remote_ip[2], remote_ip[3], getPINGIDR(), getPINGSEQR());succ_count++;break;case TIMEOUT_INT:printf("Request timeout\r\n");default:break;}RandomID++;RandomSeqNum++;}printf("Ping request: %d, Succ: %d, Fail: %d.\r\n", ping_count, succ_count, (ping_count - succ_count));while (1);
}

主程序只需要初始化相关对应信息后,传入主函数循环调用即可,这里我们要进行ping测试的主机IP为我们开发板同一网段的电脑IP,如下所示:

#define SOCKET_ID 0
#define ETHERNET_BUF_MAX_SIZE (1024 * 2)void network_init(void);wiz_NetInfo net_info = {.mac = {0x00, 0x08, 0xdc, 0x16, 0xed, 0x2e},.ip = {192, 168, 1, 11},.sn = {255, 255, 255, 0},.gw = {192, 168, 1, 1},.dns = {8, 8, 8, 8},.dhcp = NETINFO_STATIC};
wiz_NetInfo get_info;
static uint8_t ethernet_buf[ETHERNET_BUF_MAX_SIZE] = {0,};
static uint8_t remote_ip[4] = {192, 168, 1, 2};int main()                                                          
{   stdio_init_all();sleep_ms(2000);network_init();while(true){do_ping(SOCKET_ID, remote_ip);// SLping(remote_ip, 4);sleep_ms(500);}
}void network_init(void)
{uint8_t temp;wizchip_initialize();printf("W5100s udp client example.\r\n");sleep_ms(2000);wizchip_setnetinfo(&net_info);print_network_information(get_info);sleep_ms(2000);   
}

2. 测试现象

编译烧录后,打开串行监视器,打开wireshark输入过滤条件<icmp>然后开启监听,可以看到在串口打印的配置信息,以及ping测试情况,wireshark的抓包情况,这里是通过软件实现的测试,硬件实现大家自行尝试;测试结果如下图所示:

相关链接

本章例程链接icon-default.png?t=N7T8https://gitee.com/wiznet-hk/w5100s-evb-pico-routine.git

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

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

相关文章

LeetCodeHot100python版本:单调栈,栈,队列,堆

单调栈 739. 每日温度 42. 接雨水 双指针 单调栈(横向求解) ​​​​​​84. 柱状图中最大的矩形 栈和队列 队列:先入先出 栈:先入后出 两个栈 模拟 队列 一个队列 可以模拟 栈 20. 有效的括号 ​​​​​​155. 最小栈 394. 字符串解码 堆 215. 数组中的第K个最大元素 (…

STM32 Cubemx 同名外设中断及回调

文章目录 前言示例工程个人理解 前言 最近在学习STM32&#xff0c;采用HAL库开发方式。记录一下同名外设中断及回调。 这里提及的同名外设指USART1/2之类的相同外设&#xff0c;但不是同一个instance。 示例工程 以使用cubemx配置两个同名外设EXTI0/EXT4为例。 在NVIC配置…

JS三座大山 —— 原型和原型链

系列文章目录 内容链接2023前端面试笔记HTML52023前端面试笔记CSS3 文章目录 系列文章目录前言一、原型是什么&#xff1f;二、原型链是什么&#xff1f;2.1 原型链全方面解析2.2 为什么构造函数也有原型&#xff1f; 总结 前言 理解原型和原型链可以帮助我们更好地理解 Java…

传统分拣弊端明显,AI机器视觉赋能物流行业包裹分类产线数智化升级

随着电子商务的快速发展&#xff0c;物流行业的包裹数量持续增长&#xff0c;给物流企业带来了巨大的运营压力。目前&#xff0c;国内大型物流运转中心已开始采用机器视觉自动化设备&#xff0c;但多数快递公司处于半自动化状态&#xff0c;中小型物流分拣中心目前仍靠人工录入…

每日一题——旋转图像

旋转图像 题目链接 方法一&#xff1a;利用辅助数组 通过对示例的观察和分析&#xff0c;我们可以得到这样的结论&#xff1a; 对于原数组的下标为i行元素&#xff0c;顺时针旋转九十度后&#xff0c;都变成了下标为&#xff08;n-1-i&#xff09;列元素。如图所示&#xff…

代替forever下一个部署node的持久化工具---pm2

最近有个后端项目&#xff0c;用的是node&#xff0c;在持久化的时候会挂掉&#xff0c;详细了解到用的是nohup&#xff0c;然后先详细了解了一下nohup nohup是一个Linux命令&#xff0c;用于在系统后台不挂断地运行命令&#xff0c;退出终端不会影响程序的运行1nohup的英文全称…

基于RabbitMQ的模拟消息队列需求文档

文章目录 一、项目背景二、需求分析1.核心概念2.BrokerServer核心组件3.核心API4.交换机类型5.持久化6.网络通信7.消息应答 三、消息队列模块划分 一、项目背景 什么是消息队列&#xff1f; 消息队列就是&#xff0c;基于阻塞队列&#xff0c;封装成一个独立的服务器程序&#…

Nginx百科之gzip压缩、黑白名单、防盗链、零拷贝、跨域、双机热备

引言 早期的业务都是基于单体节点部署&#xff0c;由于前期访问流量不大&#xff0c;因此单体结构也可满足需求&#xff0c;但随着业务增长&#xff0c;流量也越来越大&#xff0c;那么最终单台服务器受到的访问压力也会逐步增高。时间一长&#xff0c;单台服务器性能无法跟上业…

three.js渲染带动画的glb文件

1. 准备工作 将下列文件在three.js的包中找到&#xff0c;注意的是我这里使用的是模块化版本的&#xff0c;这里不知道模块化的&#xff0c;可以先去看一下es6的模块化。 控制器&#xff1a; OrbitControls.js 加载器&#xff1a;GLTFLoader.js 材质&#xff1a; RoomEnvironm…

数据时代的必备利器:数据可视化工具的崭新价值

在当今信息时代&#xff0c;数据扮演着越来越重要的角色&#xff0c;而数据的可视化呈现正是一种强大的工具&#xff0c;能够帮助我们更好地理解和利用这些数据。虽然Excel和PPT在处理数据方面有着不可否认的作用&#xff0c;但在处理大规模、复杂数据时&#xff0c;数据可视化…

微信小程序 基于Android的美容理发师预约管理系统

&#xff0c;本系统主要根据管理员、用户及理发师的实际需要&#xff0c;方便用户利用互联网实现对商品信息进行立即订购&#xff0c;同时让管理者可以通过这个系统对用户实际需求以及各信息进行管理。设计该系统主要目的是为了方便用户、理发师可以有一个非常好的平台体验&…

文心一言 VS 讯飞星火 VS chatgpt (84)-- 算法导论8.2 1题

一、用go语言&#xff0c;参照图8-2 的方法&#xff0c;说明 COUNTING-SORT 在数组 A(6&#xff0c;0&#xff0c;2&#xff0c;0&#xff0c;1&#xff0c;3&#xff0c;4&#xff0c;6&#xff0c;1&#xff0c;3&#xff0c;2)上的操作过程。 文心一言&#xff1a; Counti…

现货黄金走势图中的止盈点

对平仓时机的把握能力&#xff0c;是衡量现货黄金投资者水平的重要标志&#xff0c;止盈点设置得是否合理&#xff0c;在行情兑现的时候能否及时地离场&#xff0c;是事关投资者账户浮盈最终能否落袋为安的“头等大事”&#xff0c;要在现货黄金走势图中把握止盈点&#xff0c;…

Linux-安装redis6.2.1及主备复制模式(replication)

Linux-安装redis6.2.1 下载redis6.2.1资源上传至安装目录解压及编译解压修改名称编译 修改配置文件主节点从节点 启动及测试启动主节点从节点 测试 下载redis6.2.1资源 地址》https://redis.io/download/ 上传至安装目录 例&#xff1a;/data/replication/ 解压及编译 解…

【kubernetes系列】Calico原理及配置

概述 Calico是针对容器&#xff0c;虚拟机和基于主机的本机工作负载的开源网络和网络安全解决方案。 Calico支持广泛的平台&#xff0c;包括Kubernetes&#xff0c;OpenShift&#xff0c;Docker EE&#xff0c;OpenStack和裸机服务。 Calico在每个计算节点都利用Linux Kernel实…

DP4863 国产双声道音频功率放大器芯片

产品概述&#xff1a; DP4863 电路是一种双声道桥接音频功率放大器。在 5 V 电源电压下&#xff0c;它能向 4 Ω 负载提供 2.2 W 的输出功率&#xff0c;或向 3 Ω 负载提供 2.5 W的输出功率&#xff0c;THD N 小于 1 %。此外&#xff0c;它还具有耳机输入端&#xff0c;可驱…

《Go 语言第一课》课程学习笔记(十四)

接口 认识接口类型 接口类型是由 type 和 interface 关键字定义的一组方法集合&#xff0c;其中&#xff0c;方法集合唯一确定了这个接口类型所表示的接口。type MyInterface interface {M1(int) errorM2(io.Writer, ...string) }我们在接口类型的方法集合中声明的方法&#…

博士后申请有哪些技巧?

在博士后申请过程中&#xff0c;有一些关键的技巧可以帮助申请者提高成功的机会。以下是知识人网小编的一些建议&#xff1a; 1.精选合适的导师和研究课题&#xff1a;选择与自己研究方向相关且感兴趣的导师和课题非常重要。导师的声誉、研究成果和合作风格都会影响你的博士后经…

智慧工地源码带开发手册文档 app 数据大屏、硬件对接、萤石云

智慧工地解决方案依托计算机技术、物联网、云计算、大数据、人工智能、VR、AR等技术相结合&#xff0c;为工程项目管理提供先进技术手段&#xff0c;构建工地现场智能监控和控制体系&#xff0c;弥补传统方法在监管中的缺陷&#xff0c;最终实现项目对人、机、料、法、环的全方…

黑马程序员上课笔记 P2 JAVA 前置课CMD的使用

引入&#xff1a; 一、人机交互 人机交互的故事&#xff1a; 计算机刚出现的时候的三个特点&#xff0c;占地广 造价高 耗电多 故事&#xff1a; 在计算机的历史中&#xff0c;人机交互&#xff08;Human-Computer Interaction&#xff0c;简称HCI&#xff09;一直在不断地…