本文将使用一个gitHub开源的组件技术来实现S7服务器的功能,使用的是基于以太网的TCP/IP实现,不需要额外的组件

github地址:https://github.com/dathlin/HslCommunication                             如果喜欢可以star或是fork,还可以打赏支持。

官网地址:http://www.hslcommunication.cn/

联系作者及加群方式:http://www.hslcommunication.cn/Cooperation


演示的demo,快速开发,下载demo程序,您可以进行初步的访问的测试,免去了您写测试程序的麻烦,快速实验通讯,测试开发软件的操作。

下载地址为:HslCommunicationDemo.zip

演示的服务器截图为:

再配合本组件支持的客户端通讯、就可以实现自我测试。

两者的地址格式是一致的。

服务器端支持4种地址:输入的I0,输出的Q0,中间寄存器M100,DB块,DB1.100

自定义服务器开发


实际的场景中,很有可能你需要的是一个可以测试的demo,当你在开发上位机,SCADA软件,监控软件,历史追述软件的时候,还没有PLC来给你测试,开发,这时候就可以使用本demo来实现模拟服务器的功能。

当然还有另一种需求,当你要集成一个服务器到你自己的程序中的时候,就可以使用本组件来实现,而要集成一个自定义的服务器将会是非常的简单。

1. 安装组件,可以通过下面的指令,或是nuget可视化的客户端来安装

Install-Package HslCommunication

2. 引用命名空间:

using HslCommunication.Profinet.Siemens;
using HslCommunication;

3. 写代码。这个服务器可以是在你的窗体中,当然也可以在你的自定义类中,下面的举例在类中定义(窗体的本质也是类)

        private SiemensS7Server s7NetServer;
public void S7Start()
{
try
{
s7NetServer = new SiemensS7Server();
s7NetServer.ServerStart(102);
}
catch(Exception ex)
{
Console.Write("Failed:" + HslCommunication.BasicFramework.SoftBasic.GetExceptionMessage(ex));
}
}

这样就启动了一个最基本的西门子虚拟服务器了。然后就可以用Hsl组件去读写数据了。端口号是102。

4. 服务器操作数据信息,有了上述的例子后,我们来扩充服务器的功能,比如在服务器端进行读写数据信息。如下的代码举例的一般类型的读写操作说明。

            // 此处以M100寄存器作为示例
bool bool_M100_0 = s7NetServer.ReadBool("M100.0").Content;
byte byte_M100 = s7NetServer.ReadByte("M100").Content; // 读取M100的值
short short_M100 = s7NetServer.ReadInt16("M100").Content; // 读取M100-M101组成的字
ushort ushort_M100 = s7NetServer.ReadUInt16("M100").Content; // 读取M100-M101组成的无符号的值
int int_M100 = s7NetServer.ReadInt32("M100").Content; // 读取M100-M103组成的有符号的数据
uint uint_M100 = s7NetServer.ReadUInt32("M100").Content; // 读取M100-M103组成的无符号的值
float float_M100 = s7NetServer.ReadFloat("M100").Content; // 读取M100-M103组成的单精度值
long long_M100 = s7NetServer.ReadInt64("M100").Content; // 读取M100-M107组成的大数据值
ulong ulong_M100 = s7NetServer.ReadUInt64("M100").Content; // 读取M100-M107组成的无符号大数据
double double_M100 = s7NetServer.ReadDouble("M100").Content; // 读取M100-M107组成的双精度值
string string_M100 = s7NetServer.ReadString("M100", 10).Content; // 读取M100-M109组成的ASCII字符串数据 // 读取数组
short[] short_M100_array = s7NetServer.ReadInt16("M100", 10).Content; // 读取M100-M101组成的字
ushort[] ushort_M100_array = s7NetServer.ReadUInt16("M100", 10).Content; // 读取M100-M101组成的无符号的值
int[] int_M100_array = s7NetServer.ReadInt32("M100", 10).Content; // 读取M100-M103组成的有符号的数据
uint[] uint_M100_array = s7NetServer.ReadUInt32("M100", 10).Content; // 读取M100-M103组成的无符号的值
float[] float_M100_array = s7NetServer.ReadFloat("M100", 10).Content; // 读取M100-M103组成的单精度值
long[] long_M100_array = s7NetServer.ReadInt64("M100", 10).Content; // 读取M100-M107组成的大数据值
ulong[] ulong_M100_array = s7NetServer.ReadUInt64("M100", 10).Content; // 读取M100-M107组成的无符号大数据
double[] double_M100_array = s7NetServer.ReadDouble("M100", 10).Content; // 读取M100-M107组成的双精度值

