异形Modbus客户端 和 异形modbus服务器之间的通讯 侦听模式的modbus-tcp客户端通讯
前言
本文将使用一个Github公开的组件技术来实现一个异形ModBus TCP的客户端,方便的对异形Modbus tcp的服务器进行读写,这个服务器可以是电脑端C#设计的,也可以是特殊设备实现的,也可以是其他任何支持这个通信协议的服务器。
github地址:https://github.com/dathlin/HslCommunication 如果喜欢可以star或是fork,还可以打赏支持。
本文下面的DEMO的项目的源代码都在这个地址里面
联系作者及加群方式(激活码在群里发放):http://www.hslcommunication.cn/Cooperation
在Visual Studio 中的NuGet管理器中可以下载安装,也可以直接在NuGet控制台输入下面的指令安装
Install-Package HslCommunication
NuGet安装教程 http://www.cnblogs.com/dathlin/p/7705014.html
组件API地址:http://www.cnblogs.com/dathlin/p/7703805.html
关于异形模式,也叫侦听式客户端
通常的模式都是服务器客户端模式,由客户端发起连接,然后和服务器进行数据交换实现的,但是实际中还有一种模式就是,由服务器主动发起对客户端的连接,然后客户端再执行对服务器的数据交互,听着可能会有些别扭,但是确实存在的,通常应用于一些,工业现场的4G上网的设备。当然也可以实现自定义的一些功能操作。需要慢慢的看下面的代码。
异形模式主要分两部分组成,侦听服务器,异形modbus-tcp客户端。
侦听服务器负责,侦听网络请求和Alien协议验证,通过之后将连接抛给异形modbus-tcp客户端使用。
注册包及Alien协议
在modbus服务器连上云服务器的ip及端口地址后,需要发送一条注册包信息,这条注册包信息需要遵循如下的协议,称为Alien协议,其他的协议支持需要二次定制开发完成。本协议详细如下:
注册包共28个字节,
// 注册包
0x48 0x73 0x6E 0x00 0x17 0x31 0x32 0x33 0x34 0x35 0x36 0x37 0x38 0x39 0x30 0x31 0x00 0x00 0x00 0x00 0x00 0x00 0xC0 0xA8 0x00 0x01 0x17 0x10
+------------------+ +----+ +-----+ +-----------------------------------------------------------------------------+ +----------------------------------------+ +---------------------------+ +-------------+
+ 固定消息头 + 备用 后面长度 DTU码 12345678901 (唯一标识,比如手机号) 登录密码(不受信的排除) Ip:192.168.0.1 端口10000
+------------------+ +----+ +-----+ +----------------------------------------------------------------------------+ +-----------------------------------------+ +-------------------------+ +--------------+
// 返回消息,下面是正常的注册成功的信息
0x48 0x73 0x6E 0x00 0x01 0x00
+----------------- + +----+ +----+ +----+
固定消息头 备用 后面长度 结果代码
// 结果代码
0x00: 登录成功
0x01: DTU重复登录
0x02: DTU禁止登录
0x03: 密码验证失败
侦听请求
第一步需要先建立侦听服务器,触发的事件为什么会有两个参数是因为当你有多个服务器的时候,就可以共同关联一个方法,然后通过network来区分信号,核心代码如下所示,到时候只要调用 NetworkAlienStart 方法即可
private NetworkAlienClient networkAlien = null; private void NetworkAlienStart( int port )
{
networkAlien = new NetworkAlienClient( );
networkAlien.OnClientConnected += NetworkAlien_OnClientConnected;
networkAlien.LogNet = logNet;
networkAlien.ServerStart( port );
} private void NetworkAlien_OnClientConnected( NetworkAlienClient network , AlienSession session )
{
// 当有连接的时候会触发这个方法
}
异形Modbus-Tcp
建立一个异形客户端,数据交互块和,原来的客户端几乎是一模一样的,仅仅是连接原理不一样,设置成异形客户端之后,就不在负责连接的功能了,变成了被动设置连接对象的功能。代码也是很方便的
1. 先定义对象
private ModbusTcpNet busTcpClient = null;
2. 实例化,IP和端口随便指定,反正对于异形客户端是没有用途的,但是站号还是有用的
busTcpClient = new ModbusTcpNet( textBox1.Text, port, station );
3. 设置为异形模式,当然先不设置也可以,可以调到第四步再进行设置
busTcpClient.ConnectServer( null );
4. 修改请求侦听的回调方法
private void NetworkAlien_OnClientConnected( NetworkAlienClient network, AlienSession session )
{
busTcpClient.ConnectServer( session );
}
当有modbus服务器连接上来的时候,就触发该方法,就可以通过busTcpClient对服务器进行数据读写了。上面演示的情况仅仅是一个客户端的情况,如果有多个客户端呢?我们可以通过唯一的识别码来相互关联,对于每个传进来的session数据,还包含了连接请求的DTU唯一码,我们就可以进行判定了。
我们先设置异形客户端的唯一码
busTcpClient.ConnectionId = "12345678901"
再修改回调方法
private void NetworkAlien_OnClientConnected( NetworkAlienClient network , AlienSession session )
{
if(session.DTU == busTcpClient.ConnectionId)
{
busTcpClient.ConnectServer( session );
}
}
通常的方法都是先定义好自己的客户端数组,并指定DTU码,然后批量的对数组进行数据请求操作。
具体的数据请求操作,请参照正常的Modbus-TCP博客,
http://www.cnblogs.com/dathlin/p/7885368.html
下面随便贴一点示例代码
private void userButton30_Click(object sender, EventArgs e) { // 读取操作 bool coil100 = busTcpClient.ReadCoil("100").Content; // 读取线圈100的通断 short short100 = busTcpClient.ReadInt16("100").Content; // 读取寄存器100的short值 ushort ushort100 = busTcpClient.ReadUInt16("100").Content; // 读取寄存器100的ushort值 int int100 = busTcpClient.ReadInt32("100").Content; // 读取寄存器100-101的int值 uint uint100 = busTcpClient.ReadUInt32("100").Content; // 读取寄存器100-101的uint值 float float100 = busTcpClient.ReadFloat("100").Content; // 读取寄存器100-101的float值 long long100 = busTcpClient.ReadInt64("100").Content; // 读取寄存器100-103的long值 ulong ulong100 = busTcpClient.ReadUInt64("100").Content; // 读取寄存器100-103的ulong值 double double100 = busTcpClient.ReadDouble("100").Content; // 读取寄存器100-103的double值 string str100 = busTcpClient.ReadString("100", 5).Content;// 读取100到104共10个字符的字符串 // 写入操作 busTcpClient.WriteCoil("100", true);// 写入线圈100为通 busTcpClient.Write("100", (short)12345);// 写入寄存器100为12345 busTcpClient.Write("100", (ushort)45678);// 写入寄存器100为45678 busTcpClient.Write("100", 123456789);// 写入寄存器100-101为123456789 busTcpClient.Write("100", (uint)123456778);// 写入寄存器100-101为123456778 busTcpClient.Write("100", 123.456);// 写入寄存器100-101为123.456 busTcpClient.Write("100", 12312312312414L);//写入寄存器100-103为一个大数据 busTcpClient.Write("100", 12634534534543656UL);// 写入寄存器100-103为一个大数据 busTcpClient.Write("100", 123.456d);// 写入寄存器100-103为一个双精度的数据 busTcpClient.Write("100", "K123456789"); }
测试的Demo
如果感兴趣,可以下载Demo测试,下载2个软件,一个是服务器软件,一个是客户端软件
先打开服务器,并启动服务
再打开异形客户端
设置好相关的参数后,启动服务器,默认的参数如下,启动成功的话,会弹出消息框【等待服务器的连接】
然后我们再回到服务器界面,点击 连接异形客户端 按钮,弹出如下:然后将IP地址修改成本机的,端口改成刚刚在客户端填写的,ID和客户端的一致
然后服务器界面弹框,连接成功。然后我们就可以回到客户端界面进行数据读写的交互了。
异形Modbus客户端 和 异形modbus服务器之间的通讯 侦听模式的modbus-tcp客户端通讯的更多相关文章
- 初识Modbus TCP/IP-------------C#编写Modbus TCP客户端程序(一)
转自:http://blog.csdn.net/thebestleo/article/details/52269999 首先我要说明一下,本人新手一枚,本文仅为同样热爱学习的同学提供参考,有不 对的地 ...
- 初识Modbus TCP/IP-------------C#编写Modbus TCP客户端程序(二)
由于感觉上一次写的篇幅过长,所以新开一贴,继续介绍Modbus TCP/IP的初步认识, 书接上回 3).03(0x03)功能码--------读保持寄存器 请求与响应格式 这是一个请求读寄存器108 ...
- Android 客户端 okhttp3 与服务器之间的双向验证
[原文]https://blog.csdn.net/leng_wen_rou/article/details/58596142 本篇是Android 客户端基于okhttp3的网络框架 和后台服务器之 ...
- Java开发之使用websocket实现web客户端与服务器之间的实时通讯
使用websocket实现web客户端与服务器之间的实时通讯.以下是个简单的demo. 前端页面 <%@ page language="java" contentType=& ...
- unity客户端与c++服务器之间的简单通讯_1
// 服务器 # pragma once using namespace std; # include <iostream> # include <string> # incl ...
- 多Web服务器之间共享Session的解决方案
一.提出问题: 为了满足足够大的应用,满足更多的客户,于是我们架设了N台Web服务器(N>=2),在多台Web服务器的情况下,我们会涉及到一个问题:用户登陆一台服务器以后,如果在跨越到另一台服务 ...
- C/S架构程序多种类服务器之间实现单点登录(转)
(一) 在项目开发的过程中,经常会出现这样的情况:我们的产品包括很多,以QQ举例,如登陆.好友下载.群下载.网络硬盘.QQ游戏.QQ音乐等,总不能要求用户每次输入用户名.密码吧,为解决这个问题,高手提 ...
- PHP、Java、C#实现URI参数签名算法,确保应用与REST服务器之间的安全通信,防止Secret Key盗用、数据篡改等恶意攻击行为
简介 应用基于HTTP POST或HTTP GET请求发送Open API调用请求时,为了确保应用与REST服务器之间的安全通信,防止Secret Key盗用.数据篡改等恶意攻击行为,REST服务器使 ...
- 多台web服务器之间共享session
常见的几种方法如下: 1. 写客户端Cookie的方式 当用户登陆成功以后,把网站域名.用户名.密码.token.session有效时间全部采用cookie的形式写入到客户端的cookie里面,如果用 ...
随机推荐
- LeetCode (236):Lowest Common Ancestor of a Binary Search Tree
Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in the BS ...
- php实现dota天梯、wow竞技场、lol排位赛匹配加分算法ELO
public function marchOpponents() { $rstep = Yii::$app->params['ratingStep'];//(随机范围) $rsN=100; $d ...
- 2705: [SDOI2012]Longge的问题
Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 1898 Solved: 1191[Submit][Status][Discuss] Descripti ...
- 爬虫之动态HTML处理(Selenium与PhantomJS )动态页面模拟点击
动态页面模拟点击 #!/usr/bin/env python # -*- coding:utf-8 -*- # python的测试模块 import unittest from selenium im ...
- C5 标准IO库:APUE 笔记
C5 :标准IO库 在第三章中,所有IO函数都是围绕文件描述符展开,文件描述符用于后续IO操作.由于文件描述符相关的操作是不带缓冲的IO,需要操作者本人指定缓冲区分配.IO长度等,对设备环境要求一定的 ...
- GDB操作基本命令
GDB操作基本命令 1 打开文件及退出操作 shell下输入 gdb filename : 打开单个文件 gdb filename -q: 打开单个文件,屏蔽掉GDB自带的说明信息 gdb下输入qui ...
- 动态延迟加载网页元素jQuery插件scrollLoading
如果一个网页很长,那么该页面的加载时间也会相应的较长.而这里给大家介绍的这个jQuery插件scrollLoading的作用则是,对页面元素进行动态加载,通俗的说就是滚到哪就加载到哪,屏幕以下看不见的 ...
- Android ---------高德卫星地图绘制多个点和点的点击事件自定义弹窗
最近开发中,遇到一个多个点绘制,并实现点击事件,出现自定义窗口显示相关信息等功能,所以写了这篇博客. 从后台请求数据,得到多个经纬度,然后绘制在地图上,并实现点击,出现相关信息(自定义弹框实现) 先来 ...
- MySQL设置某一字段默认为0,但是插入数据化却显示为null
1.MySQL字段默认的含义:在插入时不指定该字段的值:2.以mybatis举例,如果是插入实体,那么为空的字段就会插入空:3.如果不想mybatis等持久化工具插入空,可以尝试insertSelec ...
- iOS JavaScriptCore使用
iOS JavaScriptCore使用 JavaScriptCore是iOS7引入的新功能,JavaScriptCore可以理解为一个浏览器的运行内核,使用JavaScriptCore可以使用nat ...