微信公众号免费制作成微网站盱眙有做网站开发的吗

张小明 2026/3/12 8:43:42
微信公众号免费制作成微网站,盱眙有做网站开发的吗,档案网站建设比较分析,如何在电脑登录wordpress一、项目背景与设计目标 在典型的IOT物联网应用中#xff0c;嵌入式硬件设备#xff08;如 ESP8266 / ESP32#xff09;往往部署在内网或复杂网络环境中#xff0c;而控制端#xff08;PC / 手机 / 上位机#xff09;需要通过云端服务器与这些设备进行远程通信。 IOT物联…一、项目背景与设计目标在典型的IOT物联网应用中嵌入式硬件设备如 ESP8266 / ESP32往往部署在内网或复杂网络环境中而控制端PC / 手机 / 上位机需要通过云端服务器与这些设备进行远程通信。IOT物联网通常都是要实现以下功能支持多个硬件客户端同时在线支持软件控制端与指定硬件设备通信支持云端服务器对客户端进行统一管理与数据转发协议简单、可扩展、适合 MCU 侧实现二、通信协议设计为了降低 MCU 端解析复杂度协议采用定长二进制结构体并通过#pragma pack(1)保证字节对齐。1.定义存放客户端传输数据的结构体#pragma pack(1) //以下结构体以一个字节对齐 //定义存放客户端传输数据的结构体 struct SocketRxTxData { unsigned char FrameHead[4]; //存放帧头数据 固定为: 0xA1 0xA2 0xA3 0xA4 unsigned char Databuffer[30]; //存放传输的字符串数据 unsigned int id[3]; //存放96位ID号 unsigned char clientmode; //0表示硬件客户端 1表示软件控制客户端 unsigned int CheckSum; //存放数据位的校验和 };协议设计要点固定帧头用于快速丢弃非法数据96 位 ID唯一标识一组通信对象clientmode区分控制端与被控端简单累加校验和适合 MCU 实时计算二、IOT物联网服务端实现1. 服务器核心任务1监听指定TCP端口接受客户端连接。2为每个TCP客户端创建独立线程。3保存客户端的信息ID / fd / 类型。4根据协议规则转发数据。2. 多客户端并发连接架构实现服务器采用一个主线程 多个子线程 的架构一个主线程 负责TCP服务端的创建、监听和接收客户端。多个子线程 负责每一个客户端的数据收发处理。/*TCP服务器代码*/ int main(int argc,char *argv[]) { if(argc ! 2) { printf(传参格式./app 端口号\n); return -1; } //相关变量定义 pthread_t thread_id; //存放线程的标识符 struct sockaddr_in client_address; //存放客户端的信息 socklen_t address_len; //存放客户端结构体信息的长度 int socketfd; //保存TCP服务器的网络套接字 int *clientfd; //保存TCP客户端的网络套接字 struct sockaddr_in server_address; //存放服务器的IP地址信息 memset(server_address,0,sizeof(struct sockaddr_in)); //初始化内存空间 memset(client_address,0,sizeof(struct sockaddr_in)); //初始化内存空间 server_address.sin_familyPF_INET; //IPV4协议 server_address.sin_porthtons(atoi(argv[1])); //端口号赋值 server_address.sin_addr.s_addrINADDR_ANY; //本地IP地址 /*初始化信号量*/ sem_init(lock,0,1); //信号量的值初始为 1表示资源可用 //创建链表头 TCP_ClientInfoListHeadCreateListHead(TCP_ClientInfoListHead); /*1 .创建套接字*/ socketfdsocket(PF_INET,SOCK_STREAM,0); if(socketfd0) { printf(服务器网络套接字创建失败!\n); return -1; } int on 1; setsockopt(socketfd, SOL_SOCKET, SO_REUSEADDR, on, sizeof(on)); /*2. 绑定端口创建服务器*/ if(bind(socketfd,(const struct sockaddr *)server_address,sizeof(struct sockaddr))!0) { printf(服务器绑定端口失败!\n); return -1; } /*3. 设监听的端口数量*/ if(listen(socketfd,100)!0) { printf(服务器端口监听失败!\n); return -1; } int i; while(1) { address_lensizeof(struct sockaddr); //计算结构体大小 20 //申请空间,线程并发执行不能使用变量地址传参数 clientfdmalloc(sizeof(int)); /*4. 等待客户端连接*/ if((*clientfdaccept(socketfd,(struct sockaddr *)client_address,address_len))0) { printf(等待客户端连接失败!\n); break; } /*打印一些客户端的信息*/ printf(成功连接的客户端端口号:%d\n,ntohs(client_address.sin_port)); printf(成功连接的客户端IP地址:%s\n,inet_ntoa(client_address.sin_addr)); //创建线程 if(pthread_create(thread_id,NULL,pthread_func,(void*)clientfd)!0) { printf(线程_%d_创建失败!\n,i); } pthread_detach(thread_id); //设置分离属性自己回收资源 } sem_destroy(lock); //注销信号量 return 0; }3. 客户端信息管理链表服务器通过单向链表维护所有在线客户端/*------------------------------------------------------------------------------*/ #pragma pack(1) //以下结构体以一个字节对齐 //定义存放客户端信息的结构体 struct SocketTcpClient { unsigned int id[3]; //存放96位ID号 int clientfd; //存放客户端文件描述符 unsigned char clientmode; //存放客户端区分标志 0表示硬件客户端 1表示软件客户端 struct SocketTcpClient *next; //定义存放下一个地址的成员 };客户端首次发送合法数据包后加入链表/* 函数功能:链表结尾添加新的节点 函数参数: head:链表头 NewData:要添加进去的结构体数据 */ void AddNewListNode(struct SocketTcpClient *head,struct SocketTcpClient NewData) { struct SocketTcpClient *phead; //保存链表头 struct SocketTcpClient *tmpNULL; //新链表节点 /*1. 找到链表结尾*/ while(p-next!NULL) { pp-next; } /*2. 申请新节点*/ tmpmalloc(sizeof(struct SocketTcpClient)); //申请新的节点空间 memcpy(tmp,NewData,sizeof(struct SocketTcpClient)); //拷贝结构体数据 tmp-nextNULL; //结尾指向空 /*3. 添加新节点到链表结尾*/ p-nexttmp; }客户端断开连接时从链表中删除/* 函数功能: 根据文件描述符删除指定的链表节点 函数参数: head :链表头 clientfd:文件描述符 */ void DeleteListNode(struct SocketTcpClient *head,int clientfd) { struct SocketTcpClient *phead; //保存链表头 struct SocketTcpClient *tmpNULL; //保存链表地址节点 /*1. 查找要删除的链表节点*/ while(p-next!NULL) { tmpp; //保存上一个节点的地址 pp-next; if(p-clientfdclientfd) //查找到节点 { /*2. 删除节点*/ tmp-nexttmp-next-next; //连接节点 free(p); //释放节点空间 break; } } }4. 数据转发逻辑核心服务器并不关心数据内容仅根据规则转发ID相同的两个客户端但TCP套接字不一样。这使得一个软件客户端可以控制指定硬件设备多组设备之间互不干扰服务器逻辑高度通用/*---------------------------------------遍历链表向符合条件客户端发送数据-----------------------------*/ int SendDataToClient(struct SocketRxTxData data, int clientfd) { int cnt 0; struct SocketTcpClient *p TCP_ClientInfoListHead; while(p ! NULL) { if(p-id[0]data.id[0]p-id[1]data.id[1]p-id[2]data.id[2]p-clientfd!clientfdp-clientmode!data.clientmode) //查找到节点 { //存在就转发数据 write(p-clientfd,(void*)data,sizeof(struct SocketRxTxData)); cnt; } p p-next; } return cnt; }三、IOT物联网客户端实现1. 客户端核心任务TCP 客户端主要用于1连接云端服务器2定期发送数据帧3接收并解析服务器转发的数据2. 客户端实现简单来说就是创建TCP客户端→连接TCP服务端→收发数据→校验数据→解析数据/* TCP客户端创建 */ int main(int argc,char **argv) { struct SocketRxTxData RxTxData; int tcp_client_fd; //客户端套接字描述符 int Server_Port; //服务器端口号 struct sockaddr_in tcp_server; //存放服务器的IP地址信息 int rx_len; struct SocketRxTxData socket_data; struct SocketRxTxData rx_data; fd_set readfds; struct timeval timeout; if(argc!7) { printf(TCP客户端形参格式:./tcp_client 服务器IP地址 端口号 stringData id1 id2 id3\n); return -1; } /*1. 创建网络套接字*/ tcp_client_fdsocket(AF_INET,SOCK_STREAM,0); if(tcp_client_fd0) { printf(TCP服务器端套接字创建失败!\n); return -1; } /*2. 连接到指定的服务器*/ tcp_server.sin_familyAF_INET; //IPV4协议类型 tcp_server.sin_porthtons(atoi(argv[2]));//端口号赋值,将本地字节序转为网络字节序 tcp_server.sin_addr.s_addrinet_addr(argv[1]); //IP地址赋值 if(connect(tcp_client_fd,(const struct sockaddr*)tcp_server,sizeof(const struct sockaddr))0) { printf(TCP客户端: 连接服务器失败!\n); return -1; } //封装结构体 SetPackageData(socket_data,argv[3],atoi(argv[4]),atoi(argv[5]),atoi(argv[6])); while(1) { FD_ZERO(readfds); //清除文件描述符集合 FD_SET(tcp_client_fd,readfds); //设置监听的文件描述符 timeout.tv_sec1; timeout.tv_usec100; /*监控是否有对应的事件发生*/ rx_lenselect(tcp_client_fd1,readfds,NULL,NULL,timeout); if(rx_len0) //有数据 { rx_lenread(tcp_client_fd,rx_data,sizeof(struct SocketRxTxData)); if(rx_lensizeof(struct SocketRxTxData)) { if(CheckPackageData(rx_data)0) { printf(rx%s,%d,%d,%d\n,rx_data.Databuffer,rx_data.id[0],rx_data.id[1],rx_data.id[2]); } } if(rx_len0)break; //客户端断开连接 } if(rx_len0)break; //出现错误 if(rx_len0) //没有事件产生,等待超时 { //向服务器发送数据 write(tcp_client_fd,socket_data,sizeof(struct SocketRxTxData)); } } /*4. 关闭连接*/ close(tcp_client_fd); }数据封包和校验/* 函数功能: 数据封包 */ void SetPackageData(struct SocketRxTxData *p,char *str,int id1,int id2,int id3) { int i; p-FrameHead[0]0xA1; p-FrameHead[1]0xA2; p-FrameHead[2]0xA3; p-FrameHead[3]0xA4; memcpy(p-Databuffer,str,30); p-CheckSum0; p-id[0]id1; p-id[1]id2; p-id[2]id3; p-clientmode 1;//标志为软件客户端 //赋值校验和 for(i0;i30;i) { p-CheckSump-Databuffer[i]; } } /* 函数功能:判断传输的数据是否正确 函数返回值: 0正确 其他值错误 */ int CheckPackageData(struct SocketRxTxData ClientRxTxData) { int i; unsigned int CheckSum0; //存放校验和 /*1. 判断帧头是否正确*/ if(ClientRxTxData.FrameHead[0]!0xA1|| ClientRxTxData.FrameHead[1]!0xA2|| ClientRxTxData.FrameHead[2]!0xA3|| ClientRxTxData.FrameHead[3]!0xA4) { return -1; } /*2. 计算校验和*/ for(i0;i30;i) { CheckSumClientRxTxData.Databuffer[i]; } if(CheckSum!ClientRxTxData.CheckSum) //校验失败 { return -1; } return 0; //数据校验成功 }四、IOT服务端客户端源码附件【免费】IOT物联网服务端和客户端搭建代码资源-CSDN下载https://download.csdn.net/download/qq_34885669/92470649
版权声明:本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

