.NET6实现对西门子1500PLC的开放式TCP/IP数据读取与写入

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>WinExeOutputType>
    <TargetFramework>net6.0-windowsTargetFramework>
    <Nullable>enableNullable>
    <UseWindowsForms>trueUseWindowsForms>
    <ImplicitUsings>enableImplicitUsings>
  PropertyGroup>

	<ItemGroup>
		<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.3" />
		<PackageReference Include="Microsoft.EntityFrameworkCore.Abstractions" Version="6.0.3" />
		<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.3">
		  <PrivateAssets>allPrivateAssets>
		  <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitiveIncludeAssets>
		PackageReference>
		<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="6.0.3" />
		<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="6.0.3" />
		<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.3">
			<PrivateAssets>allPrivateAssets>
			<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitiveIncludeAssets>
		PackageReference>
		<PackageReference Include="Microsoft.Extensions.Configuration" Version="6.0.1" />
		<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="6.0.0" />
		<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="6.0.0" />
		<PackageReference Include="Microsoft.Extensions.Options" Version="6.0.0" />
		<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
		<PackageReference Include="NModbus4.NetCore" Version="2.0.1" />
		<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="6.0.1" />
	ItemGroup>

	<ItemGroup>
	  <Folder Include="DataConvertLib\" />
	  <Folder Include="Service\" />
	ItemGroup>

	<ItemGroup>
	  <None Include="..\.editorconfig" Link=".editorconfig" />
	ItemGroup>

	<ItemGroup>
	  <None Update="VariableNode.json">
	    <CopyToOutputDirectory>PreserveNewestCopyToOutputDirectory>
	  None>
	ItemGroup>
Project>

先建立json文件点表:

{
  "ConnectionStrings": {
    "SqliteConnectionString": "Data Source=D:\\Csharp\\code\\STM32Demon\\STM32Demon\\bin\\Debug\\net6.0-windows\\Database\\DbSqlite.db",
    "MySQLConnectionString": "server=127.0.0.1; database=OneToMany; uid=root; pwd=123456;"
  },
  "ServerURL": "192.168.1.100",
  "Port": "2000",
  "VarNum": "6",
  "ByteLenth": "100",
  "Variable": [
    {
      "Id": 1,
      "Number": "1",
      "Name": "Float1",
      "Description": "40001-40002",
      "Type": "TCP",
      "VarAddress": 0,
      "Scale": "1",
      "Offset": "0",
      "Start": "0",
      "AccessProperty": "读写",
      "VarType": "Float",
      "InsertTime": "0",
      "Value": "0"
    },
    {
      "Id": 2,
      "Number": "2",
      "Name": "Float2",
      "Description": "40001-40002",
      "Type": "TCP",
      "VarAddress": 2,
      "Scale": "1",
      "Offset": "0",
      "Start": "0",
      "AccessProperty": "读写",
      "VarType": "Float",
      "InsertTime": "0",
      "Value": "0"
    },
    {
      "Id": 3,
      "Number": "3",
      "Name": "Float3",
      "Description": "40005-40006",
      "Type": "TCP",
      "VarAddress": 4,
      "Scale": "1",
      "Offset": "0",
      "Start": "0",
      "AccessProperty": "读写",
      "VarType": "Float",
      "InsertTime": "0",
      "Value": "0"
    },
    {
      "Id": 4,
      "Number": "4",
      "Name": "Float4",
      "Description": "40007-40008",
      "Type": "TCP",
      "VarAddress": 6,
      "Scale": "1",
      "Offset": "0",
      "Start": "0",
      "AccessProperty": "读写",
      "VarType": "Float",
      "InsertTime": "0",
      "Value": "0"
    },
    {
      "Id": 5,
      "Number": "5",
      "Name": "UShort1",
      "Description": "40008",
      "Type": "TCP",
      "VarAddress": 8,
      "Scale": "1",
      "Offset": "0",
      "Start": "0",
      "AccessProperty": "读写",
      "VarType": "UShort",
      "InsertTime": "0",
      "Value": "0"
    },
    {
      "Id": 6,
      "Number": "6",
      "Name": "UShort2",
      "Description": "40009",
      "Type": "TCP",
      "VarAddress": 9,
      "Scale": "1",
      "Offset": "0",
      "Start": "0",
      "AccessProperty": "读写",
      "VarType": "UShort",
      "InsertTime": "0",
      "Value": "0"
    }
  ]
}

客户端主程序:

using EF6Demon.DAL;
using Microsoft.Extensions.Configuration;
using STM32Demon.Models;
using System.Net;
using System.Net.Sockets;
using thinger.DataConvertLib;
using DataType = thinger.DataConvertLib.DataType;

