【持续更新】近期C++开发Modbus通讯接口小结

2023-10-27

项目需求:对PLC上存储的数据进行读取,并转存到数据库

语言:C++、DDL

所需知识点:Socket通信、Modbus帧结构、C++中数据库的操作、多线程、Linux

项目进度拆解记录(不会做就是困难!!管它简不简单!)

1、Socket通信。

        由于之前一直采用串口通信,并未了解过其他通信机制,所以&*%¥%!@#(啥也不会)。打开网页、视频各种学习,发现是自己掌握的TCP通信机制,但自己只是理论掌握,不具备代码实现的能力,在CSDN、GitHub寻找各种资源后,终于写出了自己的Socket.cpp。这只是开始,耗时一周(严重浪费!!!)

        1.1、Socket通信连接问题

       在不打开服务器的情况下,程序会一直停在连接时(我用的是connect连接)。且打开服务器后,通信连接成功,但会报出一个错误(自己写的,取出connect返回值为-1)。这里理想的优化方案是连接服务器超时时,报出一个错误,然后再尝试继续连接。实现方式学习中……

2、Modbus帧结构。(这个我可以,最喜欢帧结构!)

        2.1、Socket通信连接问题

       耗时一个下午,各处查找资料后,学习到Modbus帧中的位所代表的信息。——这里安利两个小工具(Modbus Slave和Modbus Poll)下载地址(链接:https://pan.baidu.com/s/1YNz1wbb6PeRrVDhg2mrdgQ 提取码:z2a0 --来自百度网盘超级会员V4的分享)——下图可以即为帧结构,显然~~~所以~~~这里懂了。在代码实现的过程中,由于不可抗力的被要求加入CRC校验算法,然后打开GitHub一顿扒拉,读了很多之后,自己写了一段适合自己的,然后!发现CRC在TCP里不需要(内心:hhhh我就当学习了吧,rm -rf /*                  One week later!)

        2.2、忽略MODBUS通信机制造成的错误

        在modbus中,下发信息后,目标机会回复一条信息(即便是在下发修改指令)。此处,由于我在下发修改指令后,并未进行接收数据的操作,导致我其它读值部分读取的全是修改的返回数据。于是便在修改后加入一个recv接收socket中的缓冲区进行清空缓冲区(十分重要),用数组接受完后,记得释放数组,不然也会引发异常。

3、MySQL。

        之前只用过Access和SQLServers,众所周知,这俩都是图形化操作界面,真的是很友好了,首先,拿到外包提供的数据库不会链接到自己的库中,只好转txt然后Ctrl CV(神技)自己执行。这里感谢好朋友的帮助,提供给我Navicat,用起来感觉MySQL也就洒洒水啦,有了图形化操作界面我乱点都点的出来,嘿嘿嘿。。。。回归正题,之后用C++链接数据库,这里应该不算是一个难点了,无非是增删改查,各种资源一看就懂。

        3.1 数据库写入时的中文乱码。

          本来在写连接的时候,有些函数设置了语句:

        const char* query = "set names \'GBK\'";
        mysql_query(_mysql, query);

        但是由于并未在我写入之前进行设置,所以我把这里的设置改到对数据库的连接中,连接上数据库后立刻设置,Nice!

        3.2 重复写入机制的优化

        由于对对某一个表需要重复写入200条记录,每次的值都相当于是刷新替代旧的值。为了防止对数据库写入超行和写入数据重复,我在写入前优先使用查询语句进行查询内容是否存在,存在则选择UPDATE更新值,不存在的话使用INSERT插入值。

--------------------------------------------------------------分割------------------------------------------------------------

         然后突然发现有一个REPLACE语句,可以直接更换,相当于对我的查询和插入做了一个集合。对接口来说,在整个写入过程中,时间减少了一半,且REPLACE写入机制刚好符合我的要求,果断选择更换到REPLACE语句实现。

--------------------------------------------------------------分割------------------------------------------------------------

         抱着重温Mysql知识的想法,去官网看了一下插入语言。突然发现对INSERT插入时,有一个关键字IGNORE可以忽视主键存在,进行重复插入。于是取消REPLACE方法。(此处有一个猜想,在调用REPLACE时,前、后端对数据库的异步操作,会不会对前端来说,在某次查询数据时,由于REPLACE引起的清空而导致表中数据为NULL然后报错?)有待验证~

4、关于整个接口的实现方式引发的不同版本。

        姑且称多线程为V1.0,单线程为V2.0。问题来了,在V1.0版本中需要多线程的知识(我真的超级喜欢多线程,顺带学习了C++的多线程实现,声明实现~)问题来了,在多线程中我肯定不能用同一个socket连接和数据库连接吧,于是大方地给了每个线程发了一个新的。这里就得加上互斥锁了!但,问题来了,数据库新建连接多了导致我写入超时(这里是因为我在每个线程后未断开数据库)。由于时间的影响,本来找到的解决办法:数据库的线程池操作,就被我pass掉了。于是Copy出副本,改V2.0,用同一个socket和数据库连接(但愿不会崩)一切就挺顺利,剩下的代码大同小异的查询PLC然后转存到数据库,祭出神技:Ctrl C(V)!!    (One week later)等待有空了一定把那个多线程的给搞出来,多线程在逻辑上更符合多功能实现!

5、C++。

       按理说这个应该是首要问题,但是对其的学习贯穿了我整个开发过程,属于边学习边实现。不过对const char *、char *、char、string还是区别不清(有问题即时百度,虽然有点浪费时间)。

        5.1、Printf假死

        C++中的printf竟然还会出现假死状态,我这里真的弄不懂为什么在连接socket和数据库的时候,我的printf不输出值,而且假死在数据库的连接中!!!为什么我的缓冲区就满了呀!我就写了几个字符而已啊!!!看了网上的

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【持续更新】近期C++开发Modbus通讯接口小结 的相关文章

  • 通过 SocketCAN 进行 boost::asio

    我正在考虑利用升压阿西奥 http www boost org doc libs 1 49 0 doc html boost asio html从a读取数据套接字CAN http en wikipedia org wiki SocketCA
  • 如何在 DataColumn.Expression 中使用 IF/ELSE 或 CASE?

    我有一个包含 1 列的表 状态 我想添加另一列名为 Action 的列 其值如下 如果 Status Yes 则 Action Go 否则 Action Stop 我使用以下代码添加到 操作 列中 但它不起作用 myDataTable Co
  • 在 C/C++ 中获得正模数的最快方法

    通常在我的内部循环中 我需要以 环绕 方式索引数组 因此 例如 如果数组大小为 100 并且我的代码要求元素 2 则应该给它元素 98 高级语言 例如 Python 可以简单地使用my array index array size 但由于某
  • 我如何理解这个 C 类型声明?

    double bar int double double double double 在查看讲座幻灯片时 我发现了留给学生的练习 用简单的英语来说 什么是类型bar在这个 C 声明中 Please帮助我解决这个问题 我什至不知道从哪里开始
  • 为什么在创建矩阵类时使用向量不好?

    对于我的矩阵类 我做了 template
  • 更改 Qt OpenGL 窗口示例以使用 OpenGL 3.3

    我正在尝试更改 Qt OpenGL 示例以使用更现代的 opengl 版本 330 似乎合适 所以我做了 在 main cpp 上设置版本和配置文件 设置着色器版本 更改着色器以使用统一 它现在构建没有任何错误 但我只看到一个空白窗口 我错
  • 在 Xamarin 中隐藏软键盘

    如何隐藏软键盘以便在聚焦时显示Entry在 Xamarin forms 便携式表单项目中 我假设我们必须为此编写特定于平台的渲染器 但以下内容不起作用 我创建自己的条目子类 public class MyExtendedEntry Entr
  • ASP.NET Web API 客户端 ProgressMessageHandler Post 任务卡在 WinForm 应用程序中

    我在用着HttpClient and ProgressMessageHandler来自MS ASP NET Web API 客户端库 http nuget org packages Microsoft AspNet WebApi Clien
  • 防止 boost::asio::io_context 在空轮询调用时停止

    此代码调用发布的句柄 boost asio io context ioc boost asio post ioc std cout lt lt lol lt lt std endl ioc poll 而这并没有 boost asio io
  • 与 Qt 项目的静态链接

    我有一个在 Visual Studio 2010 Professional 中构建的 Qt 项目 但是 当我运行它 在调试或发布模式下 时 它会要求一些 Qt dll 如果我提供 dll 并将它们放入 System32 中 它就可以工作 但
  • 如何在 SqlDataReader.Read() 期间从死锁异常中恢复

    我的 NET 应用程序的事件日志显示 它在从 Sql Server 读取数据时偶尔会出现死锁 这种情况通常非常罕见 因为我们已经优化了查询以避免死锁 但有时仍然会发生 过去 我们在调用ExecuteReader函数在我们的SqlComman
  • 指向特征矩阵的指针数组

    我在代码中使用 Eigen 的 MatrixXd 矩阵 在某个时刻我需要一个 3D 矩阵 由于 Eigen 没有三维矩阵类型 因为它仅针对线性代数进行了优化 因此我创建了一个 MatrixXd 类型的指针数组 Eigen MatrixXd
  • 动态生成的控件 ID 返回为 NULL

    我可以在 Page PreInit 函数中创建动态控件 如何检索控件及其 ID 我的 C 代码用于创建动态控件之一 var btn new WebForms Button btn Text btn ID Addmore btn Click
  • std::forward_as_tuple 将参数传递给 2 个构造函数

    我想传递多个参数以便在函数内构造两个对象 以同样的方式std pair
  • ASP.NET MailMessage.BodyEncoding 和 MailMessage.SubjectEncoding 默认值

    很简单的问题 但我在 MSDN 上找不到答案 查找 ASP NET 将用于的默认值 MailMessage BodyEncoding and MailMessage SubjectEncoding 如果你不在代码中设置它们 Thanks F
  • 跨多个域的 ASP.NET 会话

    是否有合适的 NET 解决方案来在多个域上提供持久服务器会话 即 如果该网站的用户在 www site1 com 下登录 他们也将在 www site2 com 下登录 安全是我们正在开发的程序的一个问题 Thanks 它是否需要在会话中
  • C++ Streambuf 方法可以抛出异常吗?

    我正在尝试找到一种方法来获取读取或写入流的字符数 即使存在错误并且读 写结束时间较短 该方法也是可靠的 我正在做这样的事情 return stream rdbuf gt sputn buffer buffer size 但如果streamb
  • C++0x中disable_if在哪里?

    Boost 两者都有enable if and disable if 但 C 0x 似乎缺少后者 为什么它被排除在外 C 0x 中是否有元编程工具允许我构建disable if按照enable if 哦 我刚刚注意到std enable i
  • QFileDialog::getSaveFileName 和默认的 selectedFilter

    我有 getSaveFileName 和一些过滤器 我希望当用户打开 保存 对话框时选择其中之一 Qt 文档说明如下 可以通过将 selectedFilter 设置为所需的值来选择默认过滤器 我尝试以下变体 QString selFilte
  • ASP.NET Core MVC 视图组件搜索路径

    在此处的文档中 https learn microsoft com en us aspnet core mvc views view components view aspnetcore 2 2 https learn microsoft

随机推荐

  • 位置式和增量式PID控制

    PID控制是一个二阶线性控制器 定义 通过调整比例 积分和微分三项参数 使得大多数的工业控制系统获得良好的闭环控制性能 优点 a 技术成熟 b 易被人们熟悉和掌握 c 不需要建立数学模型 d 控制效果好 e 鲁棒性 通常依据控制器输出与执行
  • 测试管理之测试过程

    测试过程 以此文来阐述自己对于测试过程的认识 目录 文章目录 目录 过程分类 测试过程主要分为测试前 测试中 测试完成 发布后 测试前 测试前注意事项 需求评审 参与评审 了解需求背景 需求详情以及需求价值 初步评估需求覆盖面 需求测试工作
  • CSS背景:背景色/背景图像/背景重复/背景附着/简写背景属性(一文搞懂)

    目录 CSS背景 CSS 背景色 实例 其他元素 实例 不透明度 透明度 实例 使用 RGBA 的透明度 实例 CSS 背景图像 实例 实例 实例 CSS 背景重复 实例 实例 CSS background repeat no repeat
  • 程序员版孔乙己

    互联网的格局 是和别处不同的 都是格子衫 稀疏的头发 双肩包 男 写代码的人 傍午傍晚散了工 每每三两人 背着手 沿着软件园溜达一圈 倘肯花点钱 便还会走到星巴克 买一杯咖啡 那样便能再多摸几分钟的鱼 我从十九岁起 便在软件园的星巴克打工
  • Vim 键盘贴纸(打印用)

    Vim是一个类似于Vi的著名的功能强大 高度可定制的文本编辑器 在Vi的基础上改进和增加了很多特性 vim学习过程中需要记住好多键位的使用 下面分享一下vim键位图 打印后贴在键盘上 原版下载地址 密码 ultv 注 作者纯手工打造 难免有
  • 数据相关知识点(数据资产、业务底座、业务中台、企业数仓、即席查询)

    业务底座 企业数仓所提供的支撑能力 业务中台 企业在经营过程中积累起来的 具有一定规模的且能够快速适应变化 能够支撑器企业数字化转型升级的能力 企业数仓 又名企业数据仓库 是一个面向主题的 集成的 非易失的且随时间变化的数据集合 用来支持管
  • 微信小程序自定义弹窗实现详解(可通用)

    本文为自定义弹窗 该内容可满足如下需求 自定义各种布局弹窗 点击弹窗布局外消失弹窗 弹出弹窗时背景阴影半透明 各方向弹出效果 本文为自下而上弹出 wxml 文件中 直接放到wxml的最底部就行了 十分简练
  • Unity之实现拖拽UI功能

    一 unity 图片切割 先把图片导入到Unity中 选中图片你会看到上边的Inspector界面 然后 选择Texture Type类型为Advanced 将Read Write Enabled选上 然后Sprite Mode选择Mult
  • [ Matlab ] 遗传算法求最短路径

    打包下载源代码 实例描述 配送中心数为 1 客户数 k 为 8 车辆总数 m 为 2 车辆载重皆为 8 吨 各客户点需求为 g i 1 2 8 单位为吨 已知客户点与配送中心的距离如表 1 其中 0 表示中心仓库 要求合理安排车辆的运输路线
  • 服务计算——web 技术 - 处理 Request 与 Response

    基于Negroni框架的cloudgo应用 本次实验是基于Negroni框架的应用 我设计了一个简单的四则运算应用 这个应用设计主要分为两部分 中间件设计 以及 main函数的设计 接下来就分别对这两个部分进行介绍 中间件设计 printF
  • VS2017配置Qt开发环境

    VS2017配置Qt开发环境 安装Qt5 12 11 安装Qt插件 在VS2017中进行设置 参考教程 安装Qt5 12 11 安装Qt插件 在VS2017中进行设置 参考教程 Qt下载地址 https download qt io Qt安
  • 前端拖拽自动生成代码_我的前端布局自动化——开始,布局自动生成(一)

    在web前端工作的这些年 历经多次技术变革 不过依然只是一个追随大牛们的小白 此时此刻 尤其加班时 最想做的就是干掉自己职业的东西 做一个可代替前端工作的工具 由此开始了前端自动化探索 这篇文章就是自己的旗子吧 先举起一面变革之旗 不论自己
  • 关于Number.toFixed()的总结

    关于Number toFixed 函数的总结 前言 今天工作中遇到了一个需求 需要将类似于 1 99999 这样的数字格式化为 2 00 这样的两位小数 本来打算自己实现一个类似的功能函数 但是没想到看起来容易 实际实现起来却还是有点复杂的
  • Windows server 2016 云主机创建虚拟机

    Windows server 2016 云主机创建虚拟机 Hyper V 安装失败 处理器没有所需要的虚拟化功能 vmvare workstation play 17 安装 vmvare ok https customerconnect v
  • 【毕设教程】深度学习经典网络 CNN模型:ResNet

    文章目录 0 简介 1 ResNet 介绍 2 深度网络的退化问题 3 残差学习 4 ResNet的网络结构 5 ResNet的TensorFlow实现 6 最后 0 简介 Hi 大家好 这里是丹成学长的毕设系列文章 对毕设有任何疑问都可以
  • HTML-CSS笔记_0424

    HTML CSS 学习笔记源码 链接 https pan baidu com s 1PRorRSlAW0PSHM4grOoapg 提取码 fnr2 HTML 一 网页的基本结构和基础 1 html基础
  • qt 实现UDP通信简单案例

    实现效果 实现功能 创建两个界面 可以通过udp进行通信 并显示通信内容 界面部分由代码实现 并使用qss简单美化 udp通信由创建套接字 绑定端口号 发送和接收数据函数完成 代码实现 创建第一个通信对象 ud1 h ifndef UDPU
  • 【CV学习笔记】onnx篇之DETR

    1 摘要 本次学习内容主要学习了DETR的网络结构 损失函数等知识 明白了DETR是如何做到了端到端的检测 确实是一个十分优雅的框架 同时将DETR利用onnxtime进行推理 对于transformer的理解进一步加深了 DETR学习链接
  • Vue中关于组件的封装复用

    我们在写前端代码时常常会有一些控件或者HMTL代码片段在许多页面都需要 并且内容几乎一样 只是数据的不同而已 此时 我们就可以把这些代码封装成组件 以供我们重复使用 组件化 是一种思想 解决对复杂问题简单化的思想 将我们的程序开发成一个个独
  • 【持续更新】近期C++开发Modbus通讯接口小结

    项目需求 对PLC上存储的数据进行读取 并转存到数据库 语言 C DDL 所需知识点 Socket通信 Modbus帧结构 C 中数据库的操作 多线程 Linux 项目进度拆解记录 不会做就是困难 管它简不简单 1 Socket通信 由于之