基本的写入操作

            // 此处以M100寄存器作为示例
s7NetServer.Write("M100", true); // 写入M100 bool值
s7NetServer.Write("M100", (byte)123); // 写入M100 byte值
s7NetServer.Write("M100", (short)1234); // 写入M100 short值
s7NetServer.Write("M100", (ushort)45678); // 写入M100 ushort值
s7NetServer.Write("M100", 1234566); // 写入M100 int值
s7NetServer.Write("M100", (uint)1234566); // 写入M100 uint值
s7NetServer.Write("M100", 123.456f); // 写入M100 float值
s7NetServer.Write("M100", 123.456d); // 写入M100 double值
s7NetServer.Write("M100", 123456661235123534L); // 写入M100 long值
s7NetServer.Write("M100", 523456661235123534UL); // 写入M100 ulong值
s7NetServer.Write("M100", "K123456789"); // 写入M100 string值 // 读取数组
s7NetServer.Write("M100", new short[] { 123, 3566, -123 }); // 写入M100 short值 ,W3C0,R3C0 效果是一样的
s7NetServer.Write("M100", new ushort[] { 12242, 42321, 12323 }); // 写入M100 ushort值
s7NetServer.Write("M100", new int[] { 1234312312, 12312312, -1237213 }); // 写入M100 int值
s7NetServer.Write("M100", new uint[] { 523123212, 213, 13123 }); // 写入M100 uint值
s7NetServer.Write("M100", new float[] { 123.456f, 35.3f, -675.2f }); // 写入M100 float值
s7NetServer.Write("M100", new double[] { 12343.542312d, 213123.123d, -231232.53432d }); // 写入M100 double值
s7NetServer.Write("M100", new long[] { 1231231242312, 34312312323214, -1283862312631823 }); // 写入M100 long值
s7NetServer.Write("M100", new ulong[] { 1231231242312, 34312312323214, 9731283862312631823 }); // 写入M100 ulong值

5. 高级读写,所谓的高级的读写,就是读写基础的字节数据,相关的转换需要自己来完成

读数据的例子如下:

            OperateResult<byte[]> read = s7NetServer.Read("M100", 8);
if (read.IsSuccess)
{
float temp = s7NetServer.ByteTransform.TransInt16(read.Content, 0) / 10f;
float press = s7NetServer.ByteTransform.TransInt16(read.Content, 2) / 100f;
int count = s7NetServer.ByteTransform.TransInt32(read.Content, 2); // do something
}
else
{
// failed
}

写数据的例子:

            // 拼凑数据,这样的话,一次通讯就完成数据的全部写入
byte[] buffer = new byte[8];
s7NetServer.ByteTransform.TransByte((short)1234).CopyTo(buffer, 0);
s7NetServer.ByteTransform.TransByte((short)2100).CopyTo(buffer, 2);
s7NetServer.ByteTransform.TransByte(12353423).CopyTo(buffer, 4); OperateResult write = s7NetServer.Write("M100", buffer);
if (write.IsSuccess)
{
// success
}
else
{
// failed
} // 上面的功能等同于三个数据分别写入,下面的方式性能稍微差一点点,几乎看不出来
// s7NetServer.Write( "M100", (short)1234 );
// s7NetServer.Write( "M100", (short)2100 );
// s7NetServer.Write( "M100", 12353423 );