namespace STM32Demon
{
    public partial class FrmMain1 : Form
    {
        public FrmMain1()
        {
            InitializeComponent();
            this.Load += FrmMain1_Load;
        }

        //private ModelsResponsitory dbContext = new ModelsResponsitory();
        private ConfigurationBuilder cfgBuilder = new ConfigurationBuilder();
        private IConfigurationRoot configRoot;
        private CancellationTokenSource cts = new CancellationTokenSource();
        private byte[] setArray;
        private Socket tcpClient;
        private FrmServer frmServer;

        private void FrmMain1_Load(object? sender, EventArgs e)
        {
            cfgBuilder.AddJsonFile("VariableNode.json", optional: true, reloadOnChange: true);
            this.configRoot = cfgBuilder.Build();
            CommonMethods.Ip = configRoot.GetSection("ServerURL").Value;
            CommonMethods.Port = configRoot.GetSection("Port").Value;
            CommonMethods.VarNum = configRoot.GetSection("VarNum").Value;
            CommonMethods.ByteLenth = int.Parse(configRoot.GetSection("ByteLenth").Value);
            CommonMethods.AllVarList = new List<Variable>();
            for (int i = 0; i < int.Parse(CommonMethods.VarNum); i++)
            {
                Variable variable = configRoot.GetSection($"Variable:{i}").Get<Variable>();
                CommonMethods.AllVarList.Add(variable);
            }
            foreach (var item in CommonMethods.AllVarList)
            {
                this.comboBox1.Invoke(() =>
                {
                    this.comboBox1.Items.Add(item.Name);
                });
                CommonMethods.CurrentPLCValue.Add(item.Name, item.Value);
                CommonMethods.CurrentPLCNote.Add(item.Name, item.VarType);

            }
        }

        private void btnConn_Click(object sender, EventArgs e)
        {
            tcpClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            tcpClient.Connect(IPAddress.Parse(CommonMethods.Ip), int.Parse(CommonMethods.Port));
            CommonMethods.IsConnected = tcpClient.Connected;
            CommonMethods.FirstConnect = false;
            Addinfo(CommonMethods.IsConnected ? "连接成功" : "连接失败");
        }


        private void Addinfo(string info)
        {
            this.isInfo.Items.Insert(
                0, DateTime.Now.ToString("HH:mm:ss") + " " + info + Environment.NewLine);
        }

        private void btnRead_Click(object sender, EventArgs e)
        {
            Task.Run(async () =>
            {
                while (!cts.IsCancellationRequested)
                {
                    await Task.Delay(200);
                    byte[] buffer = new byte[1024];
                    int length = -1;
                    length = tcpClient.Receive(buffer, SocketFlags.None);
                    byte[] result = new byte[CommonMethods.ByteLenth / 2];
                    byte[] setArray1 = new byte[CommonMethods.ByteLenth / 2];
                    this.setArray = setArray1;
                    if (length == CommonMethods.ByteLenth) //100 =100
                    {
                        //数据源, 数据源开始索引, 目标数据,目标数据开始索引, 长度
                        Array.Copy(buffer, 0, result, 0, CommonMethods.ByteLenth / 2);
                        setArray = ByteArrayLib.GetByteArrayFromByteArray(buffer, CommonMethods.ByteLenth / 2, CommonMethods.ByteLenth / 2);

                        foreach (var item in CommonMethods.AllVarList)
                        {
                            int start = item.VarAddress * 2;
                            switch (item.VarType)
                            {
                                case DataType.Bool:
                                    item.Value = BitLib.GetBitFromByteArray(result, start, int.Parse(item.Offset)).ToString();
                                    break;
                                case DataType.Short:
                                    item.Value = ShortLib.GetShortFromByteArray(result, start).ToString();
                                    
                                    break;
                                case DataType.UShort:
                                    item.Value = UShortLib.GetUShortFromByteArray(result, start).ToString();
                                    break;
                                case DataType.Int:
                                    item.Value = IntLib.GetIntFromByteArray(result, start).ToString();
                                    break;
                                case DataType.UInt:
                                    item.Value = UIntLib.GetUIntFromByteArray(result, start).ToString();
                                    break;
                                case DataType.Float:
                                    item.Value = FloatLib.GetFloatFromByteArray(result, start).ToString();
                                    break;
                                case DataType.Double:
                                    item.Value = DoubleLib.GetDoubleFromByteArray(result, start).ToString();
                                    break;
                                default:
                                    break;
                            }
                            //包含就替换,否则就添加
                            if (CommonMethods.CurrentPLCValue.ContainsKey(item.Name))
                            {
                                CommonMethods.CurrentPLCValue[item.Name] = item.Value;

                            }
                            else
                            {
                                CommonMethods.CurrentPLCValue.Add(item.Name, item.Value);
                            }
                        }
                    }

                    foreach (var item in CommonMethods.CurrentPLCValue)
                    {
                        this.isInfo.Invoke(() =>
                        {
                            this.isInfo.Items.Add(item.Key+":");
                            this.isInfo.Items.Add(item.Value.ToString());
                        });
                    };

                    Invoke(new Action(() =>
                    {
                        foreach (Control item in this.Controls)
                        {
                            //if (item is TextBox txt)
                            //{
                            //    item.Text = CommonMethods.CurrentPLCValue[this.comboBox1.Text].ToString();
                            //}
                            if (item is LabelShow ls)
                            {
                                if (ls.VarTitle == "Float1")
                                {
                                    ls.VarValue = CommonMethods.CurrentPLCValue["Float1"].ToString();
                                }
                                if (ls.VarTitle == "Float2")
                                {
                                    ls.VarValue = CommonMethods.CurrentPLCValue["Float2"].ToString();
                                }
                                if (ls.VarTitle == "Float3")
                                {
                                    ls.VarValue = CommonMethods.CurrentPLCValue["Float3"].ToString();
                                }
                                if (ls.VarTitle == "Float4")
                                {
                                    ls.VarValue = CommonMethods.CurrentPLCValue["Float4"].ToString();
                                }
                                if (ls.VarTitle == "UShort1")
                                {
                                    ls.VarValue = CommonMethods.CurrentPLCValue["UShort1"].ToString();
                                }
                                if (ls.VarTitle == "UShort2")
                                {
                                    ls.VarValue = CommonMethods.CurrentPLCValue["UShort2"].ToString();
                                }
                            }
                        }
                    }
                    ));

                }

            }, cts.Token);
        }

