• [问题求助] 小熊派【智能烟感】模块学习中遇到的几个问题(问题已解决,附带解决方法)
    【功能模块】https://bbs.huaweicloud.com/forum/thread-190006-1-1.html【操作步骤&问题现象】1、步骤六选择方案①和WiFi模块,紧跟步骤完成后,最终设备连接WiFi后成功上云,但是不能够实时上传属性数据多次从头按照步骤做之后还是相同的结果,恳求成功的小伙伴的帮助2、步骤六中可选方案①+NB35-A通信扩展板或者方案①+WiFi通信扩展板,均为使用CoAP协议的方案①,如果想用方案②(即MQTT协议),代码需要如何改动?3、步骤六的第三步协议接入地址可否使用华为云IoTDA中的接入地址,我在1、中的代码输入IoTDA总览中的接入地址,结果是设备显示为"未激活"状态,改为与教程中相同的"119.3.250.80"后设备成功变为"在线"状态,若使用MQTT协议,除去接入端口改为"1883"外,接入地址该改为什么?解决方法:1、问题所在:在网站下载并导入的CoAP图形化开发的messageId与工程代码中oc_smoke_template.c中的数据结构体不同,以及Smoke_Value在下载并导入的文件中为String而实际上为int16u解决方式:到创建产品处的"插件开发"-“图形化开发”修改字段数据,如图2&&3、参考楼下版主大大回答
  • [问题求助] SDC APP怎么和公网地址建立tcp连接
    使用SDC的tproxy.paas.sdc服务,为啥只能连接和摄像头同个网段的地址,没法访问公网IP
  • [技术干货] STM32入门开发 制作红外线遥控器(智能居家-万能遥控器)
    # 一、环境介绍 **MCU:** STM32F103ZET6 **编程软件环境:** keil5 **红外线传输协议:** NEC协议---38KHZ载波:。NEC协议是红外遥控协议中常见的一种。 **编码发送思路:** 延时函数模拟38KHZ + PWM产生38KHZ两种方式 **代码风格:** 模块化编程,寄存器直接操作方式 # 二、NEC协议与相关硬件介绍 ## **2.1 NEC协议介绍** 红外线协议有很多,本章节主要是针对NEC协议讲解,只要把NEC协议原理搞懂了,其他协议都是一样的使用;如果想要模拟空调遥控器,去控制美的空调、格力空调这些设备,就需要按照美的、格力空调的协议发送;如果不知道协议长什么样,可以将逻辑分析仪插在红外线接收头的引脚上,拿个正常的空调遥控器对着接收头按一下,然后采集数据分析,即可得到协议规律,然后网络上也有空调按键值功能的说明文档,调试一下即可。 ## 2. 2 使用的相关硬件 因为要模拟红外线遥控器,就需要一个红外线发射管;在学习阶段,如果不想自己搭建电路,可以买现成的模块。 买模块连接也是比较稳定,接线也比较简单,VCC和GND接好之后,把DAT引脚接到STM32任意一个IO口上即可,如果想用硬件PWM控制发送,那么引脚接到STM32的PWM输出脚即可。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20228/4/1659578809866557777.png) ## **2.3 完成NEC协议编码发送** **先看一段红外线接收头引脚上采集的NEC协议的电平: 这是接收端采集的。** ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20228/4/1659578823013799853.png) **红外线接收头的硬件特性:** (注意: 这里是针对NEC遥控器协议来说明),下图就是当前使用的红外线接收头。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20228/4/1659578836334252529.png) 收到38KHZ的红外光,IN引脚就输出低电平;没有收到IN引脚就输出高电平。 **NEC红外线协议说明:(这是站在接收端解码的角度分析的)** 一段独立的NEC协议数据包由引导码+32位数据组成。 引导码: 9ms的高电平 + 4.5ms 低电平组成。 32位数据就是: 8位用户码+ 8位用户反码+ 8位按键码+8位按键反码 每个数据位之间的间隔时间是0.56ms(低电平) NEC协议是依靠收到的高电平持续时间来判断数据0和数据1;高电平持续时间是0.56ms表示数据0,高电平持续时间是1.68ms表示数据1。 只要明白上面说的两个特点,就可以写程序,按照NEC协议驱动红外线发射管,发送数据了。 **编写发送程序之前,得先明白这个38KHZ的红外光如何产生?** STM32支持硬件PWM功能,可以配置38KHZ方波输出;如果没有硬件PWM功能的单片机,也可以使用延时的方式产生38KHZ方波,差那么一点点问题也不到,解码端适当调整一下时间范围即可。 **采用延时函数实现方法如下:** ```cpp /* 函数功能: 发送38KHZ的载波 函数参数: u32 time_us 持续的时间 u8 flag 1表示发送38KHZ载波,0表示不发送 */ void InfraredSend38KHZ(u32 time_us,u8 flag) { u32 i; if(flag) { //发送38KHZ载波 for(i=0;i13;i++) { INFRARED_OUTPUT=!INFRARED_OUTPUT; DelayUs(13); } } else { INFRARED_OUTPUT=1;//关闭红外线发射管 DelayUs(time_us); } } ``` **为了方便发送指定的用户码和按键码,可以封装成一个函数调用。** ```cpp /* 函数功能: NEC协议编码发送 函数参数: u8 user 用户码 u8 key 按键码 先发低位 按键反码+按键码+用户反码+用户码 */ void InfraredNECSend(u8 user,u8 key) { u32 i; /*1. 组合发送的数据*/ u32 data=((~key&0xFF)24)|((key&0xFF)16)|((~user&0xFF)8)|((user&0xFF)0); /*2. 发送引导码*/ InfraredSend38KHZ(9000,1);//发送38KHZ载波 InfraredSend38KHZ(4500,0);//不发送 /*3. 发送32位数据*/ for(i=0;i32;i++) { InfraredSend38KHZ(560,1); //间隔时间 if(data&0x01)InfraredSend38KHZ(1685,0); //发送1 else InfraredSend38KHZ(560,0); //发送0 data>>=1; } InfraredSend38KHZ(560,1); //间隔时间 } ``` **这是使用逻辑分析仪采集的发送端波形: 和协议对应了一下,没有问题。** ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20228/4/1659578853558645546.png) **对比一下解码端采集的波形图:** ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20228/4/1659578864976399017.png) # 三、核心代码 ## 3.1 main.c ```cpp #include "stm32f10x.h" #include "beep.h" #include "delay.h" #include "led.h" #include "key.h" #include "sys.h" #include "usart.h" #include #include #include "exti.h" #include "timer.h" #include "rtc.h" #include "adc.h" #include "ds18b20.h" #include "ble.h" #include "esp8266.h" #include "wdg.h" #include "oled.h" #include "rfid_rc522.h" #include "infrared.h" int main() { LED_Init(); KEY_Init(); BEEP_Init(); TIM1_Init(72,20000); //辅助串口1接收,超时时间为20ms USART_X_Init(USART1,72,115200); //InfraredDecodeInit(); //红外线解码初始化 InfraredCodingInit(); //红外线编码初始化 printf("UART1 OK.....\n"); while(1) { InfraredNECSend(13,14); //发送红外线数据 DelayMs(500); LED0=!LED0; } } ``` ## 3.2 红外线.c ```cpp #include "infrared.h" /* 函数功能: 红外线编码初始化 硬件连接: PG11 编码思路: 采用延时函数实现38KHZ */ void InfraredCodingInit(void) { RCC->APB2ENR|=18; //PG GPIOG->CRH&=0xFFFF0FFF; GPIOG->CRH|=0x00003000; GPIOG->ODR|=111; } /* 函数功能: 发送38KHZ的载波 函数参数: u32 time_us 持续的时间 u8 flag 1表示发送38KHZ载波,0表示不发送 */ void InfraredSend38KHZ(u32 time_us,u8 flag) { u32 i; if(flag) { //发送38KHZ载波 for(i=0;i13;i++) { INFRARED_OUTPUT=!INFRARED_OUTPUT; DelayUs(13); } } else { INFRARED_OUTPUT=1;//关闭红外线发射管 DelayUs(time_us); } } /* 函数功能: NEC协议编码发送 函数参数: u8 user 用户码 u8 key 按键码 先发低位 按键反码+按键码+用户反码+用户码 */ void InfraredNECSend(u8 user,u8 key) { u32 i; /*1. 组合发送的数据*/ u32 data=((~key&0xFF)24)|((key&0xFF)16)|((~user&0xFF)8)|((user&0xFF)0); /*2. 发送引导码*/ InfraredSend38KHZ(9000,1);//发送38KHZ载波 InfraredSend38KHZ(4500,0);//不发送 /*3. 发送32位数据*/ for(i=0;i32;i++) { InfraredSend38KHZ(560,1); //间隔时间 if(data&0x01)InfraredSend38KHZ(1685,0); //发送1 else InfraredSend38KHZ(560,0); //发送0 data>>=1; } InfraredSend38KHZ(560,1); //间隔时间 } ``` # 四、格力空调遥控协议介绍 ## 4.1 协议解析 报头脉冲:9ms 报头间距:4.5ms 载波频率:37.9KHz(38KHz) 码段1与码段2间距:20ms “1”:脉宽,656us。间距,1640us。 “0”:脉宽,656us。间距,544us。 ## 4.2 编码定义 1-3位:模式 送风:图标:风扇。代码:110。 自动:图标:循环箭头。代码:000。 除湿:图标:水滴。代码:010。 制冷:图标:雪花。代码:100。 制热:图标:太阳。代码:001。 4位(加68位):开机关机 开机:1。 关机:0。第68位取反。 5-6位:风速 一级:10 二级:01 三级:11 自动:00 7、37、41位(加65位):扫风 上下扫风:110。第65位取反 左右扫风:101。 上下左右:111 无扫风:000 8位:睡眠 睡眠:1 不睡眠:0 9-12位与65-68位:温度 制冷模式下: | 温度 | 9-12位 | 65-68位 | | ---- | -------- | -------- | | 30 | **0111** | **1000** | | 29 | **1011** | **0000** | | 28 | **0011** | **1111** | | 27 | **1101** | **0111** | | 26 | **0101** | **1011** | | 25 | **1001** | **0011** | | 24 | **0001** | **1101** | | 23 | **1110** | **0101** | | 22 | **0110** | **1001** | | 21 | **1010** | **0001** | | 20 | **0010** | **1110** | | 19 | **1100** | **0110** | | 18 | **0100** | **1010** | | 17 | **1000** | **0010** | | 16 | **0000** | **1100** | 制热模式: | 温度 | 9-12位 | 65-68位 | | ---- | -------- | -------- | | 30 | **0111** | **0010** | | 29 | **1011** | **1100** | | 28 | **1101** | **0100** | | 27 | **1101** | **1000** | | 26 | **0101** | **0000** | | 25 | **1001** | **1111** | | 24 | **0001** | **0111** | | 23 | **1110** | **1011** | | 22 | **0110** | **0011** | | 21 | **1010** | **1101** | | 20 | **0010** | **0101** | | 19 | **1100** | **1001** | | 18 | **0100** | **0001** | | 17 | **1000** | **1110** | | 16 | **0000** | **0110** | 吸湿模式: | 温度 | 9-12位 | 65-68位 | | ---- | -------- | -------- | | 30 | **0111** | **0100** | | 29 | **1011** | **1000** | | 28 | **0011** | **0000** | | 27 | **1101** | **1111** | | 26 | **0101** | **0111** | | 25 | **1001** | **1011** | | 24 | **0001** | **0011** | | 23 | **1110** | **1101** | | 22 | **0110** | **0101** | | 21 | **1010** | **1001** | | 20 | **0010** | **0001** | | 19 | **1100** | **1110** | | 18 | **0100** | **0110** | | 17 | **1000** | **1010** | | 16 | **0000** | **0010** | 送风模式: | 温度 | 9-12位 | 65-68位 | | ---- | -------- | -------- | | 30 | **0111** | **1100** | | 29 | **1011** | **0100** | | 28 | **0011** | **1000** | | 27 | **1101** | **0000** | | 26 | **0101** | **1111** | | 25 | **1001** | **0111** | | 24 | **0001** | **1011** | | 23 | **1110** | **0011** | | 22 | **0110** | **1101** | | 21 | **1010** | **0101** | | 20 | **0010** | **1001** | | 19 | **1100** | **0001** | | 18 | **0100** | **1110** | | 17 | **1000** | **0110** | | 16 | **0000** | **1010** | 13-20位:睡眠定时 | 时间 | 13-20位 | | ---- | ------------ | | 0.5 | **10010000** | | 1 | **00011000** | | 1.5 | **10011000** | | 2 | **00010100** | | 2.5 | **10010100** | | 3 | **00011100** | | 3.5 | **10011100** | | 4 | **00010010** | | 4.5 | **10010010** | | 5 | **00011010** | | 5.5 | **10011010** | | 6 | **00010110** | | 6.5 | **10010110** | | 7 | **00011110** | | 7.5 | **10011110** | | 8 | **00010001** | | 8.5 | **10010001** | | 9 | **00011001** | | 9.5 | **10011001** | | 10 | **01010000** | | 10.5 | **11010000** | | 11 | **01011000** | | 11.5 | **11011000** | | 12 | **01010100** | | 12.5 | **11010100** | | 13 | **01011100** | | 13.5 | **11011100** | | 14 | **01010010** | | 14.5 | **11010010** | | 15 | **01011010** | | 15.5 | **11011010** | | 16 | **01010110** | | 16.5 | **11010110** | | 17 | **01011110** | | 17.5 | **11011110** | | 18 | **01010001** | | 18.5 | **11010001** | | 19 | **01011001** | | 19.5 | **11011001** | | 20 | **00110000** | | 20.5 | **10110000** | | 21 | **00111000** | | 21.5 | **10111000** | | 22 | **00110100** | | 22.5 | **10110100** | | 23 | **00111100** | | 23.5 | **10111100** | | 24 | **00110010** | | 0 | **00000000** | 21位:超强 超强:1 普通:0 22位:灯光 亮:1 灭:0 23位与25位:健康,换气 健康:10 换气:01 健康+换气:11 普通:00 24位:制冷模式下-干燥;制热模式下-辅热; 干燥:1 普通:0 45-46位:显示温度 不显示:00 显示:10 显示室内温度:01 显示室外温度:11 其他位: 除了29、31、34位为“1”外,均为“0”。其他位功能不详(遥控器无对应项)。 第36位和69位分别是码段1和码段2的最后一位,无所谓“0”“1”。 ## 4.3 其他说明 在自动模式下只可以设置的项目有:风速1、2、3级、自动;上上下左右扫风;显示温度;灯光;睡眠定时(非睡眠)。其他项均不可以设置。此时温度不可设置,温度段的代码为:10011101。 在关机状态下,可以设置定时开机,代码与睡眠定时关机一样。也可以设置灯光。 在制冷模式下,可以设置的项有:温度;扫风;健康换气,节能(仅在此状态下可以设置);风速;定时;超强;睡眠;灯光;温度显示。 在除湿模式下,可以设置的项有:温度;扫风;健康换气;干燥;温度显示;定时;睡眠;灯光。 在送风模式下,可以设置的项有:温度;风速;健康换气;扫风;温度显示;定时;灯光。 在制热模式下,可以设置的项有:温度;风速;扫风;辅热;温度显示;定时;超强;睡眠;灯光。 MGQ 2012-04-141、 格力YB0F2红外信号命令格式 红外信号主要包括CMD1和CMD2两部分,其中CMD1包括35 位的命令 和一位停止位,CMD2包括32位的命令和一位停止位。 # 五、美的空调协议介绍 L为引导码, S为分隔码, A为认别码(A=10110010=B2,预留方案时A=10110111=B7), A'为A的反码, B'为B的反码, C'为C的反码 遥控器发射红外信号之时,通过“560微秒低电平+1680微秒高电平”代表“1”,通过“560微秒低电平+560微秒低电平”代表“0”。 **美的的红外采用NEC格式的R05d** 该协议的红外信号编码格式为:**引导码+客户码+客户反码+数据码+数据反码+结束位**, 其中引导码和结束码都是固定的,数据反码由数据码按位取反得来,真正变化的只有用户码和数据码。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20228/4/1659578895902229753.png)
  • [技术干货] 网络参考模型与标准协议
    网络参考模型OSI(Open System Interconnect),即开放式系统互连。OSI参考模型,是ISO组织在1985年研究的网络互连模型,该体系结构标准定义了网络互连的七层框架(物理层、数据链路层、网络层、传输层、会话层、表示层和应用层):7.应用层对应用程序提供接口6.表示层进行数据格式的转换,以确保一个系统生成的应用层数据能够被另外一个系统的应用层所识别和理解。5.会话层在通信双方之间建立、管理和终止会话。4.传输层建立、维护和取消一次端到端的数据传输过程。控制传输节奏的快慢,调整数据的排序等等。3.网络层定义逻辑地址;实现数据从源到目的地的转发。2.数据链路层将分组数据封装成帧;在数据链路上实现数据的点到点、点到多点方式的直接通信;差错检测。1.物理层在媒介上传输比特流;提供机械的和电器的规约。因为OSI协议栈比较复杂,且TCP和IP两大协议在业界被广泛使用,所以TCP/IP模型成为了互联网的主流参考模型,目前我们常用的是TCP/IP对等模型。三者的对应关系如下图所示: 标准协议在TCP/IP对等模型中,常用协议如下: 应用层HTTP(Hypertext Transfer Protocol,超文本传输协议):是互联网应用最为广泛的一种网络协议,用来访问在网页服务器上的各种页面。FTP(File Transfer Protocol,文件传输协议):是一个从一台主机传送文件到另一台主机的协议,用于文件的“下载”和“上传”。Telnet(Telecommunication Network Protocol,电信网络协议):是数据网络中提供远程登录服务的标准协议。为用户提供了在本地计算机上完成远程设备工作的能力。SSH(Secure Shell,安全外壳):允许在本地计算机和远程计算机之间建立安全渠道,以保护网络不受诸如IP地址欺诈、简单口令截取等攻击。SNMP(Simple Network Management Protocol,简单网络管理协议):该协议允许远程用户查看和修改网元的管理信息。DNS(Domain Name Service,域名称解析服务):用于实现从主机域名到IP地址之间的转换。传输层TCP(Transmission Control Protocol,传输控制协议):为应用程序提供可靠的面向连接的通信服务。目前,许多流行的应用程序都使用TCP。UDP(User Datagram Protocol,用户数据报协议):提供了无连接通信,且不对传送数据包进行可靠性的保证。网络层 IP(Internet Protocol,互联网协议):将传输层的数据封装成数据包并完成源站点到目的站点的转发,提供无连接的、不可靠的服务。 IGMP(Internet Group Management Protocol,因特网组管理协议):负责IP组播 成员管理的协议。它用来在IP主机和与其直接相邻的组播路由器之间建立、维护组播组成员关系。 ICMP(Internet Control Message Protocol,网际报文控制协议):基于IP协议在网 络中发送控制消息,提供可能发生在通信环境中的各种问题反馈。通过这些信息,使管理者可以对所发生的问题作出诊断,然后采取适当的措施解决。ARP(Address Resolution Protocol,地址解析协议):根据已知的IP地址解析获得其对应的MAC地址。 
  • [技术干货] 基于CC2530_ZigBee+华为云IOT设计的冷链信息采集系统
    ## 1. 前言 近年来,随着人们消费需求的不断提高,连锁超市、便利店、大卖场等商超不但提供了各种各样的新鲜食品,而且采用统一进货和冷链储藏的方式,从而不但使得商品质量有保证,而且购物环境良好,越来越成为人们购物的主要场所。超市作为冷链物流产品的末端,在分销以及零售过程中都对产品质量、运营成本和功耗等方面有着较高的要求,而冷链系统的压力参数作为保证这一品质的重要参数之一,实现智能压力检测和控制对于时刻掌握冷链的工作状态非常重要,可以保证运营的安全性和经济性。因此,如果能够设计一款针对冷链系统数据采集系统,就可以实现对冷链系统进行实时监控,达到经济性运营的目的,对提高企业经济效益具有非常重要的意义。 ## 2. 设计需求 以CC2530单片机为核心器件,设计一个冷链环境信息采集系统,利用传感器技术对冷藏仓内的环境参数进行采集,上传到物联网云平台,然后通过手机端或移动端进行显示,便于分析,观察冷链环境信息。 **硬件选型:** (1)ESP8266-WIFI 用于与上位机进行通信,实现数据传输 (2)CC2530单片机,本身是51内核,与普通的51单片机编程一样,它内部多了一个ZigBee 模块,能实现ZigBee 组网。 (3)DHT11 温湿度传感器。这是一款有已校准数字信号输出的温湿度传感器。 其精度湿度±5%RH, 温度±2℃,量程湿度5~95%RH, 温度-20~+60℃。 (4)蜂鸣器。当设置阀值超出标准时,可以发出警报提醒。 ![image.png](https://bbs-img.huaweicloud.com/blogs/img/20220731/1659279732830585909.png) ## 3. 硬件选型 ### 3.1 CC2530+WIFI模块 ![image.png](https://bbs-img.huaweicloud.com/blogs/img/20220731/1659279753001899460.png) ### 3.2 DHT11温湿度模块 ![image.png](https://bbs-img.huaweicloud.com/blogs/img/20220731/1659279760592727149.png) ### 3.3 蜂鸣器 ![image.png](https://bbs-img.huaweicloud.com/blogs/img/20220731/1659279768676884068.png) ## 4. 物联网云端配置与应用 ### 4.1 华为云IoTDA介绍 当前的设计中,用的物联网平台服务是华为云的设备接入服务(IoTDA),IoTDA提供海量设备连接上云、设备和云端双向消息通信、批量设备管理、远程控制和监控、OTA升级、设备联动规则等能力,并可将设备数据灵活流转到华为云其他服务。 使用物联网平台构建一个完整的物联网解决方案主要包括3部分:物联网平台、业务应用和设备。 物联网平台作为连接业务应用和设备的中间层,屏蔽了各种复杂的设备接口,实现设备的快速接入;同时提供强大的开放能力,支撑行业用户构建各种物联网解决方案。 设备可以通过固网、2G/3G/4G/5G、NB-IoT、Wifi等多种网络接入物联网平台,并使用LWM2M/CoAP、MQTT、HTTPS协议将业务数据上报到平台,平台也可以将控制命令下发给设备。 业务应用通过调用物联网平台提供的API,实现设备数据采集、命令下发、设备管理等业务场景。 ![image.png](https://bbs-img.huaweicloud.com/blogs/img/20220731/1659280917897611126.png) 接下来就详细把整个物联网平台的使用流程进行介绍。 ### 4.1 产品创建 地址: https://www.huaweicloud.com/ ![image.png](https://bbs-img.huaweicloud.com/blogs/img/20220801/1659318767539998388.png) ![image.png](https://bbs-img.huaweicloud.com/blogs/img/20220801/1659318802477698241.png) 查看平台接入地址: ![image.png](https://bbs-img.huaweicloud.com/blogs/img/20220801/1659318845861398118.png) ![image.png](https://bbs-img.huaweicloud.com/blogs/img/20220801/1659318867179517617.png) 点击右上角创建产品: ![image.png](https://bbs-img.huaweicloud.com/blogs/img/20220801/1659318931101336875.png) 根据自己的产品信息填充: ![image.png](https://bbs-img.huaweicloud.com/blogs/img/20220801/1659318973051411162.png) ![image.png](https://bbs-img.huaweicloud.com/blogs/img/20220801/1659318986372396640.png) 根据产品的传感器属性创建服务器的属性字段: ![image.png](https://bbs-img.huaweicloud.com/blogs/img/20220801/1659319951835193774.png) ![image.png](https://bbs-img.huaweicloud.com/blogs/img/20220801/1659319979909306876.png) ![image.png](https://bbs-img.huaweicloud.com/blogs/img/20220801/1659320015048106243.png) ![image.png](https://bbs-img.huaweicloud.com/blogs/img/20220801/1659320035868499555.png) ![image.png](https://bbs-img.huaweicloud.com/blogs/img/20220801/1659320092203499175.png) ### 4.2 设备创建 详细创建流程,看下面的截图: ![image.png](https://bbs-img.huaweicloud.com/blogs/img/20220801/1659319015895225162.png) ![image.png](https://bbs-img.huaweicloud.com/blogs/img/20220801/1659319074944475729.png) ![image.png](https://bbs-img.huaweicloud.com/blogs/img/20220801/1659319089733402686.png) 保存设备信息,接下来的MQTT登录需要使用。 ```cpp { "device_id": "62e732be3a884835598654f7_dev1", "secret": "12345678" } ``` ### 4.3 MQTT三元组信息生成 在这里可以使用华为云提供的工具快速得到MQTT三元组进行登录。 [https://support.huaweicloud.com/devg-iothub/iot_01_2127.html#ZH-CN_TOPIC_0240834853__zh-cn_topic_0251997880_li365284516112](https://support.huaweicloud.com/devg-iothub/iot_01_2127.html#ZH-CN_TOPIC_0240834853__zh-cn_topic_0251997880_li365284516112) ![image.png](https://bbs-img.huaweicloud.com/blogs/img/20220801/1659320198725137713.png) 工具的页面地址: [https://iot-tool.obs-website.cn-north-4.myhuaweicloud.com/](https://iot-tool.obs-website.cn-north-4.myhuaweicloud.com/) 根据提示填入信息,然后生成三元组信息即可。 这里填入的信息就是在创建设备的时候生成的信息。 ![image.png](https://bbs-img.huaweicloud.com/blogs/img/20220801/1659320259478396144.png) ```cpp ClientId 62e732be3a884835598654f7_dev1_0_0_2022080102 Username 62e732be3a884835598654f7_dev1 Password 13483ebeadd786ea107527a3c92c5463a8f3c71377cd33276143ffe2fb85c1dc ``` ### 4.4 MQTT主题订阅与发布格式 ```cpp //订阅主题: 平台下发消息给设备 $oc/devices/62e732be3a884835598654f7_dev1/sys/messages/down //设备上报数据 $oc/devices/62e732be3a884835598654f7_dev1/sys/properties/report //上报的属性消息 (一次可以上报多个属性,在json里增加就行了) {"services": [{"service_id": "server_id","properties":{"温度":23.4}},{"service_id": "server_id","properties":{"湿度":80.5}}]} ``` ### 4.5 设备模拟登录测试 ![image.png](https://bbs-img.huaweicloud.com/blogs/img/20220801/1659320841996720300.png) ![image.png](https://bbs-img.huaweicloud.com/blogs/img/20220801/1659320861395753895.png) ### 4.6 应用侧开发接口介绍 在设备上云之后,为了能方便管理设备,方便用户设备入网,都需要开发一款手机APP或者微信小程序、桌面软件等,进行数据交互,设备管理。 华为云IOT提供了应用侧开发的API对接接口,这里就介绍一下使用应用侧开发的流程。这个API接口里常用的接口包括:产品创建、设备创建、设备属性获取、设备删除、查询设备等管理接口,可以通过API主动获取产品下面某个设备的属性,要求设备上报最新的数据过来。整个开发过程,都是基于HTTP协议的API接口进行交互,不依赖开发环境,不依赖开发语言。 不管是桌面软件,还是手机APP、微信小程序、web网页等,核心代码基本都是一样,都是HTTP协议交互。下面的例子里,我是采用C++编写的,采用QT框架库完成整个开发,了解了整个思路,你就可以采用自己熟悉的语言完成相同的功能。 官方帮助文档:[ https://support.huaweicloud.com/usermanual-iothub/iot_01_0045.html]( https://support.huaweicloud.com/usermanual-iothub/iot_01_0045.html) ![image.png](https://bbs-img.huaweicloud.com/blogs/img/20220801/1659321098553976784.png) ## 5. CC2530程序设计 ### 5.1 IAR环境搭建 完整的安装整个配套环境,需要安装以下的软件,具体的版本型号也介绍了,直接百度搜索就能找到;最简单的办法是,淘宝搜索一下CC2530的开发板,店铺里一般都有配套的资料包下载,里面基本都包含了下面这些软件,直接白嫖就行: 安装集成开发环境: IAR-EW8051-8.10.1。 安装仿真器“SmartRF4EB”的驱动程序。 安装代码烧写工具: Setup_SmartRF_Programmer_1.10.2。 安装 TI 的 Zigbee 协议栈: ZStack-CC2530-2.5.1a。 **安装过程截图请看另外的文档。** ![image.png](https://bbs-img.huaweicloud.com/blogs/img/20220731/1659279792871764035.png) ### 5.2 硬件原理图 ![image.png](https://bbs-img.huaweicloud.com/blogs/img/20220731/1659279805707563798.png) ### 5.3 IAR程序工程图 ![image.png](https://bbs-img.huaweicloud.com/blogs/img/20220731/1659279814345255814.png) ### 5.4 DHT11.c代码 ```cpp #include "uart.h" /* 函数功能:串口0初始化 */ void Init_Uart0(void) { PERCFG&=~(10); //串口0的引脚映射到位置1,即P0_2和P0_3 P0SEL|=0x32; //将P0_2和P0_3端口设置成外设功能 U0BAUD = 216; //32MHz的系统时钟产生115200BPS的波特率 U0GCR&=~(0x1F0);//清空波特率指数 U0GCR|=110; //32MHz的系统时钟产生115200BPS的波特率 U0UCR |= 0x80; //禁止流控,8位数据,清除缓冲器 U0CSR |= 0x36; //选择UART模式,使能接收器 } /* 函数功能:UART0发送字符串函数 */ void UR0SendString(u8 *str) { while(*str!='\0') { U0DBUF = *str; //将要发送的1字节数据写入U0DBUF while(UTX0IF == 0);//等待数据发送完成 UTX0IF = 0; //清除发送完成标志,准备下一次发送 str++; } } /* 函数功能: 模仿printf风格的格式化打印功能 */ char USART0_PRINT_BUFF[200]; //格式化数据缓存数据 void USART0_Printf(const char *format,...) { char *str=NULL; /*1. 格式化转换*/ va_list ap; // va_list---->char * va_start(ap,format); //初始化参数列表 vsprintf(USART0_PRINT_BUFF, format, ap); //格式化打印 va_end(ap); //结束参数获取 /*2. 串口打印*/ str=USART0_PRINT_BUFF;//指针赋值 while(*str!='\0') { U0DBUF=*str; //发送一个字节的数据 str++; //指针自增,指向下一个数据 while(UTX0IF == 0);//等待数据发送完成 UTX0IF = 0; //清除发送完成标志,准备下一次发送 } } ``` ### 5.5 ESP8266.c代码 ```cpp #include "esp8266.h" uint lenU1 = 0; uchar tempRXU1; uchar RecdataU1[MAXCHAR]; //"AT+CIPSEND=0,10\r\n" //长度10 //返回">" 之后就可以正常发送数据了 //发送成功返回 "SEND OK" //发送数据 void ESP8266_SendData(char *p,int len) { int i=0; char buff[50]; sprintf(buff,"AT+CIPSEND=0,%d\r\n",len); clearBuffU1(); Uart1_Send_String(buff); //发送指令 DelayMs(1000); //等待 for(i=0;i/等待发送完成 DelayMs(1000); RecdataU1[lenU1]='\0'; UR0SendString(RecdataU1); clearBuffU1(); } /**************************************************************************** * 名 称: SetWifi() * 功 能: 设置LED灯相应的IO口 * 入口参数: 无 * 出口参数: 无 ****************************************************************************/ void SetWifi(void) { P0DIR |= 0x40; //P0.6定义为输出 IGT = 0; //高电平复位 DelayMs(500); IGT = 1; //低电平工作 } /* 设置WIFI为AP模式+TCP服务器 */ void SetESP8266_AP_TCP_Server() { clearBuffU1(); Uart1_Send_String("AT\r\n"); DelayMs(2000); RecdataU1[lenU1]='\0'; UR0SendString(RecdataU1); clearBuffU1(); Uart1_Send_String("ATE0\r\n"); DelayMs(2000); RecdataU1[lenU1]='\0'; UR0SendString(RecdataU1); clearBuffU1(); Uart1_Send_String("AT+CWMODE=2\r\n"); DelayMs(2000); RecdataU1[lenU1]='\0'; UR0SendString(RecdataU1); clearBuffU1(); Uart1_Send_String("AT+RST\r\n"); DelayMs(2000); DelayMs(2000); DelayMs(2000); RecdataU1[lenU1]='\0'; UR0SendString(RecdataU1); clearBuffU1(); Uart1_Send_String("ATE0\r\n"); DelayMs(2000); RecdataU1[lenU1]='\0'; UR0SendString(RecdataU1); clearBuffU1(); Uart1_Send_String("AT+CWSAP=\"wifi_cc2530\",\"12345678\",1,4\r\n"); DelayMs(2000); DelayMs(2000); DelayMs(2000); DelayMs(2000); RecdataU1[lenU1]='\0'; UR0SendString(RecdataU1); clearBuffU1(); Uart1_Send_String("AT+CIPMUX=1\r\n"); DelayMs(2000); DelayMs(2000); RecdataU1[lenU1]='\0'; UR0SendString(RecdataU1); clearBuffU1(); Uart1_Send_String("AT+CIPSERVER=1,8089\r\n"); DelayMs(2000); DelayMs(2000); RecdataU1[lenU1]='\0'; UR0SendString(RecdataU1); clearBuffU1(); Uart1_Send_String("AT+CIFSR\r\n"); DelayMs(2000); DelayMs(2000); RecdataU1[lenU1]='\0'; UR0SendString(RecdataU1); } unsigned char dataRecv; unsigned char Flag = 0; /*===================UR1初始化函数====================*/ void Init_Uart1() { PERCFG = 0x00; //位置1 P0.4/P0.5口 P0SEL |= 0x30; //P0.4,P0.5用作串口(外部设备功能) U1CSR |= 0x80; //设置为UART方式 U1GCR |= 11; //BAUD_E U1BAUD |= 216; //BAUD_M 波特率设为115200 UTX1IF = 0; //UART1 TX中断标志初始置位0 U1CSR |= 0X40; //允许接收 IEN0 |= 0x88; // 开总中断,UART1接收中断 } void clearBuffU1(void) { int j; for(j=0;j } lenU1=0; } /******************************************************************************* 串口1发送一个字节函数 *******************************************************************************/ void Uart1_Send_Char(char Data) { U1CSR &= ~0x40; //禁止接收 U1DBUF = Data; while(UTX1IF == 0); UTX1IF = 0; U1CSR |= 0x40; //允许接收 } /******************************************************************************* 串口1发送字符串函数 *******************************************************************************/ void Uart1_Send_String(char *Data) { while(*Data!='\0') { Uart1_Send_Char(*Data); Data++; } } /**************************************************************** 串口接收一个字符: 一旦有数据从串口传至CC2530, 则进入中断,将接收到的数据赋值给变量temp. ****************************************************************/ #pragma vector = URX1_VECTOR __interrupt void UART1_ISR(void) { if(lenU181) { tempRXU1 = U1DBUF; RecdataU1[lenU1]=tempRXU1; URX1IF = 0; // 清中断标志 lenU1++; } } ``` ## 6. 总结 随着业务的发展,越来越多的企业选择结合物联网技术来实现自身效益增长。相比企业自建MQTT集群,使用华为云IoT服务低成本构建物联网解决方案,在能力、成本、运维、安全、生态等诸多方面具有突出优势。 广泛支持IoT主流的接入协议及私有协议,满足各类设备和接入场景要求;与主流模组、芯片预集成,实现多网络、多协议接入,简化设备接入难度,实现小时级设备极简接入。
  • [技术干货] HarmonyOS 设备联网上云
    ### 1.对接华为loT平台 #### 1.1华为loT平台介绍 华为云物联网平台即华为设备接入服务(loT Device Access),提供海量设备连接上云、设备和云端双向消息通信、批量设备管理、远程控制和监控、OTA升级、设备联动规则等能力,并可将设备数据灵活流转到华为云其他服务,帮助物联网行业用户快速完成设备联网及行业应用集成。   ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20228/1/1659350449224629088.png)   **华为loT平台地址:** /www.huaweicloud.com/product/iothub.html> #### 1.2华为loT平台产品创建 产品模型用于描述设备具备的能力和特性。开发者通过定义产品模型,在物联网平台构建一款设备的抽象模型,使平台理解该款设备支持的服务、属性、命令等信息,如颜色、开关等。   ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20228/1/1659350476467768598.png)   **服务信息** |服务ID | 服务类型 | |---------|------| | Agriculture | Senser |   **属性信息** |属性名称 | 数据类型 | |---------|------| | Temperature | int | | Humidity | int | | Luminance | int | | LightStatus | string | | MotorStatus | string|   **命令信息** |命令名称|参数名称|数据类型|长度|枚举| |-------|-----|------|------|-----| | Agriculture_Control_light | Light | string | 3 |ON,OFF| | Agriculture_Control_Motor | Motor | string | 3 |ON,OFF| #### 1.3设备对接华为loT平台 打开“D6_iot_cloud_oc”工程的iot_cloud_oc_sample.c文件,查看实现MQTT协议对接华为loT平台的代码。   **代码展示:**   ```js static int task_main_entry(void) { app_msg_t *app_msg; uint32_t ret = WifiConnect("Hold", "0987654321"); device_info_init(CLIENT_ID, USERNAME, PASSWORD); oc_mqtt_init(); oc_set_cmd_rsp_cb(oc_cmd_rsp_cb); while (1) { app_msg = NULL; (void)osMessageQueueGet(mid_MsgQueue, (void **)&app_msg, NULL, 0U); if (NULL != app_msg) { switch (app_msg->msg_type) { case en_msg_cmd: deal_cmd_msg(&app_msg->msg.cmd); break; case en_msg_report: deal_report_msg(&app_msg->msg.report); break; default: break; } free(app_msg); } } return 0; } ```   **案例演示**   案例将演示如何在BearPi-HM_Nano开发板上使用MQTT协议连接华为IoT平台,需要将E53_IA1智慧农业扩展板BearPi-HM_Nano开发板安装在一起。   **详细操作见:** https://www.bilibili.com/video/BV1tv411b7SA?p=30&share_source=copy_web&vd_source=8f1cf1d7278a65d1271a6ccbd8891dc6 P30   `如果没有板子,可在下面链接处购买` **E53_IA1智慧农业扩展板购买地址:** /item.taobao.com/item.htm?id-607878490044> ### 2.对接OneNET平台 #### 2.1 OneNET平台介绍 OneNET是中国移动打造的高效、稳定、安全的物联网开放平台。OneNET支持适配各种网络环境和协议类型,可实现各种传感器和智能硬件的快速接入,提供丰富的API和应用模板以支撑各类行业应用和智能硬件的开发,有效降低物联网应用开发和部署成本,满足物联网领域设备连接、协议适配、数据存储、数据安全以及大数据分析等平台级服务需求。   ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20228/1/1659350510246591499.png)   **OneNET平台地址:** /open.iot.10086.cn/develop/global/product/#/console> #### 2.2 OneNET平台产品创建 OneNET平台资源(包括设备,APlKey,触发器,应用等)的集合,一个产品对应唯一的masterkey、产品ID,设备注册码,一个产品下包含多个具备同一特征的设备,多个设备之间的唯一性由SN来区分   ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20228/1/1659350523187425735.png)   **教程地址:** https://gitee.com/bearpi/bearpi-hm_nano/blob/master/applications/BearPi/BearPi-HM_Nano/sample/D7_iot_cloud_onenet/README.md #### 2.3 设备对接OneNET平台 打开“D7_iot_cloud_onenet”工程的iot_cloud_onenet_sample.c文件,查看实现MQTT协议对接OneNET平台的代码   **代码展示:**   ```js void MQTT_Report_Task(void) { WifiConnect(Wifi_SSID, Wifi_PASSWORD); device_info_init(ONENET_INFO_DEVID, ONENET_INFO_PROID, ONENET_INFO_AUTH, ONENET_INFO_APIKEY, ONENET_MASTER_APIKEY); onenet_mqtt_init(); onenet_set_cmd_rsp_cb(onenet_cmd_rsp_cb); while (1) { onenet_mqtt_upload_digit("Temperature", (int)E53_IA1_Data.Temperature); onenet_mqtt_upload_digit("Humidity", (int)E53_IA1_Data.Humidity); onenet_mqtt_upload_digit("Luminance", (int)E53_IA1_Data.Lux); sleep(1); } } ```   **详细操作见:** https://www.bilibili.com/video/BV1tv411b7SA?p=30&share_source=copy_web&vd_source=8f1cf1d7278a65d1271a6ccbd8891dc6 P31 
  • [技术干货] 什么是IPsec?
    IPsec(Internet Protocol Security)是为IP网络提供安全性的协议和服务的集合,它是VPN(Virtual Private Network,虚拟专用网)中常用的一种技术。 由于IP报文本身没有集成任何安全特性,IP数据包在公用网络如Internet中传输可能会面临被伪造、窃取或篡改的风险。通信双方通过IPsec建立一条IPsec隧道,IP数据包通过IPsec隧道进行加密传输,有效保证了数据在不安全的网络环境如Internet中传输的安全性。什么是IPsec VPN?VPN(Virtual Private Network,虚拟专用网)是一种在公用网络上建立专用网络的技术。它之所以称之为虚拟网,主要是因为VPN的两个节点之间并没有像传统专用网那样使用端到端的物理链路,而是架构在公用网络如Internet之上的逻辑网络,用户数据通过逻辑链路传输。按照VPN协议分,常见的VPN种类有:IPsec、SSL、GRE、PPTP和L2TP等。其中IPsec是通用性较强的一种VPN技术,适用于多种网络互访的场景。IPsec VPN是指采用IPsec实现远程接入的一种VPN技术,通过在公网上为两个或多个私有网络之间建立IPsec隧道,并通过加密和验证算法保证VPN连接的安全。IPsec VPNIPsec VPN保护的是点对点之间的通信,通过IPsec VPN可以在主机和主机之间、主机和网络安全网关之间或网络安全网关(如路由器、防火墙)之间建立安全的隧道连接。其协议主要工作在IP层,在IP层对数据包进行加密和验证。相对于其他VPN技术,IPsec VPN安全性更高,数据在IPsec隧道中都是加密传输,但相应的IPsec VPN在配置和组网部署上更复杂。IPsec是如何工作的?IPsec的工作原理大致可以分为4个阶段:识别“感兴趣流”。网络设备接收到报文后,通常会将报文的五元组等信息和IPsec策略进行匹配来判断报文是否要通过IPsec隧道传输,需要通过IPsec隧道传输的流量通常被称为“感兴趣流”。协商安全联盟(Security Association,以下简称SA)。SA是通信双方对某些协商要素的约定,比如双方使用的安全协议、数据传输采用的封装模式、协议采用的加密和验证算法、用于数据传输的密钥等,通信双方之间只有建立了SA,才能进行安全的数据传输。识别出感兴趣流后,本端网络设备会向对端网络设备发起SA协商。在这一阶段,通信双方之间通过IKE协议先协商建立IKE SA(用于身份验证和密钥信息交换),然后在IKE SA的基础上协商建立IPsec SA(用于数据安全传输)。数据传输。IPsec SA建立成功后,双方就可以通过IPsec隧道传输数据了。IPsec为了保证数据传输的安全性,在这一阶段需要通过AH或ESP协议对数据进行加密和验证。加密机制保证了数据的机密性,防止数据在传输过程中被窃取;验证机制保证了数据的真实可靠,防止数据在传输过程中被仿冒和篡改。如图所示,IPsec发送方会使用加密算法和加密密钥对报文进行加密,即将原始数据“乔装打扮”封装起来。然后发送方和接收方分别通过相同的验证算法和验证密钥对加密后的报文进行处理得到完整性校验值ICV。如果两端计算的ICV相同则表示该报文在传输过程中没有被篡改,接收方对验证通过的报文进行解密处理;如果ICV不相同则直接丢弃报文。IPsec加密验证过程隧道拆除。通常情况下,通信双方之间的会话老化(连接断开)即代表通信双方数据交换已经完成,因此为了节省系统资源,通信双方之间的隧道在空闲时间达到一定值后会自动删除。IPsec的3个重要协议- IKE/AH/ESPIKE(Internet Key Exchange,因特网密钥交换)IKE协议是一种基于UDP的应用层协议,它主要用于SA协商和密钥管理。IKE协议分IKEv1和IKEv2两个版本,IKEv2与IKEv1相比,修复了多处公认的密码学方面的安全漏洞,提高了安全性能,同时简化了安全联盟的协商过程,提高了协商效率。IKE协议属于一种混合型协议,它综合了ISAKMP(Internet Security Association and Key Management Protocol)、Oakley协议和SKEME协议这三个协议。其中,ISAKMP定义了IKE SA的建立过程,Oakley和SKEME协议的核心是DH(Diffie-Hellman)算法,主要用于在Internet上安全地分发密钥、验证身份,以保证数据传输的安全性。IKE SA和IPSec SA需要的加密密钥和验证密钥都是通过DH算法生成的,它还支持密钥动态刷新。AH(Authentication Header,认证头)AH协议用来对IP报文进行数据源认证和完整性校验,即用来保证传输的IP报文的来源可信和数据不被篡改,但它并不提供加密功能。AH协议在每个数据包的标准IP报文头后面添加一个AH报文头,AH协议对报文的完整性校验的范围是整个IP报文。ESP(Encapsulating Security Payload,封装安全载荷)ESP协议除了对IP报文进行数据源认证和完整性校验以外,还能对数据进行加密。ESP协议在每一个数据包的标准IP报头后方添加一个ESP报文头,并在数据包后方追加一个ESP尾(ESP Trailer和ESP Auth data)。ESP协议在传输模式下的数据完整性校验范围不包括IP头,因此它不能保证IP报文头不被篡改。AH和ESP可以单独使用,也可以同时使用。AH和ESP同时使用时,报文会先进行ESP封装,再进行AH封装;IPsec解封装时,先进行AH解封装,再进行ESP解封装。IPsec使用的端口IPsec中IKE协议采用UDP 500端口发起和响应协商,因此为了使IKE协商报文顺利通过网关设备,通常要在网关设备上配置安全策略放开UDP 500端口。另外,在IPsec NAT穿越场景下,还需要放开UDP 4500端口。而AH和ESP属于网络层协议,不涉及端口。为了使IPsec隧道能正常建立,通常还要在网关设备上配置安全策略放开AH(IP协议号是51)和ESP(IP协议号是50)服务。IPsec VPN和SSL VPN对比IPsec和SSL是部署VPN时最常用的两种技术,它们都有加密和验证机制保证用户远程接入的安全性。从以下几个方面对IPsec VPN和SSL VPN进行对比:OSI参考模型工作层级OSI定义了网络互连的七层框架:物理层、数据链路层、网络层、传输层、会话层、表示层、应用层。IPsec工作在网络层,它直接运行在IP(Internet Protocol,互联网协议)之上。而SSL工作在应用层,是一种应用层协议,它加密的是HTTP流量,而不是直接加密IP数据包。IPsec和SSL的工作层级配置部署IPsec VPN通常适用于Site to Site(站点到站点)的组网,要求站点分别部署VPN网关或远程用户安装专用的VPN客户端,因此配置部署复杂度和维护成本都比较高。但SSL VPN通常适用于Client to Site(客户端到站点)的组网,只要求远程用户使用支持SSL的标准浏览器安装指定插件即可进行访问,通过数据中心部署VPN网关进行集中管理和维护,因此配置部署更简单,维护成本相对较低。IPsec VPNSSL VPN安全性IPSec工作在网络层,对站点间传输的所有数据进行保护。IPSec VPN要求远程用户安装专用的VPN客户端或在站点部署VPN网关设备,用户访问会受到客户端或网关在用户认证规则、安全策略规则或内容安全过滤方面的检查,因此安全性更高。而SSL VPN不要求安装专用客户端或接入站点部署网关设备,更容易受到安全威胁的影响。访问控制IPsec工作在网络层,不能基于应用进行细粒度的访问控制。而SSL VPN在精细化访问控制上更灵活,网络管理员可以将网络资源根据不同的应用类型划分为不同的资源类型,每一类资源的访问权限不同。
  • [技术干货] Python实现邮件自动下载的示例详解【转】
    开始码代码之前,我们先来了解一下三种邮件服务协议:1、SMTP协议SMTP(Simple Mail Transfer Protocol),即简单邮件传输协议。相当于中转站,将邮件发送到客户端。2、POP3协议POP3(Post Office Protocol 3),即邮局协议的第3个版本,是电子邮件的第一个离线协议标准。该协议把邮件下载到本地计算机,不与服务器同步,缺点是更易丢失邮件或多次下载相同的邮件。3、IMAP协议IMAP(Internet Mail Access Protocol),即交互式邮件存取协议。该协议连接远程邮箱直接操作,与服务器内容同步。然后介绍一下email包这个包的中心组件是代表电子邮件消息的“对象模型”。 应用程序主要通过在 message 子模块中定义的对象模型接口与这个包进行交互。 应用程序可以使用此 API 来询问有关现有电子邮件的问题、构造新的电子邮件,或者添加或移除自身也使用相同对象模型接口的电子邮件子组件。 也就是说,遵循电子邮件消息及其 MIME 子组件的性质,电子邮件对象模型是所有提供 EmailMessage API 的对象所构成的树状结构。接下来我们通过具体的代码实现一个登录邮箱客户端,下载邮件,解析邮件附件内容的功能。首先我们需要定义一个邮件解析的类,该类需要三个变量:1、邮箱所属的imap服务地址;2、邮箱账号;3、邮箱密码【注:不同邮箱需要不同的安全策略,例如qq邮箱需要短信验证,获取登录授权码,而不是明文密码去登录远程客户端】123456789class Email_parse:     def __init__(self,remote_server_url,email_url,password):        # imap服务地址        self.remote_server_url = remote_server_url        # 邮箱账号        self.email_url = email_url        # 邮箱密码        self.password = password然后定义类中入口函数,登录远程,默认获取第一页所有的邮件。我们获取邮件的主题,并打印出来【不同邮件主题的编码可能不同,二进制需要转码才能正确显示】12345678910111213141516171819202122def main_parse_Email(self):    """入口函数,登录imap服务"""    server = imaplib.IMAP4_SSL(self.remote_server_url, 993)    server.login(self.email_url, self.password)    server.select('INBOX')    status,data = server.search(None,"ALL")    if status != 'OK':        raise Exception('read email error')    emailids = data[0].split()    mail_counts = len(emailids)    print("count:",mail_counts)    # 邮件的遍历是按时间从后往前,这里我们选择最新的一封邮件    for i in range(mail_counts - 1, mail_counts - 2, -1):        status, edata = server.fetch(emailids[i], '(RFC822)')        msg = email.message_from_bytes(edata[0][1])        #获取邮件主题title        subject = email.header.decode_header(msg.get('subject'))        if type(subject[-1][0]) == bytes:            title = subject[-1][0].decode(str(subject[-1][1]))        elif type(subject[-1][0]) == str:            title = subject[-1][0]        print("title:", title)其中,msg变量保存的就是邮件的主体,接下来因为会重复用到msg和tilte,我们将构造一个类函数返回msg和title。12345678def get_email_title(msg):    subject = email.header.decode_header(msg.get('subject'))    if type(subject[-1][0]) == bytes:        title = subject[-1][0].decode(str(subject[-1][1]))    elif type(subject[-1][0]) == str:        title = subject[-1][0]    print("title:", title)    return title解析邮件,我们分为两部分,邮件正文【HTML】和附件【xlsx等】,判断有附件,我们就保存到固定的路径下。表格的解析不再赘述了,pandas之类的包足以搞定。12345678910111213def get_att(msg):    """获取附件并下载"""    filename = Email_parse.get_email_name(msg)    for part in msg.walk():        file_name = part.get_param("name")        if file_name:            data = part.get_payload(decode=True)            if data != None:                att_file = open('./src/' + filename, 'wb')                att_file.write(data)                att_file.close()            else:                pass邮件正文内容,我们直接解析html,将文本内容直接保存到.txt文件中,方便读取。12345678910111213def get_text_from_HTML(msg):    """获取邮件中的html"""    filename = Email_parse.get_email_name(msg)    current_title = Email_parse.get_email_title(msg)    print("filename:",filename,type(filename))    for part in msg.walk():        if not part.is_multipart():            result = part.get_payload(decode=True)            result = result.decode('gbk')            f = open(f'./src/{current_title}.txt','w')            f.write(result)            f.close()            return result完整代码如下:123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293import emailimport imaplibfrom email.header import decode_headerimport pandas as pdimport datetime  class Email_parse:    def __init__(self,remote_server_url,email_url,password):        self.remote_server_url = remote_server_url        self.email_url = email_url        self.password = password     def get_att(msg):        filename = Email_parse.get_email_name(msg)        for part in msg.walk():            file_name = part.get_param("name")            if file_name:                data = part.get_payload(decode=True)                if data != None:                    att_file = open('./src/' + filename, 'wb')                    att_file.write(data)                    att_file.close()                else:                    pass     def get_email_title(msg):        subject = email.header.decode_header(msg.get('subject'))        if type(subject[-1][0]) == bytes:            title = subject[-1][0].decode(str(subject[-1][1]))        elif type(subject[-1][0]) == str:            title = subject[-1][0]        print("title:", title)        return title      def get_email_name(msg):        for part in msg.walk():            file_name = part.get_param("name")            if file_name:                h = email.header.Header(file_name)                dh = email.header.decode_header(h)                filename = dh[0][0]                if dh[0][1]:                    value, charset = decode_header(str(filename, dh[0][1]))[0]                    if charset:                        filename = value.decode(charset)                        print("附件名称:", filename)                        return filename      def main_parse_Email(self):        server = imaplib.IMAP4_SSL(self.remote_server_url, 993)        server.login(self.email_url, self.password)        server.select('INBOX')        status,data = server.search(None,"ALL")        if status != 'OK':            raise Exception('read email error')        emailids = data[0].split()        mail_counts = len(emailids)        print("count:",mail_counts)        for i in range(mail_counts - 1, mail_counts - 2, -1):            status, edata = server.fetch(emailids[i], '(RFC822)')            msg = email.message_from_bytes(edata[0][1])            subject = email.header.decode_header(msg.get('subject'))            if type(subject[-1][0]) == bytes:                title = subject[-1][0].decode(str(subject[-1][1]))            elif type(subject[-1][0]) == str:                title = subject[-1][0]            print("title:", title)            Email_parse.get_att(msg)            Email_parse.get_text_from_HTML(msg)      def get_text_from_HTML(msg):        filename = Email_parse.get_email_name(msg)        current_title = Email_parse.get_email_title(msg)        print("filename:",filename,type(filename))        for part in msg.walk():            if not part.is_multipart():                result = part.get_payload(decode=True)                result = result.decode('gbk')                f = open(f'./src/{current_title}.txt','w')                f.write(result)                f.close()                return result if __name__ == "__main__":    remote_server_url = 'imap.qq.com'    email_url = "*********@qq.com"    password = "**********"    demo = Email_parse(remote_server_url,email_url,password)    demo.main_parse_Email()
  • [技术干货] 第六章培训总结(终)
    # 网络应用开发 ## HarmonyOS网络应用开发 UDP服务端 ### 1.主要学习内容 (1)了解UDP协议相关API (2)学习并掌握UDP服务端创建流程 (3)学习UDP通信流程 ### 2.UDP协议相关API介绍 (1)socket.h接口简介: 其中包含声明UDP协议相关接口函数 (2)主要接口及其功能 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20227/27/1658927640935603466.png) ### UDP服务端创建流程介绍 流程如图所示 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20227/27/1658927907487557100.png) ### 如何实现实现UDP服务端 打开“D4_iot_tcp_server"工程的tcp_server_demo.c文件,修改部分代码即可实现UDP服务端。 具体代码 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20227/27/1658928155634525371.png) ### 学习总结 本节小结 1.了解了UDP协议相关API介绍 2.掌握UDP服务端创建流程 3.了解认识了UDP通信流程,实现UDP服务端。 ## HarmonyOS网络应用开发 MQTT客户端 ### 1.主要内容 (1)了解什么是Paho MQTT (2)学习Paho MQTT文件目录 (3)学习掌握如何使用Paho MQTT ### MQTT介绍 (1)MQTT(Message Queuing Telemetry Transport,消息队列遥测传输协议),是一种基于发布/订阅(publish/subscribe)模式的"轻量级"通讯协议,该协议构建于TCP/IP协议上,由IBM在1999年发布。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20227/27/1658928737011988108.png) Paho是IBM在2011年建立的Eclipse开源项目,该项目包含以C、Java、Python、Javascript等语言编写的可用客户 端。 (2)Paho MQTT 文件目录介绍 MQTTClient:封装MQTTPacket生成的高级别C开客户端程序。 MQTTClient-C:封装MQTTPacket生成的高级别C客户端程序。 samples目录提供FreeRTOS和linux两个例程,分别支持FreeRTOS和Linux系统。 src目录提供MQTTClient的代码实现能力,以及用于移植到对应平台的网络驱动。 MQTTPacket:提供MQTT数据包的序列化与反序列化,以及部分辅助函数。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20227/27/1658928868182560215.png) ### MQTTClient.h 其中包含声明Paho MQTT相关接口函数。 主要接口及其功能 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20227/27/1658928959363601357.png)
  • [交流吐槽] 鸿蒙培训第六章笔记
    UDP客户端UDP协议相关API介绍socket.h中包含声明UDP协议相关接口函数创建流程代码创建客户端前需要先连接WiFi热点连接完成后可以进行socket创建定义协议初始化预连接的服务端地址(此处要设置成本机IP地址),主要设置三个参数send_addr.sin_family——协议族send_addr.sin_port——端口号send_addr.sin_addr.s_addr——IP地址(通过API转化形式)通过循环去发送以及接收数据发送数据到服务远端线程休眠(即延时)接收返回的字符串将返回的数据进行打印TCP服务器TCP协议相关API介绍socket.h中包含声明TCP协议相关接口函数TCP服务端创建流程代码与上讲相同,先连接WiFi并创建socketTCP协议UDP协议调用bind函数绑定socket以及地址listen()函数指定port监听调用accept函数用于接受监听到的数据内容recv()、send()函数用于识别剑庭内容以及进行答复直接接受转接的通道TCP客户端TCP协议相关API介绍socket.h中包含声明TCP协议相关接口函数(与上讲相比,新增connect)TCP客户端创建流程代码对第一讲的UDP客户端搭建代码进行修改便可获得TCP客户端创建代码修改发送的数据信息、任务名称等将UDP改为TCPsocket创建代码中协议内容进行修改对TCP进行连接服务器调用conncet()函数删除指定地址已建立的数据只需要在进行收数据以及发数据其余与上讲搭建类似UDP服务器UDP协议相关API介绍socket.h中包含声明UDP协议相关接口函数UDP服务器创建流程代码与上一讲修改客户端信息改变客户端类型相似,这里也直接对TCP服务器创建代码进行修改修改TCP任务名等成UDP数据信息socket创建代码中的UDP协议创建一个bind,将IP端口绑定到socket文件描述符上删除listen()与accept()函数,UDP服务器不需要监听和接收recv()函数中加入新的参数,及客户端信息和长度进行数据的收发,参数是修改关键,MQTT客户端定义MQTT (Message Queuing Telemetry Transport,消息队列遥测传输协议),是一种基于发布/订阅(publish/subscribe)模式的"轻量级"通讯协议。组成MQTT客户端MQTT代理数据接收设备文件目录MQTT相关API介绍MQTTClient.h中包含声明Paho MQTT相关接口函数代码连接WiFi、创建socket函数并利用返回的文件描述符连接IPMQTT代码初始化并创建MQTT对象配置MQTT客户端信息(版本信息、ID等)发送连接数据包发送失败则重连服务器并创建一个对象连接成功将实现订阅消息订阅消息的回调函数通过循环语句实现发布信息的功能注意参数设置
  • [技术干货] 寻找OpenConfig Yang和IETF Yang的前世今生:1.Yang的缘起
    本期将为大家区分NETCONF和YANG的概念,梳理NETCONF协议及YANG语言出现背景,明确Yang模型作用及其重要性,述说YANG的缘起。      名词 亲爱的们,名词概念别混淆~★ NETCONF是一种协议,实现该协议的建模语言有多种,目前最广泛使用的是YANG语言;★ YANG是一种建模语言(xml的结构模型),是实现NETCONF的手段,不同组织定义的YANG存在差异,业界有很多种YANG模型。    Yang模型分类         (1)OpenConfig Yang          (2)IETF/公有/标准 Yang         (3)私有Yang    上述Yang归根结底都是netconf 协议中的Yang功能。    各厂商都在于积极地推动网络配置开放,企业只要基于这些yang 文件编写控制器接口,就能通过下发一套yang报文实现对各个厂商设备的控制,实现配置的兼容性。.     Netconf的出现     有这样一个业务场景:需求为一个POD里面几十台交换机修改Qos配置(理解为对网元进行xx配置)    早期,人肉的方式,一台台修改,运维工程人员比较累(还可能出错)。    随着DevOps的流行,采用自动化脚本方式会节省不少人力物力。但是不同厂商不同设备,甚至不同版本之间配置指令(CLI)可能有较大差异,这意味着如果设备版本升级,运行的脚本就得更改,同时多个厂商设备,也会使脚本比较复杂,对运维人员要求较高。    减轻运维人员的工作量,办法总是有的,于是SNMP协议就出现了,xxx多好处,主要是能解决上面的问题。但是,它还是有缺点,特别是不能满足配置管理的需求。    然后,为了弥补SNMP的缺陷,基于可扩展标记语言XML的NETCONF协议应用而生。通俗的讲,NETCONF(Network Configuration Protocol)协议提供一套管理网络设备的机制,用户可以使用这套机制增加、修改、删除网络设备的配置,同时还可以获取网络设备的配置和状态信息。目前绝大多数的网络设备,包括华为的网络设备支持NETCONF协议,这些网络设备提供规范的API接口,应用程序可以直接使用这些API接口(以NETCONF协议报文),向网络设备发送配置指令或者获取配置信息。    Netconf 是 IETF 发布的标准协议,它的全称是 Network Configuration Protocal。从名字就可以看出来,Netconf 的作用是基于网络来安装、操作和删除设备的配置。在 Netconf 的架构中,网络设备充当 Netconf Server 的角色,而运维人员的这一侧则是 Netconf Client。此外,和 OSI 标准模型一样,Netconf 也是分层结构。NETCONF是应用层协议,在逻辑上划分为4层,从下到上依次为:    01安全传输层    安全传输层在 Netconf Client 和 Netconf Server 之间提供安全的端到端连接。与 SNMP 采用非面向连接的UDP 协议不同,Netconf 采用面向连接的 TCP 协议,通常是 SSH 协议,保证连接的可靠性和安全性。    02消息层    消息层也称为 RPC(远程过程调用)层。Netconf Server(网络设备)上面部署了 Netconf 应用,Netconf Client 需要调用 Server 上的应用所提供的函数/方法,但由于 Client 和 Server 不在同一个内存空间,无法直接调用,所以需要通过网络来表达调用的语义,并传达调用的数据。这个过程,称为 RPC。它提供了一个简单的,与安全传输层无关的机制来封装操作层和内容层的数据:    • RPC 调用: <rpc> 元素所封装的消息    • RPC 结果: <rpc-reply> 元素所封装的消息    • 事件通知:  元素所封装的消息    03操作层    操作层定义了如图所示的 9 种基础操作集,其中:    • <get>、 <get-config> 用来对设备进行取值操作    • <edit-config>、 <copy-config>、 <delete-config> 用于配置设备参数    • 和  是在对设备进行操作时,为防止并发产生混乱的锁行为    • 和  用于结束一个会话操作    04内容层    顾名思义,内容层就是用来表达配置数据和状态数据,网络运维人员只需要关注数据本身,而不需要去关注设备的相关命令。基础网络设备在内容层所采用的数据格式通常是 XML,但也有厂商的数据格式采用了 JSON。     Yang的出现     在NETCONF的学习中,我们知道内容层就是用来表达配置数据和状态数据,网络运维人员只关注数据本身,而不需要去关注设备的相关命令。    而网络设备在内容层所采用的数据格式通常是XML,但也有厂商的数据格式采用的是JSON。    所以虽然不需要关注网络设备的操作命令,但是配置的数据还是需要有一定的结构。    YANG模型就是对内容层的建模,打个比方,向领导请假,领导说写个请假单,包含请假人的姓名,请假的起止时间,请假事由和代理人。于是我做了一个表格,包含了上述要求,并根据实际情况填入了真实信息。那么领导的描述,就可以理解为“建模”,而最后提交的填好内容的表格,就是将模型实例化了。    那么我们不禁思考:    是否可以理解为采用YANG模型,不同设备的差异可以通过代码去做适配呢?    现在,大家知道Netconf和Yang的关系,以及Yang模型的作用和重要性了吧,下期我们将一起重点了解Yang的树形结构。请大家持续关注!.*注:部分文档来源于网络.下一篇:《Yang的语法结构》.iMaster NCE AOC社区入口:    中文版社区      /    英文版社区 
  • [技术干货] 第六章笔记培训(2)
    # 网络应用开发 ## HarmonyOS网络应用开发TCP服务端 ### 1.主要内容 (1)了解TCP协议相关API (2)学习TCP服务端创建流程 (3)学习了解TCP通信流程 ### 2.TCP协议相关API介绍 socket.h接口简介: 其包含声明TCP协议相关接口函数。 主要接口及其功能 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20227/26/1658834262834236539.png) TCP服务端创建流程介绍 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20227/26/1658834367977616132.png) 最后发送数据,验证效果 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20227/26/1658834697882318881.png) ## OpenHarmony网络应用开发TCP客户端 ### 1.主要学习内容 (1)TCP协议相关API (2)TCP客户端创建流程 (3)TCP通信流程 ### 2.TCP协议相关API介绍 (1)socket.h接口简介: 其中包含声明TCP协议相关接口函数。 (2)主要接口及其功能 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20227/26/1658835209428701900.png) ### TCP客户端创建流程介绍 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20227/26/1658835247292914140.png) ## 学习 1.了解了TCP协议的相关API 2.掌握TCP服务端的创建流程 3.掌握TCP通信流程 4.掌握TCP客户端创建流程
  • [交流吐槽] 第七次笔记
    # UDP客户端 UDP具有较好的实时性,工作效率比TCP高,适用于对高速传输和实时性有较高的通信或广播通信。 但UDP作为一种最简单的传输层协议,基本上没有做什么的操作来帮助用户处理复杂的网络环境,所以UDP保留下来这种不可靠的特性。 ## UDP协议相关API介绍 ![](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20227/25/1658728233721199658.png) ## 创建流程 ![](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20227/25/1658728284406746507.png) ## 实现 ![](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20227/25/1658728299179714542.png) # TCP服务端 TCP:传输控制协议 **目标:** > 以进程为单位传递数据 > 追求可靠性 ## 相关API ![](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20227/25/1658728424696479298.png) ## 创建流程 ![](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20227/25/1658728467427137155.png) ## 实现 ![](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20227/25/1658728486269246746.png)
  • [交流吐槽] 第六章总结与浅解
    UDP客户端:测试UDP客户端:通过socket工具测试UDP客户端:工具下载地址:https://pan.baidu.com/share/init?surl=3YlqQVzEa5ygcQeTSGQ_JA提取码:12341)选择UDP服务端,然后点击创建2)将本地端口修改为案例代码中的端口号Windows查看IP地址方法:1)同时按【win】+【R】,进入cmd窗口2)输入:ipconfig,按【Enter】3)查看IP地址案例代码解析:#include <stdio.h>#include <unistd.h>#include "ohos_init.h"#include "cmsis_os2.h"#include "wifi_device.h"#include "lwip/netifapi.h"#include "lwip/api_shell.h"#include <netdb.h>#include <string.h>#include <stdlib.h>#include "lwip/sockets.h"#include "wifi_connect.h"#define _PROT_ 8888//服务端端口号//在sock_fd 进行监听,在 new_fd 接收新的链接int sock_fd;//定义文件描述符int addr_length;static const char *send_data = "Hello! I'm BearPi-HM_Nano UDP Client!\r\n";//定义发送给服务端的信息static void UDPClientTask(void){//服务器的地址信息struct sockaddr_in send_addr;socklen_t addr_length = sizeof(send_addr);char recvBuf[512];//连接WifiWifiConnect("TP-LINK_65A8", "0987654321");//该函数被封装在./src/wifi_connect.c里//创建socketif ((sock_fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)//协议组:AF_INET是IPV4,AF_INET6是IPV6;协议类型:SOCK_DGRAM是UDP;协议:0是按照第二个参数去定义,通常填0    {perror("create socket failed!\r\n");exit(1);    }//初始化预连接的服务端地址send_addr.sin_family = AF_INET;//协议组send_addr.sin_port = htons(_PROT_);//端口号(通过htons()将主机端口号转化为网络端口号)send_addr.sin_addr.s_addr = inet_addr("192.168.0.175");//服务端IP地址addr_length = sizeof(send_addr);//总计发送 count 次数据while (1)    {bzero(recvBuf, sizeof(recvBuf));//将recvBuf里的数据清零//发送数据到服务远端sendto(sock_fd, send_data, strlen(send_data), 0, (struct sockaddr *)&send_addr, addr_length);//线程休眠一段时间(10s)sleep(10);//接收服务端返回的字符串,如果没有收到数据就一直阻塞在这recvfrom(sock_fd, recvBuf, sizeof(recvBuf), 0, (struct sockaddr *)&send_addr, &addr_length);printf("%s:%d=>%s\n", inet_ntoa(send_addr.sin_addr), ntohs(send_addr.sin_port), recvBuf);//输出接收的数据;inet_ntoa()是将长整型的数据转化为点分十进制的数据;ntohs()是将网络字符数据转化为主机字符数据    }//关闭这个 socketclosesocket(sock_fd);}static void UDPClientDemo(void){osThreadAttr_t attr;attr.name = "UDPClientTask";attr.attr_bits = 0U;attr.cb_mem = NULL;attr.cb_size = 0U;attr.stack_mem = NULL;attr.stack_size = 10240;attr.priority = osPriorityNormal;if (osThreadNew((osThreadFunc_t)UDPClientTask, NULL, &attr) == NULL)    {printf("[UDPClientDemo] Falied to create UDPClientTask!\n");    }}APP_FEATURE_INIT(UDPClientDemo);TCP服务端:测试TCP服务端:1)打开Socket tool,选择TCP Client,点击【创建】2)填写代码中的端口号以及日志信息中的开发板IP地址案例代码抽象化理解:1)公司买一部电话2)给电话办一张卡3)招一个前台工作人员负责转接电话(转接电话数为TCP_BACKLOG)4)对应的工作人员和客服之间进行交流TCP客户端:案例代码:#include <stdio.h>#include <unistd.h>#include "ohos_init.h"#include "cmsis_os2.h"#include "wifi_device.h"#include "lwip/netifapi.h"#include "lwip/api_shell.h"#include <netdb.h>#include <string.h>#include <stdlib.h>#include "lwip/sockets.h"#include "wifi_connect.h"#define _PROT_ 8888//服务端端口号//在sock_fd 进行监听,在 new_fd 接收新的链接int sock_fd;//定义文件描述符int addr_length;static const char *send_data = "Hello! I'm BearPi-HM_Nano TCP Client!\r\n";//定义发送给服务端的信息static void TCPClientTask(void){//服务器的地址信息struct sockaddr_in send_addr;socklen_t addr_length = sizeof(send_addr);char recvBuf[512];//连接WifiWifiConnect("TP-LINK_65A8", "0987654321");//该函数被封装在./src/wifi_connect.c里//创建socketif ((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)//协议组:AF_INET是IPV4,AF_INET6是IPV6;协议类型:SOCK_STREAM是TCP;协议:0是按照第二个参数去定义,通常填0    {perror("create socket failed!\r\n");exit(1);    }//初始化预连接的服务端地址send_addr.sin_family = AF_INET;//协议组send_addr.sin_port = htons(_PROT_);//端口号(通过htons()将主机端口号转化为网络端口号)send_addr.sin_addr.s_addr = inet_addr("192.168.0.102");//服务端IP地址addr_length = sizeof(send_addr);connect(sock_fd, (struct sockaddr *)&send_addr, addr_length);//连接TCP服务器//总计发送 count 次数据while (1)    {bzero(recvBuf, sizeof(recvBuf));//将recvBuf里的数据清零//发送数据到服务远端send(sock_fd, send_data, strlen(send_data), 0);// //线程休眠一段时间(10s)// sleep(10);//接收服务端返回的字符串,如果没有收到数据就一直阻塞在这recv(sock_fd, recvBuf, sizeof(recvBuf), 0);printf("%s:%d=>%s\n", inet_ntoa(send_addr.sin_addr), ntohs(send_addr.sin_port), recvBuf);//输出接收的数据;inet_ntoa()是将长整型的数据转化为点分十进制的数据;ntohs()是将网络字符数据转化为主机字符数据    }//关闭这个 socketclosesocket(sock_fd);}static void TCPClientDemo(void){osThreadAttr_t attr;attr.name = "TCPClientTask";attr.attr_bits = 0U;attr.cb_mem = NULL;attr.cb_size = 0U;attr.stack_mem = NULL;attr.stack_size = 10240;attr.priority = osPriorityNormal;if (osThreadNew((osThreadFunc_t)TCPClientTask, NULL, &attr) == NULL)    {printf("[TCPClientDemo] Falied to create TCPClientTask!\n");    }}APP_FEATURE_INIT(TCPClientDemo);UDP服务端:案例代码:#include <stdio.h>#include <unistd.h>#include "ohos_init.h"#include "cmsis_os2.h"#include "lwip/sockets.h"#include "wifi_connect.h"#define _PROT_ 8888#define TCP_BACKLOG 10//在sock_fd 进行监听,在 new_fd 接收新的链接int sock_fd, new_fd;char recvbuf[512];char *buf = "Hello! I'm BearPi-HM_Nano UDP Server!";static void UDPServerTask(void){//服务端地址信息struct sockaddr_in server_sock;//客户端地址信息struct sockaddr_in client_sock;int sin_size;struct sockaddr_in *cli_addr;//连接WifiWifiConnect("袁初", "123456789");//创建socketif ((sock_fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)    {perror("socket is error\r\n");exit(1);    }bzero(&server_sock, sizeof(server_sock));server_sock.sin_family = AF_INET;server_sock.sin_addr.s_addr = htonl(INADDR_ANY);server_sock.sin_port = htons(_PROT_);//调用bind函数绑定socket和地址if (bind(sock_fd, (struct sockaddr *)&server_sock, sizeof(struct sockaddr)) == -1)    {perror("bind is error\r\n");exit(1);    }// //调用listen函数监听(指定port监听)// if (listen(sock_fd, TCP_BACKLOG) == -1)// {//  perror("listen is error\r\n");//  exit(1);// }// printf("start accept\n");//调用accept函数从队列中while (1)    {sin_size = sizeof(struct sockaddr_in);// if ((new_fd = accept(sock_fd, (struct sockaddr *)&client_sock, (socklen_t *)&sin_size)) == -1)// {//  perror("accept");//  continue;// }// cli_addr = malloc(sizeof(struct sockaddr));// printf("accept addr\r\n");// if (cli_addr != NULL)// {//  memcpy(cli_addr, &client_sock, sizeof(struct sockaddr));// }//处理目标ssize_t ret;while (1)        {bzero(&recvbuf, sizeof(recvbuf));if ((ret = recvfrom(sock_fd, recvbuf, sizeof(recvbuf), 0, (struct sockaddr *)&client_sock, (socklen_t *)&sin_size)) == -1)            {printf("recv error \r\n");            }printf("recv :%s\r\n", recvbuf);// sleep(2);if ((ret = sendto(sock_fd, buf, strlen(buf) + 1, 0, (struct sockaddr *)&client_sock, sizeof(client_sock))) == -1)            {perror("send : ");            }// sleep(2);        }close(sock_fd);    }}static void UDPServerDemo(void){osThreadAttr_t attr;attr.name = "UDPerverTask";attr.attr_bits = 0U;attr.cb_mem = NULL;attr.cb_size = 0U;attr.stack_mem = NULL;attr.stack_size = 10240;attr.priority = osPriorityNormal;if (osThreadNew((osThreadFunc_t)UDPServerTask, NULL, &attr) == NULL)    {printf("[UDPServerDemo] Falied to create UDPServerTask!\n");    }}APP_FEATURE_INIT(UDPServerDemo);MQTT客户端:嵌入式c语言客户端开源地址:https://github.com/eclipse/paho.mqtt.embedded-cMQTT消息代理软件mosquitto下载地址:https://mosquitto.org/download/Eclipse桌面客户端程序下载地址:https://repo.eclipse.org/content/repositories/paho-releases/org/eclipse/paho/org.eclipse.paho.ui.app/1.1.1/MQTT客户端的简单使用:1)安装mosquitto(记住安装位置)2)打开mosquitto安装文件夹中的配置文件3)搜索“allow_anonymous”(第529行),修改为“allow_anonymous true”,4)搜索“listener”(第232行),修改为“listener 1883 你的电脑IP”,再加一行“listener 1883 localhost”,然后保存退出5)在任务管理器里寻找到mosquitto服务并启动6)打开客户端工具实例代码解析:#include <stdio.h>#include <string.h>#include <stdlib.h>#include "ohos_init.h"#include "cmsis_os2.h"#include "wifi_connect.h"#include "MQTTClient.h"static unsigned char sendBuf[1000];static unsigned char readBuf[1000];Network network;//订阅消息的回调函数void messageArrived(MessageData* data){printf("Message arrived on topic %.*s: %.*s\n", data->topicName->lenstring.len, data->topicName->lenstring.data,data->message->payloadlen, data->message->payload);}/* */static void MQTT_DemoTask(void){WifiConnect("Hold","0987654321");printf("Starting ...\n");int rc, count = 0;MQTTClient client;NetworkInit(&network);printf("NetworkConnect  ...\n");begin: NetworkConnect(&network, "192.168.0.176", 1883);//连接MQTT服务端printf("MQTTClientInit  ...\n");MQTTClientInit(&client, &network, 2000, sendBuf, sizeof(sendBuf), readBuf, sizeof(readBuf));//初始化并创建一个MQTT对象//配置MQTT客户端的信息MQTTString clientId = MQTTString_initializer;clientId.cstring = "bearpi";MQTTPacket_connectData data = MQTTPacket_connectData_initializer;  data.clientID          = clientId;//iddata.willFlag          = 0;data.MQTTVersion       = 3;//版本信息data.keepAliveInterval = 0;//保活时间data.cleansession      = 1;printf("MQTTConnect  ...\n");rc = MQTTConnect(&client, &data);//发送连接数据包//如果发送失败则断开连接,返回到begin:处重新连接MQTT服务端if (rc != 0) {printf("MQTTConnect: %d\n", rc);NetworkDisconnect(&network);MQTTDisconnect(&client);osDelay(200);goto begin;}//订阅消息substopicprintf("MQTTSubscribe  ...\n");rc = MQTTSubscribe(&client, "substopic", 2, messageArrived);if (rc != 0) {printf("MQTTSubscribe: %d\n", rc);osDelay(200);goto begin;}//每500ms发布一次消息的服务pubtopicwhile (++count){MQTTMessage message;char payload[30];message.qos = 2;message.retained = 0;message.payload = payload;sprintf(payload, "message number %d", count);message.payloadlen = strlen(payload);if ((rc = MQTTPublish(&client, "pubtopic", &message)) != 0){printf("Return code from MQTT publish is %d\n", rc);NetworkDisconnect(&network);MQTTDisconnect(&client);goto begin;}osDelay(50); }}static void MQTT_Demo(void){    osThreadAttr_t attr;    attr.name = "MQTT_DemoTask";    attr.attr_bits = 0U;    attr.cb_mem = NULL;    attr.cb_size = 0U;    attr.stack_mem = NULL;    attr.stack_size = 10240;    attr.priority = osPriorityNormal;    if (osThreadNew((osThreadFunc_t)MQTT_DemoTask, NULL, &attr) == NULL) {        printf("[MQTT_Demo] Falied to create MQTT_DemoTask!\n");    }}APP_FEATURE_INIT(MQTT_Demo);本文只是个人浅解,可能有些注释不正确,万分抱歉
  • [交流吐槽] 第六
    ## HarmonyOS网络应用开发UDP客户端(6.1) **本节主要介绍:** - UDP协议相关API - UDP客户端创建流程 - UDP通信流程 **:三目录** 1. UDP协议相关API介绍 2. UDP客户端创建流程介绍 3. 实现UDP客户端 4. 测试UDP客户端 5. 总结 ------ #### UDP协议相关API介绍 ------ ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20227/23/1658572703274541614.png) #### UDP客户端创建流程介绍 ------ **流程:** ​ 1.UDP客户端通过socket()创建套接字 ​ 2.sendto()发送数据请求,将数据发送到UDP服务端 ​ 3.服务端接收到数据后做数据应答,也就是服务端接收到数据后发送一些数据给客户端 ​ 4.客户端使用recvfrom函数接收数据 ​ 5.当不需要UDP客户端时使用close关闭客户端 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20227/23/1658572717575352319.png) #### 实现UDP客户端 ------ 打开"D3_ iot udp_client"工程的udp_ _client demo.c文件,可在代码中查看实现UDP客户端的代码。 **创建客户端之前需要连接热点。** ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20227/23/1658572731315379335.png) #### 测试UDP客户端 ------ **1.****使用Socket tool创建UDP服务端用于测试.** ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20227/23/1658572745219796706.png) **2.**上述**工具下载地址****:** https://pan.baidu.com/s/13YlqQVzEa5ygcQeTSGQ_JA提取码: 1234 **3.****打开窗口命令行****:**win R,输入cmd,输入ipconfig读取ip得到IP地址: ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20227/23/1658572756589798384.png) ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20227/23/1658572764549368337.png) 编译:![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20227/23/1658572793289808452.png) ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20227/23/1658572806249231843.png) ## HarmonyOS网络应用开发- -TCP服务端(6.2) **本节主要介绍:** - TCP协议相关API - TCP服务端创建流程 - TCP通信流程 **本节主要介绍:** 1. TCP协议相关API 2. TCP服务端创建流程 3. TCP通信流程 ------ #### TCP协议相关API介绍 ------ ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20227/23/1658572840347460238.png) #### TCP服务端创建流程介绍 ------ **流程:** ​ TCP服务端通过socket()创建套接字,再调用bind把ip和端口传递到套接字上,listen是用套接字创立的监听,然后accept的API一直阻塞,一旦连接,TCP客户端就可以发送数据使TCP服务端接收。如果服务端要发送数据调用send,由客户端接收,如果客户端关闭套接字,服务端随之关闭套接字。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20227/23/1658572858581231399.png) #### 实现TCP服务端 ------ 打开"D4_ iot_tcp_ server" 工程的tcp_ server.demo.c文件,可以查看实现TCP服务的代码。 **创建服务端之前需要连接WIFI 。** 编译:仍使用python build.py BearPi-HM Nano 继续执行:同上 HiBurn 打开串口工具 等待连接wifi Socket软件调试 ## HarmonyOS网络应用开发- -TCP客户端(6.3) **本节主要介绍:** - TCP协议相关API - TCP客户端创建流程 - TCP通信流程 **本节主要介绍:** 1. TCP协议相关API 2. TCP客户端创建流程 3. TCP通信流程 ------ #### TCP协议相关API介绍 ------ ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20227/23/1658572873614708613.png) #### TCP客户端创建流程介绍 ------ **流程:** ​ TCP客户端通过socket()创建套接字,再调用connect进行客户端与服务端的连接,一旦连接成功,TCP客户端就可以用send发送数据使TCP服务端接收。如果服务端要发送数据调用send,由客户端接收,如果客户端关闭套接字,服务端随之关闭套接字。 注意:TCP客户端创建流程图与TCP服务端创建流程图相同,方向不同。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20227/23/1658572886133453201.png) #### 实现TCP客户端 ------ 打开"D3_ iot udp_ client" 工程的udp_ _client _demo.c文件,修改部分代码即可实现TCP客户端。 **创建客户端之前需要连接WIFI 。** **视频在编译前有部分报错,后面会纠正,实操时要注意。** 编译:仍使用python build.py BearPi-HM Nano 继续执行:同上 HiBurn 打开串口工具 等待连接wifi Socket软件调试 ## HarmonyOS网络应用开发- -UDP服务端(6.4) **本节主要介绍:** - UDP协议相关API - UDP服务端创建流程 - UDP通信流程 **:三目录** 1. UDP协议相关API介绍 2. UDP服务端创建流程介绍 3. 实现UDP客户端 4. 总结 ------ #### UDP协议相关API介绍 ------ ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20227/23/1658572913642211941.png) #### UDP服务端创建流程介绍 ------ **流程:** 1. UDP服务端通过socket()创建套接字 2. 再调用bind把ip和端口传递到套接字上 3. 用recvfrom接收数据,sendto()传递数据 4. UDP服务端关闭,客户端随之关闭 ----------------------------------- ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20227/23/1658572921807921737.png) #### 实现UDP服务端 ------ 打开"D4_ iot_ tcp server"工程的tcp_ server_ demo.c文件,修改部分代码即可实现UDP服务端。 **创建客户端之前需要连接WIFI 。** **视频在编译前有部分报错,后面会纠正,实操时要注意。** 编译:仍使用python build.py BearPi-HM Nano 继续执行:同上 HiBurn 打开串口工具 等待连接wifi Socket软件调试 ## HarmonyOS网络应用开发- -MQTT客户端(6.5) **本节主要介绍:** - 什么是Paho MQTT - Paho MQTT文件目录 - 如何使用Paho MQTT ​ **目录:** 1. MQTT介绍 2. Paho MQTT文件目录介绍 3. 如何使用Paho MQTT 4. 实现MQTT客户端 5. 总结 ------ ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20227/23/1658572951565358380.png) ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20227/23/1658572958217271080.png) ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20227/23/1658572966628482293.png) ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20227/23/1658572979378817657.png) ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20227/23/1658572996313166187.png) MQTT消息代理软件mosquitto下载地址: https://mosquitto.org/download/