6. 服务器的高级操作,日志配置

        public void S7Start2()
{
try
{
s7NetServer = new SiemensS7Server();
s7NetServer.LogNet = new HslCommunication.LogNet.LogNetSingle("logs.txt"); // 配置日志信息
s7NetServer.ServerStart(102);
}
catch (Exception ex)
{
Console.Write("Failed:" + HslCommunication.BasicFramework.SoftBasic.GetExceptionMessage(ex));
}
}

7. 限制客户端的ip地址,下面举例是仅仅允许本机登录。

        public void S7Start3()
{
try
{
s7NetServer = new SiemensS7Server();
s7NetServer.LogNet = new HslCommunication.LogNet.LogNetSingle("logs.txt"); // 配置日志信息
s7NetServer.SetTrustedIpAddress(new List<string>() { "127.0.0.1" }); // 仅仅限制本机客户端读写
s7NetServer.ServerStart(102);
}
catch (Exception ex)
{
Console.Write("Failed:" + HslCommunication.BasicFramework.SoftBasic.GetExceptionMessage(ex));
}
}

8. 捕捉数据接收事件,每当客户端进行数据交互的时候,都可以触发事件,然后可以对报文进行分析,比如说,分析出了客户端写入了地址M100的数据,就触发下自定义的操作,在这种情况下就可以使用如下的代码

        public void S7Start4()
{
try
{
s7NetServer = new SiemensS7Server();
s7NetServer.LogNet = new HslCommunication.LogNet.LogNetSingle("logs.txt"); // 配置日志信息
s7NetServer.SetTrustedIpAddress(new List<string>() { "127.0.0.1" }); // 仅仅限制本机客户端读写
s7NetServer.OnDataReceived += S7NetServer_OnDataReceived;
s7NetServer.ServerStart(102);
}
catch (Exception ex)
{
Console.Write("Failed:" + HslCommunication.BasicFramework.SoftBasic.GetExceptionMessage(ex));
}
} private void S7NetServer_OnDataReceived(object sender, byte[] data)
{
Console.WriteLine(HslCommunication.BasicFramework.SoftBasic.ByteToHexString(data, ' ')); // 打印客户端发送的数据
}

9. 示例,举个简单的例子,用来模拟PLC的程序,整个PLC的程序无非是对输入输出进行代码操作,PLC的优势就是实时性,所以我们可以基于本组件开发一个虚拟化的PLC,可用于简单的模拟,调试,测试操作。