        private void btnServer_Click(object sender, EventArgs e)
        {
            frmServer = new FrmServer();
            frmServer.ShowDialog();
        }

        private void btnDisc_Click(object sender, EventArgs e)
        {
            try
            {
                tcpClient.Close();
                CommonMethods.IsConnected = tcpClient.Connected;
                //CommonMethods.IsConnected = false;
                Addinfo(CommonMethods.IsConnected ? "没有断开" : "断开成功");
            }
            catch (Exception)
            {

                throw;
            }
        }

        private void btnWrite1_Click(object sender, EventArgs e)
        {
            List<byte> res = new List<byte>();
            //byte[] res;
            string varName = this.comboBox1.Text;
            float valueF1 = Convert.ToSingle(this.txt1.Text.Trim());
            ushort valueS = Convert.ToUInt16(Math.Floor(double.Parse(this.txt1.Text.Trim())));
            int varAddress = 0;
            switch (CommonMethods.CurrentPLCNote[varName])
            {
                case DataType.UShort:
                    res = ByteArrayLib.GetByteArrayFromUShort(valueS).ToList();
                    break;
                case DataType.Float:
                    res = ByteArrayLib.GetByteArrayFromFloat(valueF1).ToList();
                    break;
                default:
                    break;
            }

            foreach (var item in CommonMethods.AllVarList)
            {
                if (item.Name==this.comboBox1.Text)
                {
                    varAddress = item.VarAddress;
                }
            }

            byte[] set = ByteArrayLib.ReplaceByteArray(setArray, varAddress*2, res.ToArray());
            tcpClient.Send(set, SocketFlags.None);
        }

        public byte[] ReplaceByteArray(byte[] source, int start, byte[] value)
        {
            for (int i = 0; i < value.Length; i++)
            {
                source[start + i] = value[i];
            }
            return source;
        }
    }
}

读取ASCII与其他格式

using STM32Demon.DataConvertLib;
using System.Text.RegularExpressions;
using DataType = thinger.DataConvertLib.DataType;

namespace STM32Demon
{
    public partial class FrmMain1 : Form
    {
        public FrmMain1()
        {
            InitializeComponent();
            this.Load += FrmMain1_Load;
        }

        //private ModelsResponsitory dbContext = new ModelsResponsitory();
        private ConfigurationBuilder cfgBuilder = new ConfigurationBuilder();
        private IConfigurationRoot configRoot;
        private CancellationTokenSource cts = new CancellationTokenSource();
        private byte[] setArray;
        private Socket tcpClient;
        private FrmServer frmServer;
        InsertDataSQLite objInsert = new InsertDataSQLite(10000);//10秒1次

