完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
一、STM32CubeMX配置:
这里展示几个关键配置 1.打开ICMP功能,这个也是默认打开的。ping使用的就是ICMP协议 2.设置RAW模式接收字节数,这里默认是0,设置成和TCP、UDP一样 3.设置以太网中断优先级,这里需要调低,不然在freeRTOS中卡住,裸机中可不用设置 二、生成的代码中更改一些配置: 1.打开RAW功能 2.打开接收超时 三、代码 1.变量定义 typedef struct icmp_hdr { unsigned char icmp_type; // 消息类型 unsigned char icmp_code; // 代码 unsigned short icmp_checksum; // 校验和 // 下面是回显头 unsigned short icmp_id; // 用来惟一标识此请求的ID号 unsigned short icmp_sequence; // 序列号 unsigned long icmp_timestamp; // 时间戳 } ICMP_HDR, *PICMP_HDR; typedef struct _IPHeader// 20字节的IP头 { uint8_t iphVerLen; // 版本号和头长度(各占4位) uint8_t ipTOS; // 服务类型 uint16_t ipLength; // 封包总长度,即整个IP报的长度 uint16_t ipID; // 封包标识,惟一标识发送的每一个数据报 uint16_t ipFlags; // 标志 uint8_t ipTTL; // 生存时间,就是TTL uint8_t ipProtocol; // 协议,可能是TCP、UDP、ICMP等 uint16_t ipChecksum; // 校验和 uint32_t ipSource; // 源IP地址 uint32_t ipDestination; // 目标IP地址 } IPHeader, *PIPHeader; typedef int SOCKET; 2.实现代码 int ETH_PingWork(const char * szDestIp) { long nRet = 0; /*****************第一步:申请SOCKET************************************/ uint32_t ip = inet_addr(szDestIp); SOCKET sRaw = lwip_socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); if(sRaw == -1) { printf("Cannot create socket! Error %drn", errno); return errno; } // 设置接收超时 struct timeval tv_out; tv_out.tv_sec = 1; tv_out.tv_usec = 0; nRet = setsockopt(sRaw, SOL_SOCKET,SO_RCVTIMEO, &tv_out, sizeof(tv_out)); if(-1 == nRet) { printf("Cannot set timeout! %d rn",errno); } /*****************第二步:组ICMP包************************************/ // 创建ICMP封包 char buff[sizeof(ICMP_HDR) + 32]; ICMP_HDR* pIcmp = (ICMP_HDR*)buff; // 填写ICMP封包数据 pIcmp->icmp_type = 8; // 请求一个ICMP回显 pIcmp->icmp_code = 0; pIcmp->icmp_id = (uint16_t)0x1234; pIcmp->icmp_checksum = 0; pIcmp->icmp_sequence = 0; pIcmp->icmp_timestamp = 0xffff; // 填充数据部分,可以为任意 memset(&buff[sizeof(ICMP_HDR)], 'E', 32); /*****************第三步:发送ICMP包************************************/ //设置目的地址 struct sockaddr_in dest; dest.sin_family = AF_INET; dest.sin_port = htons(0); dest.sin_addr.s_addr = ip; //pIcmp->icmp_checksum = checksum((uint16_t*)buff, sizeof(ICMP_HDR) + 32); //如果ping过去没回应需要屏蔽这条 //printf("icmp_checksum = %xrn",pIcmp->icmp_checksum); nRet = (long)sendto(sRaw, buff, sizeof(ICMP_HDR) + 32, 0, (struct sockaddr *)&dest, sizeof(dest)); if(nRet == -1) { printf(" sendto() failed: %d rn", errno); return -1; } printf("sendto = %ldrn",nRet); /*****************第四步:接收ICMP包************************************/ char recvBuf[1024]; struct sockaddr_in from; socklen_t nLen = sizeof(from); nRet = (long)recvfrom(sRaw, recvBuf, 1024, 0, (struct sockaddr *)&from, &nLen); if(nRet == -1) { printf(" recvfrom() failed: %drn", errno); return -1; } printf("recvfrom = %ldrn",nRet); /*****************第五步:解析ICMP包************************************/ if(nRet < sizeof(IPHeader) + sizeof(ICMP_HDR)) { printf(" Too few bytes from %s rn", inet_ntoa(from.sin_addr)); } #if 0 // IP头解析 IPHeader * header = (IPHeader*)recvBuf; struct in_addr a; a.s_addr = header->ipSource; printf("source ip %sn", inet_ntoa(a)); a.s_addr = header->ipDestination; printf("dest ip %sn", inet_ntoa(a)); #endif ICMP_HDR* pRecvIcmp = (ICMP_HDR*)(recvBuf + 20); // 接收到的数据中包含IP头,IP头大小为20个字节,所以加20得到ICMP头 if(pRecvIcmp->icmp_type != 0)// 回显 { printf("nonecho type %d recvd rn", pRecvIcmp->icmp_type); return -1; } if(pRecvIcmp->icmp_id != 0x1234) { printf(" someone else's packet! rn"); return -1; } printf(" %d bytes from %s:", (int)nRet, inet_ntoa(from.sin_addr)); printf(" icmp_seq = %d. ", pRecvIcmp->icmp_sequence); printf(" rn"); return 0; } |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1617 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1543 浏览 1 评论
977 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
683 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1595 浏览 2 评论
1863浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
644浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
515浏览 3评论
531浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
504浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-22 03:20 , Processed in 0.575163 second(s), Total 47, Slave 40 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号