C# 构建S7服务器 西门子的虚拟服务器 测试通讯 HslCommunication应用的更多相关文章

  1. [Linux] LVS虚拟服务器四层负载均衡

    随着互联网的爆炸性增长及其在我们生活中日益重要的作用,互联网上的流量急剧增加,并且每年以超过100%的速度增长.服务器上的工作负载正在迅速增加,因此服务器很容易在短时间内过载,尤其是对于流行的网站.为 ...

  2. LVS (Linux虚拟服务器)-不同的负载均衡方法

    随着Internet用户的增长,基于Web的公司处理的通信量急剧增加.有各种解决方案来应对这种不断增长的流量. 一种解决方案是垂直扩展服务器(即:简单地向服务器添加更多的CPU和内存资源.)当然在一定 ...

  3. Go 语言开发的基于 Linux 虚拟服务器的负载平衡平台 Seesaw

    负载均衡系统 Seesaw Seesaw是由我们网络可靠性工程师用 Go 语言开发的基于 Linux 虚拟服务器的负载平衡平台,就像所有好的项目一样,这个项目也是为了解决实际问题而产生的. Seesa ...

  4. macOS apache配置及开启虚拟服务器的开启,apache开启重写模式

    今天把自己的mac系统升到最新版,但是,apache却不能用了,因为mac上的apache是系统自带的,因为是mac目前的最新系统,所以出现了好多问题,整理了一下午也没有啥进展,最后还是把原来的在云盘 ...

  5. Nginx的虚拟服务器域名配置

    虚拟服务器名(server name)是通过指令server_name来指定的.在< Nginx是如何处理Request的?>一节中,我们讲到nginx分两步来匹配过来的Request请求 ...

  6. Linux虚拟服务器--LVS

    LVS 百科名片 LVS是一个开源的软件,由毕业于国防科技大学的章文嵩博士于1998年5月创立,可以实现LINUX平台下的简单负载均衡.LVS是Linux Virtual Server的缩写,意思是L ...

  7. vps 虚拟服务器 教程 ( Virtual Private Server 虚拟专用服务器 )

    VPS是虚拟服务器的意思.他是通过软件在独立服务器上划分出来的一部分资源.从而虚拟出一个服务器.他拥有独立的IP.独立的操作系统.以及用户名和密码.在功能和使用方法上与服务器一模一样.用户也可以根据自 ...

  8. 电信光猫带路由器(F452)的虚拟服务器端口映射

    现在电信宽带的光猫一般都自带路由器功能,为了方便运营商管理网络用户,电信公司插入了企业局域网,网络用户的光猫路由器都是这个局域网的节点.用户家里的电脑在网络中的结构位置一般如下所示: 互联网(公网)= ...

  9. 前端笔记之Vue(四)UI组件库&Vuex&虚拟服务器初识

    一.日历组件 new Date()的月份是从0开始的. 下面表达式是:2018年6月1日 new Date(2018, 5, 1); 下面表达式是:2018年5月1日 new Date(2018, 4 ...

随机推荐

  1. Myeclipse中xml文件里自动提示消失解决办法

    IED Eclipse Java EE IDE for Web Developers:DTD 类型约束文件    1. Window->Preferences->XML->XML C ...

  2. gcc 编译出现 internal compiler error: Killed

    系统没有交换分区, 编译过程中内存耗尽, 导致了编译中断 …解决方式也很简单, 就是增加一个交换分区:       创建分区文件, 大小 2G dd if=/dev/zero of=/swapfile ...

  3. Springboot 学习笔记 之 Day 2

    “约定大于配置”这样一句话,就是说系统,类库,框架应该假定合理的默认值,而非要求提供不必要的配置,可是使用Spring或者SpringMVC的话依然有许多这样的东西需要我们进行配置,这样不仅徒增工作量 ...

  4. 云服务器ECS挖矿木马病毒处理和解决方案

    云服务器ECS挖矿木马病毒处理和解决方案 最近由于网络环境安全意识低的原因,导致一些云服务器ECS中了挖矿病毒的坑. 总结了一些解决挖矿病毒的一些思路.由于病毒更新速度快仅供参考. 1.查看cpu爆满 ...

  5. 各种容器与服务器的区别与联系 Servlet容器 WEB容器 Java EE容器 应用服务器 WEB服务器 Java EE服务器

    转自:https://blog.csdn.net/tjiyu/article/details/53148174 各种容器与服务器的区别与联系 Servlet容器 WEB容器 Java EE容器 应用服 ...

  6. 雷林鹏分享:C# 委托(Delegate)

    C# 委托(Delegate) C# 中的委托(Delegate)类似于 C 或 C++ 中函数的指针.委托(Delegate) 是存有对某个方法的引用的一种引用类型变量.引用可在运行时被改变. 委托 ...

  7. 敏感性、特异性、假阳性、假阴性(sensitivity and specificity)

    医学.机器学习等等,在统计结果时时长会用到这两个指标来说明数据的特性. 定义 敏感性:在金标准判断有病(阳性)人群中,检测出阳性的几率.真阳性.(检测出确实有病的能力) 特异性:在金标准判断无病(阴性 ...

  8. GetTextAndImageCreateExamPaper

    Private Declare Function URLDownloadToFile Lib "urlmon" Alias "URLDownloadToFileA&quo ...

  9. android--------根据文件路径使用File类获取文件相关信息

    Android通过文件路径如何得到文件相关信息,如 文件名称,文件大小,创建时间,文件的相对路径,文件的绝对路径等. 如图: public class MainActivity extends Act ...

  10. 51nod1344

    有编号1-n的n个格子,机器人从1号格子顺序向后走,一直走到n号格子,并需要从n号格子走出去.机器人有一个初始能量,每个格子对应一个整数A[i],表示这个格子的能量值.如果A[i] > 0,机器 ...