        private void FrmMain1_Load(object? sender, EventArgs e)
        {
            cfgBuilder.AddJsonFile("VariableNode.json", optional: true, reloadOnChange: true);
            this.configRoot = cfgBuilder.Build();

            //服务器Ip和端口
            CommonMethods.Ip = configRoot.GetSection("ServerURL").Value;
            CommonMethods.Port = configRoot.GetSection("Port").Value;

            //自建服务器Ip和端口
            CommonMethods.CreateIp = configRoot.GetSection("CrateServer").Value;
            CommonMethods.CreatePort = configRoot.GetSection("CreatePort").Value;

            CommonMethods.VarNum = configRoot.GetSection("VarNum").Value;
            CommonMethods.ByteLenth = int.Parse(configRoot.GetSection("ByteLenth").Value);
            CommonMethods.AllVarList = new List<Variable>();
            //读入点表
            for (int i = 0; i < int.Parse(CommonMethods.VarNum); i++)
            {
                Variable variable = configRoot.GetSection($"Variable:{i}").Get<Variable>();
                CommonMethods.AllVarList.Add(variable);
            }
            //给combox加入变量
            foreach (var item in CommonMethods.AllVarList)
            {
                this.comboBox1.Invoke(() =>
                {
                    this.comboBox1.Items.Add(item.Name);
                });
                CommonMethods.CurrentPLCValue.Add(item.Name, item.Value);
                CommonMethods.CurrentPLCNote.Add(item.Name, item.VarType);
            }
        }

        private void btnConn_Click(object sender, EventArgs e)
        {
            tcpClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            tcpClient.Connect(IPAddress.Parse(CommonMethods.Ip), int.Parse(CommonMethods.Port));
            CommonMethods.IsConnected = tcpClient.Connected;
            CommonMethods.FirstConnect = false;
            Addinfo(CommonMethods.IsConnected ? "连接成功" : "连接失败");
        }


        private void Addinfo(string info)
        {
            this.isInfo.Items.Insert(
                0, DateTime.Now.ToString("HH:mm:ss") + " " + info + Environment.NewLine);
        }