做网站主机要选好哪里做网站一套一百

一键解锁QQ音乐加密音频:跨平台播放终极指南 【免费下载链接】QMCDecode QQ音乐QMC格式转换为普通格式(qmcflac转flac,qmc0,qmc3转mp3, mflac,mflac0等转flac),仅支持macOS,可自动识别到QQ音乐下载目录,默认转换结果存…

张小明 2026/3/5 5:15:39 网站建设

江西省城乡建设培训网 官方网站北京团购网站建设

第一章:AI驱动的洗车服务新范式人工智能正以前所未有的速度重塑传统服务行业,洗车服务作为高频次、标准化需求突出的场景,成为AI技术落地的理想试验田。通过融合计算机视觉、物联网设备与自动化控制算法,新一代智能洗车系统能够实…

张小明 2026/3/5 5:15:39 网站建设

手机网站开发软件有哪些湛江市住房建设局网站

24小时无人化篮球馆:硬件支撑体系全解析无人化篮球馆的顺畅运行,离不开软硬件的深度协同。以“全场景自助、低运维成本、高用户体验”为核心构建的硬件矩阵,覆盖准入、管控、服务、数据全链条,通过设备智能联动实现“无人在场却全…

张小明 2026/3/5 5:15:42 网站建设

网站开发接口文档模板网站开发定制企业

Keil Assistant 使用指南:VS Code中的嵌入式开发利器 【免费下载链接】keil-assistant 项目地址: https://gitcode.com/gh_mirrors/ke/keil-assistant Keil Assistant 是一款专为嵌入式开发者设计的 Visual Studio Code 插件,它将 Keil uVision …

张小明 2026/3/5 5:15:42 网站建设

网站开发得多长时间网络营销策划书8000字

为什么你的QT应用需要Fluent设计风格?完整解决方案揭秘 【免费下载链接】ElaWidgetTools Fluent-UI For QT-Widget 项目地址: https://gitcode.com/gh_mirrors/el/ElaWidgetTools 还在为QT应用界面设计发愁吗?传统桌面风格已经无法满足现代用户的…

张小明 2026/3/5 5:15:43 网站建设

效果好的魔站建站系统杭州公司建站模板

用户权限与管理 作用&#xff1a;切换到 root 用户&#xff0c;并保持 root 环境变量 命令&#xff1a;sudo -i 作用&#xff1a;切换到 root 用户&#xff0c;保持完整环境 命令&#xff1a;sudo su - 作用&#xff1a;以 root 权限执行命令 命令&#xff1a;sudo <comm…

张小明 2026/3/5 5:15:43 网站建设