在完成了前面的工作后,我们就可以实现有针对性的应用了,首先我们来实现Modbus TCP的服务器端应用。当然我们不是做具体的应用,而是对Modbus TCP的服务器端应用进行封装以供有需要时调用。
这里我们不涉及TCP的协议,这部分与Modbus没有必然联系,我们只是在其应用层运行Modbus协议而已。
对于Modbus TCP的服务器我们需要实现几个功能:首先是对接收到客户端命令进行解析,我们只实现前面提到的8中常用的功能吗的支持。其次在解析完成后,我们要实现对应各种功能码的操作。具体架构如下:
1、命令解析
服务器作为被动端接收到客户端的请求后,安装请求进行处理。所以服务器接收到信息后首先对其进行解析,这里我们只需要一个解析函数就可以完成,当在具体应用中时只要将接收到的信息调用这个函数解析就可以了。
/*解析接收到的信息,返回响应命令的长度*/
uint16_t ParsingClientAccessCommand(uint8_t *receivedMessage,uint8_t *respondBytes)
其实对外来说只有这一个函数时可见的。当我们要开发一个TCP Server的应用时,就调用这个函数。
2、命令处理
命令解析出来了之后,按不同的功能码来进行不同的处理,我们支持8种功能码,每种功能吗都对应处理部分,很多时候大家都会在解析的时候根据解析结果处理,这势必需要一个很大的解析函数。为了简化操作,我们将每个功能码对应的处理部分都封装为一个函数。然后使用一个函数指针数组来动态调用这些函数,从而简化这些函数。
首先我们需要8个处理对应个功能码操作的函数:
/*处理读线圈状态命令*/
static uint16_t HandleReadCoilStatusCommand(uint16_t startAddress,uint16_t quantity,uint8_t *receivedMessage,uint8_t *respondBytes)
/*处理读输入状态命令*/
static uint16_t HandleReadInputStatusCommand(uint16_t startAddress,uint16_t quantity,uint8_t *receivedMessage,uint8_t *respondBytes)
/*处理读保持寄存器命令*/
static uint16_t HandleReadHoldingRegisterCommand(uint16_t startAddress,uint16_t quantity,uint8_t *receivedMessage,uint8_t *respondBytes)
/*处理读输入寄存器命令*/
static uint16_t HandleReadInputRegisterCommand(uint16_t startAddress,uint16_t quantity,uint8_t *receivedMessage,uint8_t *respondBytes)
/*处理写单个线圈命令*/
static uint16_t HandleWriteSingleCoilCommand(uint16_t coilAddress,uint16_t coilValue,uint8_t *receivedMessage,uint8_t *respondBytes)
/*处理写单个寄存器命令*/
static uint16_t HandleWriteSingleRegisterCommand(uint16_t registerAddress,uint16_t registerValue,uint8_t *receivedMessage,uint8_t *respondBytes)
/*处理写多个线圈状态*/
static uint16_t HandleWriteMultipleCoilCommand(uint16_t startAddress,uint16_t quantity,uint8_t *receivedMessage,uint8_t *respondBytes)
/*处理写多个寄存器状态*/
static uint16_t HandleWriteMultipleRegisterCommand(uint16_t startAddress,uint16_t quantity,uint8_t *receivedMessage,uint8_t *respondBytes)
然后我们定义一个函数指针数组来调用这下函数:
uint16_t (*HandleClientCommand[])(uint16_t,uint16_t,uint8_t *,uint8_t *)={HandleReadCoilStatusCommand,
HandleReadInputStatusCommand,
HandleReadHoldingRegisterCommand,
HandleReadInputRegisterCommand,
HandleWriteSingleCoilCommand,
HandleWriteSingleRegisterCommand,
HandleWriteMultipleCoilCommand,
HandleWriteMultipleRegisterCommand};
3、响应的生成
对于响应命令的生成其实在第二篇中已经说过了,需要说明的是各种写数据的具体数值以及获得读数据的各种具体数值我们将在单独的文件中去实现,因为这部分TCP和RTU是相同的,我们将在后续的篇章中说明。
Modbus库开发笔记之三:Modbus TCP Server开发的更多相关文章
-
Modbus库开发笔记:Modbus ASCII Master开发
这一节我们来封装Modbus ASCII Master应用,Modbus ASCII主站的开发与RTU主站的开发是一致的.同样的我们也不是做具体的应用,而是实现ASCII主站的基本功能.我们将ASCI ...
-
CoolBlog开发笔记第2课:搭建开发环境
教程目录 1.1 CoolBlog开发笔记第1课:项目分析 前言 今天是CoolBlog开发笔记的第2课,我们将要讲解的是开发环境的搭建.俗话说"工欲善其事必先利其器",Djang ...
-
Bytom Dapp 开发笔记(二):开发流程
简介 这章的内容详细分析一下涉及智能合约Dapp的整个开发流程,注意是涉及只能合约,如果你只要一些基本转BTM功能没有太大意义,本内容补充一下官方提供的 比原链DAPP开发流程,详细实践过好踩到的一些 ...
-
Modbus库开发笔记:Modbus ASCII Slave开发
与Modbus RTU在串行链路上分为Slave和Master一样,Modbus ASCII也分为Slave和Master,这一节我们就来开发Slave.对于Modbus ASCII从站来说,需要实现 ...
-
Neo4j图数据库管理系统开发笔记之三:构建安全的RMI Service(Server)
RMI Server(服务端)主要包括以下功能:远程用户权限验证管理.远程服务接口实现类.Neo4j实体映射转换等.项目目录结构如下图所示: 3.2.1 远程用户权限验证管理 3.2.1.1 用户权限 ...
-
Kinect开发笔记之三Kinect开发环境配置具体解释
0.前言: 首先说一下我的开发环境,Visual Studio是2013的,系统是win8的64位版本号,SDK是Kinect for windows SDK 1.8版本 ...
-
学习笔记之三十年软件开发之路 - Things I Learnt The Hard Way (in 30 Years of Software Development)
三十年软件开发之路 https://mp.weixin.qq.com/s/EgN-9bIHonRid1DM0csQDw https://blog.juliobiason.net/thoughts/th ...
-
MQTT开发笔记之《MQTT Server》
MQTT SERVER 性能测试报告 : http://w3yyb.sinaapp.com/archives/1601各个MQTT SERVER功能列表: http://blog.lenix.xyz/ ...
-
LwIP应用开发笔记之三:LwIP无操作系统UDP客户端
前一节我们实现了基于RAW API的UDP服务器,在接下来,我们进一步利用RAW API实现UDP客户端. 1.UDP协议简述 UDP协议全称是用户数据报协议,在网络中它与TCP协议一样用于处理数据包 ...
随机推荐
-
js快捷输入日期
点击这里查看效果http://keleyi.com/keleyi/phtml/jstexiao/10.htm 以下式代码: <!DOCTYPE html> <html> < ...
-
LVS集群之DR模式 实现
ps:做 dr 模式 之前,先把之前做过的操作清空掉 1.ipvsadm -ln 查看规则 2.ipvsadm -C 清空规则 3.ipvsadm -ln 确认 4.iptables -t nat - ...
-
【Pig源码分析】谈谈Pig的数据模型
1. 数据模型 Schema Pig Latin表达式操作的是relation,FILTER.FOREACH.GROUP.SPLIT等关系操作符所操作的relation就是bag,bag为tuple的 ...
-
java模拟OSUnMapTbl[]
问题描述: 任务就绪表,记录当前就绪的任务,就绪表中把64个优先级的任务分成8组,优先级的1-3bit表示OSRdyTbl[]中组别OSRedyGrp,优先级的4-6bit表示每组中就绪任务的位置,当 ...
-
包含为 HTTP 定义的状态代码的值(枚举)
using System; namespace System.Net { // 摘要: // 包含为 HTTP 定义的状态代码的值. public enum HttpStatusCode { // 摘 ...
-
JDk 内部分工具 简述
jar — 一个创建和管理 jar 文件的工具. java — Java 应用启动器.在这篇文章里,开发和部署都是用的这个启动器. javac — Java 编译器. javadoc — API 文档 ...
-
maven下载jta失败,自己本地安装jta库
mvn install:install-file -Dfile=./jta-1_0_1B-classes.zip -DgroupId=javax.transaction -DartifactId=jt ...
-
VC中关于 0xcccccccc和 0xcdcdcdcd异常
VC在调试时,可能会报“写入位置0xcccccccc 时发生访问冲突”,或者“写入位置0xcdcdcdcd 时发生访问冲突”,这些问题可能是由于使用了未初始化的指针引起的. 在 Debug 模式下,V ...
-
python学习之while循环
Python While 循环语句 Python 编程中 while 语句用于循环执行程序,即在某条件下,循环执行某段程序,以处理需要重复处理的相同任务.其基本形式为: while 判断条件: 执行语 ...
-
全面理解SSD和NAND Flash
Flash Memory又叫做闪存,是一种非易失性存储器.非易失性是指断电之后数据不会丢失,这里就涉及到断电保护(后面详细讲解). 总体思路 1.NAND Flash的用途. 2.NAND Flash ...