        private void btnRead_Click(object sender, EventArgs e)
        {
            Task.Run( () =>
            {
                while (!cts.IsCancellationRequested)
                {
                    Task.Delay(200);
                    byte[] buffer = new byte[1024 * 1024 * 10];
                    int length = -1;
                    try
                    {
                        length = tcpClient.Receive(buffer, SocketFlags.None);
                    }
                    catch (Exception)
                    {
                        break;
                    }
                    
                    if (length > 0)
                    {
                        string msg = string.Empty;
                        string msg2 = string.Empty;
                        MessageType type = (MessageType)buffer[0];

                        msg = Encoding.ASCII.GetString(buffer, 1, length - 1);

                        msg2 = Encoding.ASCII.GetString(buffer, 0, length);
                        //UTF8:
                        //msg = Encoding.UTF8.GetString(buffer, 1, length - 1);

                        //hex:
                        //msg = HexGetString(buffer, 1, length - 1);



                        AddLog(0, "服务器:" + msg);
                        AddLog2(0, "服务器:" + msg2);
                        //switch (type)
                        //{
                        //    case MessageType.ASCII:

                        //        msg = Encoding.ASCII.GetString(buffer, 1, length - 1);

                        //        AddLog(0, "服务器:" + msg);

                        //        break;
                        //    case MessageType.UTF8:

                        //        msg = Encoding.UTF8.GetString(buffer, 1, length - 1);

                        //        AddLog(0, "服务器:" + msg);

                        //        break;
                        //    case MessageType.Hex:

                        //        msg = HexGetString(buffer, 1, length - 1);

                        //        AddLog(0, "服务器:" + msg);

                        //        break;
                        //    case MessageType.File:

                        //        Invoke(new Action(() =>
                        //        {
                        //            SaveFileDialog sfd = new SaveFileDialog();

                        //            sfd.Filter = "txt files(*.txt)|*.txt|xls files(*.xls)|*.xls|xlsx files(*.xlsx)|*.xlsx|All files(*.*)|*.*";

                        //            if (sfd.ShowDialog() == DialogResult.OK)
                        //            {
                        //                string fileSavePath = sfd.FileName;

                        //                using (FileStream fs = new FileStream(fileSavePath, FileMode.Create))
                        //                {
                        //                    fs.Write(buffer, 1, length - 1);
                        //                }

                        //                AddLog(0, "文件成功保存至" + fileSavePath);
                        //            }
                        //        }));

                        //        break;
                        //    case MessageType.JSON:


                        //        break;
                        //    default:
                        //        break;
                        //}
                    }




                    //byte[] result = new byte[CommonMethods.ByteLenth / 2];
                    //byte[] setArray1 = new byte[CommonMethods.ByteLenth / 2];
                    //string msg = string.Empty;
                    //this.setArray = setArray1;
                    //if (length > 0) //100 =100
                    //{
                    //    //数据源, 数据源开始索引, 目标数据,目标数据开始索引, 长度
                    //    Array.Copy(buffer, 0, result, 0, CommonMethods.ByteLenth / 2);
                    //    //setArray = ByteArrayLib.GetByteArrayFromByteArray(buffer, CommonMethods.ByteLenth / 2, CommonMethods.ByteLenth / 2);
                    //    setArray = ByteArrayLib.GetByteArrayFromByteArray(buffer, 0, CommonMethods.ByteLenth / 2);
                    //    foreach (var item in CommonMethods.AllVarList)
                    //    {
                    //        int start = item.VarAddress * 2;
                    //        switch (item.VarType)
                    //        {
                    //            case DataType.Bool:
                    //                item.Value = BitLib.GetBitFromByteArray(result, start, int.Parse(item.Offset)).ToString();
                    //                break;
                    //            case DataType.Short:
                    //                item.Value = ShortLib.GetShortFromByteArray(result, start).ToString();
                                    
                    //                break;
                    //            case DataType.UShort:
                    //                item.Value = UShortLib.GetUShortFromByteArray(result, start).ToString();
                    //                break;
                    //            case DataType.Int:
                    //                item.Value = IntLib.GetIntFromByteArray(result, start).ToString();
                    //                break;
                    //            case DataType.UInt:
                    //                item.Value = UIntLib.GetUIntFromByteArray(result, start).ToString();
                    //                break;
                    //            case DataType.Float:
                    //                item.Value = FloatLib.GetFloatFromByteArray(result, start).ToString();
                    //                break;
                    //            case DataType.Double:
                    //                item.Value = DoubleLib.GetDoubleFromByteArray(result, start).ToString();
                    //                break;
                    //            case DataType.ASCII:
                    //                break;
                    //            default:
                    //                break;
                    //        }
                    //        //包含就替换,否则就添加
                    //        if (CommonMethods.CurrentPLCValue.ContainsKey(item.Name))
                    //        {
                    //            CommonMethods.CurrentPLCValue[item.Name] = item.Value;

                    //        }
                    //        else
                    //        {
                    //            CommonMethods.CurrentPLCValue.Add(item.Name, item.Value);
                    //        }
                    //    }
                    //}

                    //foreach (var item in CommonMethods.CurrentPLCValue)
                    //{
                    //    this.isInfo.Invoke(() =>
                    //    {
                    //        this.isInfo.Items.Add(item.Key+":");
                    //        this.isInfo.Items.Add(item.Value.ToString());
                    //    });
                    //};
                    //Task.Delay(200);
                    //Invoke(new Action(() =>
                    //{
                    //    foreach (Control item in this.Controls)
                    //    {
                    //        //if (item is TextBox txt)
                    //        //{
                    //        //    item.Text = CommonMethods.CurrentPLCValue[this.comboBox1.Text].ToString();
                    //        //}
                    //        if (item is LabelShow ls)
                    //        {
                    //            for (int i = 0; i < 12; i++)
                    //            {
                    //                if (ls.VarTitle == $"UShort{i}")
                    //                {
                    //                    ls.VarValue = CommonMethods.CurrentPLCValue[$"UShort{i}"].ToString();
                    //                }
                    //            }
                    //        }
                    //    }
                    //}
                    //));

                }

            }, cts.Token);
        }

        #region 16进制字符串处理

        private string HexGetString(byte[] buffer, int start, int length)
        {
            string Result = string.Empty;

            if (buffer != null && buffer.Length >= start + length)
            {
                //截取字节数组

                byte[] res = new byte[length];

                Array.Copy(buffer, start, res, 0, length);

                string Hex = Encoding.Default.GetString(res, 0, res.Length);

                // 01   03 0 40 0A
                if (Hex.Contains(" "))
                {
                    string[] str = Regex.Split(Hex, "\\s+", RegexOptions.IgnoreCase);

                    foreach (var item in str)
                    {
                        Result += "0x" + item + " ";
                    }
                }
                else
                {
                    Result += "0x" + Hex;
                }

            }
            else
            {
                Result = "Error";
            }
            return Result;
        }


        #endregion

        //当前时间属性
        private string CurrentTime
        {
            get { return DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); }
        }

        private void AddLog(int index, string info)
        {
            if (!this.lst_Rcv.InvokeRequired)
            {
                ListViewItem lst = new ListViewItem("   " + CurrentTime, index);

                lst.SubItems.Add(info);

                lst_Rcv.Items.Insert(lst_Rcv.Items.Count, lst);

            }
            else
            {
                Invoke(new Action(() =>
                {
                    ListViewItem lst = new ListViewItem("   " + CurrentTime, index);

                    lst.SubItems.Add(info);

                    lst_Rcv.Items.Insert(lst_Rcv.Items.Count, lst);
                }));
            }
        }

        private void AddLog2(int index, string info)
        {
            if (!this.lst_Rcv1.InvokeRequired)
            {
                ListViewItem lst = new ListViewItem("   " + CurrentTime, index);

                lst.SubItems.Add(info);

                lst_Rcv1.Items.Insert(lst_Rcv1.Items.Count, lst);

            }
            else
            {
                Invoke(new Action(() =>
                {
                    ListViewItem lst = new ListViewItem("   " + CurrentTime, index);

                    lst.SubItems.Add(info);

                    lst_Rcv1.Items.Insert(lst_Rcv1.Items.Count, lst);
                }));
            }
        }

        private void btnServer_Click(object sender, EventArgs e)
        {
            frmServer = new FrmServer();
            frmServer.ShowDialog();
        }

        private void btnDisc_Click(object sender, EventArgs e)
        {
            try
            {
                tcpClient.Close();
                CommonMethods.IsConnected = tcpClient.Connected;
                //CommonMethods.IsConnected = false;
                Addinfo(CommonMethods.IsConnected ? "没有断开" : "断开成功");
            }
            catch (Exception)
            {

                throw;
            }
        }

        private void btnWrite1_Click(object sender, EventArgs e)
        {
            List<byte> res = new List<byte>();
            //byte[] res;
            string varName = this.comboBox1.Text;
            float valueF1 = Convert.ToSingle(this.txt1.Text.Trim());
            ushort valueS = Convert.ToUInt16(Math.Floor(double.Parse(this.txt1.Text.Trim())));
            int varAddress = 0;
            switch (CommonMethods.CurrentPLCNote[varName])
            {
                case DataType.UShort:
                    res = ByteArrayLib.GetByteArrayFromUShort(valueS).ToList();
                    break;
                case DataType.Float:
                    res = ByteArrayLib.GetByteArrayFromFloat(valueF1).ToList();
                    break;
                default:
                    break;
            }

            foreach (var item in CommonMethods.AllVarList)
            {
                if (item.Name==this.comboBox1.Text)
                {
                    varAddress = item.VarAddress;
                }
            }

            byte[] set = ByteArrayLib.ReplaceByteArray(setArray, varAddress*2, res.ToArray());
            tcpClient.Send(set, SocketFlags.None);
        }

        public byte[] ReplaceByteArray(byte[] source, int start, byte[] value)
        {
            for (int i = 0; i < value.Length; i++)
            {
                source[start + i] = value[i];
            }
            return source;
        }

        private void btnSendASC_Click(object sender, EventArgs e)
        {
            AddLog(0, "发送内容:" + this.txt_Send.Text.Trim());
            byte[] send = Encoding.ASCII.GetBytes(this.txt_Send.Text.Trim());

            //创建最终发送的数组
            byte[] sendMsg = new byte[send.Length + 1];

            //整体拷贝数组
            Array.Copy(send, 0, sendMsg, 1, send.Length);

            //给首字节赋值

            sendMsg[0] = (byte)MessageType.ASCII;

            tcpClient?.Send(sendMsg);

            this.txt_Send.Clear();
        }

        private void btnSendASC2_Click(object sender, EventArgs e)
        {
            AddLog(0, "发送内容:" + this.txt_Send.Text.Trim());
            byte[] send = Encoding.ASCII.GetBytes(this.txt_Send.Text.Trim());

            //UTF8:
            //byte[] send = Encoding.UTF8.GetBytes(this.txt_Send.Text.Trim());

            //hex
            //byte[] send = Encoding.Default.GetBytes(this.txt_Send.Text.Trim());

            tcpClient?.Send(send);

            this.txt_Send.Clear();
        }
    }
}

服务器端主程序

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using thinger.DataConvertLib;

namespace STM32Demon
{
    public partial class FrmServer : Form
    {
        public FrmServer()
        {
            InitializeComponent();
            this.Load += FrmServer_Load;
        }

        private void FrmServer_Load(object? sender, EventArgs e)
        {
            //给combox加入变量
            foreach (var item in CommonMethods.AllVarList)
            {
                this.comboBox1.Invoke(() =>
                {
                    this.comboBox1.Items.Add(item.Name);
                });
            }
        }

        private Socket tcpServer;

        private CancellationTokenSource cts;

        private byte[] setArray;

        private List<Socket> SocketList = new List<Socket>();

        private void Addinfo(string info)
        {
            this.isInfo.Items.Insert(
                0, DateTime.Now.ToString("HH:mm:ss") + " " + info + Environment.NewLine);
        }


        private void btnCeate_Click(object sender, EventArgs e)
        {
            tcpServer = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            IPEndPoint ipe = new IPEndPoint(IPAddress.Parse(CommonMethods.CreateIp), int.Parse(CommonMethods.CreatePort));
            try
            {
                tcpServer.Bind(ipe);
            }
            catch (Exception)
            {
                MessageBox.Show("服务器开启失败");
                return;
            }
            MessageBox.Show("服务器开启成功");

            tcpServer.Listen(6);
            //开启多线程侦听

            Task.Run(new Action(() =>
            {
                ListenConnection();

            }));
        }

        private void ListenConnection()
        {
            while (true)
            {
                Task.Delay(500);

                try
                {
                    //创建一个新的socket连接
                    Socket tcpClient = tcpServer.Accept();

                    SocketList.Add(tcpClient);

                    Task.Run(new Action(() =>
                    {
                        ReceiveFromPLC(tcpClient);
                    }));
                }
                catch (Exception)
                {
                    break;
                }
            }
        }

        private void ReceiveFromPLC(Socket tcpClient)
        {
            while (true)
            {
                Task.Delay(200);
                byte[] buffer = new byte[1024];
                int length = -1;
                try
                {
                    length = tcpClient.Receive(buffer, SocketFlags.None);
                }
                catch (Exception)
                {
                    break;
                }

                byte[] result = new byte[CommonMethods.ByteLenth / 2];
                byte[] setArray1 = new byte[CommonMethods.ByteLenth / 2];
                this.setArray = setArray1;
                if (length == CommonMethods.ByteLenth) //100 =100
                {
                    //数据源, 数据源开始索引, 目标数据,目标数据开始索引, 长度
                    Array.Copy(buffer, 0, result, 0, CommonMethods.ByteLenth / 2);
                    setArray = ByteArrayLib.GetByteArrayFromByteArray(buffer, CommonMethods.ByteLenth / 2, CommonMethods.ByteLenth / 2);

                    foreach (var item in CommonMethods.AllVarList)
                    {
                        int start = item.VarAddress * 2;
                        switch (item.VarType)
                        {
                            case DataType.Bool:
                                item.Value = BitLib.GetBitFromByteArray(result, start, int.Parse(item.Offset)).ToString();
                                break;
                            case DataType.Short:
                                item.Value = ShortLib.GetShortFromByteArray(result, start).ToString();

                                break;
                            case DataType.UShort:
                                item.Value = UShortLib.GetUShortFromByteArray(result, start).ToString();
                                break;
                            case DataType.Int:
                                item.Value = IntLib.GetIntFromByteArray(result, start).ToString();
                                break;
                            case DataType.UInt:
                                item.Value = UIntLib.GetUIntFromByteArray(result, start).ToString();
                                break;
                            case DataType.Float:
                                item.Value = FloatLib.GetFloatFromByteArray(result, start).ToString();
                                break;
                            case DataType.Double:
                                item.Value = DoubleLib.GetDoubleFromByteArray(result, start).ToString();
                                break;
                            default:
                                break;
                        }
                        //包含就替换,否则就添加
                        if (CommonMethods.CurrentPLCValue.ContainsKey(item.Name))
                        {
                            CommonMethods.CurrentPLCValue[item.Name] = item.Value;

                        }
                        else
                        {
                            CommonMethods.CurrentPLCValue.Add(item.Name, item.Value);
                        }
                    }
                }

                foreach (var item in CommonMethods.CurrentPLCValue)
                {
                    this.isInfo.Invoke(() =>
                    {
                        this.isInfo.Items.Add(item.Key + ":");
                        this.isInfo.Items.Add(item.Value.ToString());
                    });
                };
                Task.Delay(200);
                Invoke(new Action(() =>
                {
                    foreach (Control item in this.Controls)
                    {
                        //if (item is TextBox txt)
                        //{
                        //    item.Text = CommonMethods.CurrentPLCValue[this.comboBox1.Text].ToString();
                        //}
                        if (item is LabelShow ls)
                        {
                            if (ls.VarTitle == "Float1")
                            {
                                ls.VarValue = CommonMethods.CurrentPLCValue["Float1"].ToString();
                            }
                            if (ls.VarTitle == "Float2")
                            {
                                ls.VarValue = CommonMethods.CurrentPLCValue["Float2"].ToString();
                            }
                            if (ls.VarTitle == "Float3")
                            {
                                ls.VarValue = CommonMethods.CurrentPLCValue["Float3"].ToString();
                            }
                            if (ls.VarTitle == "Float4")
                            {
                                ls.VarValue = CommonMethods.CurrentPLCValue["Float4"].ToString();
                            }
                            if (ls.VarTitle == "UShort1")
                            {
                                ls.VarValue = CommonMethods.CurrentPLCValue["UShort1"].ToString();
                            }
                            if (ls.VarTitle == "UShort2")
                            {
                                ls.VarValue = CommonMethods.CurrentPLCValue["UShort2"].ToString();
                            }
                        }
                    }
                }
                ));
            }
        }

        private void btnWrite1_Click(object sender, EventArgs e)
        {
            List<byte> res = new List<byte>();
            //byte[] res;
            string varName = this.comboBox1.Text;
            float valueF1 = Convert.ToSingle(this.txt1.Text.Trim());
            ushort valueS = Convert.ToUInt16(Math.Floor(double.Parse(this.txt1.Text.Trim())));
            int varAddress = 0;
            switch (CommonMethods.CurrentPLCNote[varName])
            {
                case DataType.UShort:
                    res = ByteArrayLib.GetByteArrayFromUShort(valueS).ToList();
                    break;
                case DataType.Float:
                    res = ByteArrayLib.GetByteArrayFromFloat(valueF1).ToList();
                    break;
                default:
                    break;
            }

            foreach (var item in CommonMethods.AllVarList)
            {
                if (item.Name == this.comboBox1.Text)
                {
                    varAddress = item.VarAddress;
                }
            }

            byte[] set = ByteArrayLib.ReplaceByteArray(setArray, varAddress * 2, res.ToArray());
            //tcpClient.Send(set, SocketFlags.None);
            this.SocketList[0].Send(set, SocketFlags.None);
        }

        public byte[] ReplaceByteArray(byte[] source, int start, byte[] value)
        {
            for (int i = 0; i < value.Length; i++)
            {
                source[start + i] = value[i];
            }
            return source;
        }
    }
}

实体类 Model

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using thinger.DataConvertLib;

namespace STM32Demon.Models
{
    public class Variable
    {
        public int Id { get; set; }
        public string Number { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }
        public string Type { get; set; }
        public int VarAddress { get; set; }
        public string Scale { get; set; }
        public string Offset { get; set; }
        public string Start { get; set; }
        public string AccessProperty { get; set; }
        public DataType VarType { get; set; }
        public string InsertTime { get; set; }
        public string Value { get; set; }
    }
}

通用类

using Microsoft.EntityFrameworkCore.Query;
using STM32Demon.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using thinger.DataConvertLib;

namespace STM32Demon
{
    public class CommonMethods
    {
        public static Dictionary<string, object> CurrentPLCValue = new Dictionary<string, object>();

        //归档变量集合
        public static List<Variable> ArchiveVarList = new List<Variable>();

        //所有
        public static List<Variable> AllVarList = new List<Variable>();
        /// 
        /// 键值对,键是变量名称,值是其对应的变量实体对象 用来写数据
        /// 
        public static Dictionary<string, Variable> CurrentPLCVariable = new Dictionary<string, Variable>();

        /// 
        /// 变量名称和变量地址的键值对
        /// 
        public static Dictionary<string, DataType> CurrentPLCNote = new Dictionary<string, DataType>();

        public static bool IsConnected = false;

        public static int CacheCount = 600;//10分钟, 每秒一条

        //public static IIncludableQueryable> ModbusTCPList;
        public static int ErrorTimes = 0;
        public static bool FirstConnect = true;
        public static string Ip;
        public static string Port;
        public static string VarNum;
        public static int ByteLenth;
    }
}

博途程序 :

.NET6实现对西门子1500PLC的开放式TCP/IP数据读取与写入_第1张图片

.NET6实现对西门子1500PLC的开放式TCP/IP数据读取与写入_第2张图片

.NET6实现对西门子1500PLC的开放式TCP/IP数据读取与写入_第3张图片

"TCPServerSendData".Float1 := "TCPServerSendData".Float5;
"TCPServerSendData".Float2 := "TCPServerSendData".Float6;
"TCPServerSendData".Float3 := "TCPServerSendData".Float7;
"TCPServerSendData".Float4 := "TCPServerSendData".Float8;
"TCPServerSendData".Ushort1 := "TCPServerSendData".Ushort3;
"TCPServerSendData".Ushort2 := "TCPServerSendData".Ushort4;

.NET6实现对西门子1500PLC的开放式TCP/IP数据读取与写入_第4张图片
.NET6实现对西门子1500PLC的开放式TCP/IP数据读取与写入_第5张图片

你可能感兴趣的:(c#)