public ActionResult Login(FormCollection fc) { //请求指令头数据,该数据需要更具实际情况更改 OperateResultString result = UserClient.Net_simplify_client.ReadFromServer(CommonHeadCode.SimplifyHeadCode.维护检查); if (result.IsSuccess) { //例如返回结果为1说明允许登录,0则说明服务器处于维护中,并将信息显示 if (result.Content != "1") { return(Login(result.Message)); } } else { //访问失败 return(Login(result.Message)); } //检查账户 //包装数据 JObject json = new JObject { { UserAccount.UserNameText, new JValue(fc["UserName"]) }, { UserAccount.PasswordText, new JValue(fc["UserPassword"]) }, { UserAccount.LoginWayText, new JValue("webApp") }, { UserAccount.DeviceUniqueID, new JValue(UserClient.JsonSettings.SystemInfo) }, // 客户端唯一ID { UserAccount.FrameworkVersion, new JValue(SoftBasic.FrameworkVersion.ToString()) } // 客户端框架版本 }; result = UserClient.Net_simplify_client.ReadFromServer(CommonLibrary.CommonHeadCode.SimplifyHeadCode.账户检查, json.ToString()); if (result.IsSuccess) { //服务器应该返回账户的信息 UserAccount account = JObject.Parse(result.Content).ToObject <UserAccount>(); if (!account.LoginEnable) { //不允许登录 return(Login(account.ForbidMessage)); } Session[SessionItemsDescription.UserAccount] = account; //UserClient.UserAccount = account; } else { //访问失败 return(Login(result.Message)); } result = UserClient.Net_simplify_client.ReadFromServer(CommonLibrary.CommonHeadCode.SimplifyHeadCode.更新检查); if (result.IsSuccess) { //服务器应该返回服务器的版本号 SystemVersion sv = new SystemVersion(result.Content); //系统账户跳过低版本检测 if (fc["UserName"] != "admin") { if (UserClient.CurrentVersion != sv) { return(Login("当前版本号不正确,需要联系管理员更新服务器才允许登录。")); } } else { if (UserClient.CurrentVersion < sv) { return(Login("版本号过时,需要联系管理员更新服务器才允许登录。")); } } } else { //访问失败 return(Login(result.Message)); } result = UserClient.Net_simplify_client.ReadFromServer(CommonHeadCode.SimplifyHeadCode.参数下载); if (result.IsSuccess) { //服务器返回初始化的数据,此处进行数据的提取,有可能包含了多个数据 json = JObject.Parse(result.Content); //例如公告数据 UserClient.Announcement = SoftBasic.GetValueFromJsonObject(json, nameof(UserClient.Announcement), ""); } else { //访问失败 //访问失败 return(Login(result.Message)); } //允许登录,并记录到Session return(RedirectToAction("Index", "Home")); }
/// <summary> /// 向设备中写入指定长度的字符串,超出截断,不够补0,编码格式为Unicode /// </summary> /// <param name="address">数据地址</param> /// <param name="value">字符串数据</param> /// <param name="length">指定的字符串长度,必须大于0</param> /// <returns>是否写入成功的结果对象 -> Whether to write a successful result object</returns> public virtual OperateResult WriteUnicodeString(string address, string value, int length) { byte[] temp = ByteTransform.TransByte(value, Encoding.Unicode); temp = SoftBasic.ArrayExpandToLength(temp, length * 2); return(Write(address, temp)); }
/// <summary> /// 接收到来自客户端的数据,此处需要放置维护验证,更新验证等等操作 /// </summary> /// <param name="object1">客户端的地址</param> /// <param name="object2">消息数据,应该使用指令头+数据组成</param> private void Net_simplify_server_ReceiveStringEvent(HuStateOne object1, string object2) { //如果此处充斥大量if语句,影响观感,则考虑进行指令头分类操作 //必须返回结果,调用SendMessage(object1,[实际数据]); string head_code = object2.Substring(0, 4); if (head_code == CommonHeadCode.SimplifyHeadCode.维护检查) { net_simplify_server.SendMessage(object1, UserServer.ServerSettings.Can_Account_Login ? "1" : "0" + UserServer.ServerSettings.Account_Forbidden_Reason); } else if (head_code == CommonHeadCode.SimplifyHeadCode.更新检查) { net_simplify_server.SendMessage(object1, UserServer.ServerSettings.SystemVersion.ToString()); } else if (head_code == CommonHeadCode.SimplifyHeadCode.参数下载) { Newtonsoft.Json.Linq.JObject json = new Newtonsoft.Json.Linq.JObject(); json.Add(nameof(UserServer.ServerSettings.Announcement), new Newtonsoft.Json.Linq.JValue(UserServer.ServerSettings.Announcement)); net_simplify_server.SendMessage(object1, json.ToString()); } else if (head_code == CommonHeadCode.SimplifyHeadCode.账户检查) { //此处使用的是组件自带的验证的方式,如果使用SQL数据库,另行验证 Newtonsoft.Json.Linq.JObject json = Newtonsoft.Json.Linq.JObject.Parse(object2.Substring(4)); //提取账户,密码 string name = SoftBasic.GetValueFromJsonObject(json, UserAccount.UserNameText, ""); string password = SoftBasic.GetValueFromJsonObject(json, UserAccount.PasswordText, ""); net_simplify_server.SendMessage(object1, UserServer.ServerAccounts.CheckAccountJson( name, password, ((System.Net.IPEndPoint)(object1._WorkSocket.RemoteEndPoint)).Address.ToString())); } else if (head_code == CommonHeadCode.SimplifyHeadCode.更新公告) { UserServer.ServerSettings.Announcement = object2.Substring(4); //通知所有客户端更新公告 net_socket_server.SendAllClients(object2); net_simplify_server.SendMessage(object1, "成功"); } else if (head_code == CommonHeadCode.SimplifyHeadCode.获取账户信息) { //返回服务器的账户信息 net_simplify_server.SendMessage(object1, UserServer.ServerAccounts.GetAllAccountsJson()); } else if (head_code == CommonHeadCode.SimplifyHeadCode.更细账户信息) { //更新服务器的账户信息 UserServer.ServerAccounts.LoadAllAccountsJson(object2.Substring(4)); net_simplify_server.SendMessage(object1, "成功"); } else if (head_code == CommonHeadCode.SimplifyHeadCode.密码修改) { //更新服务器的账户密码 //此处使用的是组件自带的验证的方式,如果使用SQL数据库,另行验证 Newtonsoft.Json.Linq.JObject json = Newtonsoft.Json.Linq.JObject.Parse(object2.Substring(4)); //提取账户,密码 string name = SoftBasic.GetValueFromJsonObject(json, UserAccount.UserNameText, ""); string password = SoftBasic.GetValueFromJsonObject(json, UserAccount.PasswordText, ""); UserServer.ServerAccounts.UpdatePassword(name, password); net_simplify_server.SendMessage(object1, "成功"); } else if (head_code == CommonHeadCode.SimplifyHeadCode.网络日志查看) { net_simplify_server.SendMessage(object1, net_socket_server.LogReacord.GetLogText()); } else if (head_code == CommonHeadCode.SimplifyHeadCode.网络日志清空) { net_socket_server.LogReacord.ClearLogText(); net_simplify_server.SendMessage(object1, "成功"); } else if (head_code == CommonHeadCode.SimplifyHeadCode.步日志查看) { net_simplify_server.SendMessage(object1, net_simplify_server.log_record.GetLogText()); } else if (head_code == CommonHeadCode.SimplifyHeadCode.步日志清空) { net_simplify_server.log_record.ClearLogText(); net_simplify_server.SendMessage(object1, "成功"); } else if (head_code == CommonHeadCode.SimplifyHeadCode.更新日志查看) { net_simplify_server.SendMessage(object1, net_soft_update_Server.log_record.GetLogText()); } else if (head_code == CommonHeadCode.SimplifyHeadCode.更新日志清空) { net_soft_update_Server.log_record.ClearLogText(); net_simplify_server.SendMessage(object1, "成功"); } else if (head_code == CommonHeadCode.SimplifyHeadCode.注册账号) { bool result = UserServer.ServerAccounts.AddNewAccount(object2.Substring(4)); net_simplify_server.SendMessage(object1, result ? "1" : "0"); } else { net_simplify_server.SendMessage(object1, object2); } }
/// <summary> /// 向PLC中字软元件写入字符串,编码格式为ASCII /// </summary> /// <param name="address">要写入的数据地址</param> /// <param name="value">要写入的实际数据</param> /// <returns>返回读取结果</returns> public OperateResult Write(string address, string value) { byte[] temp = Encoding.ASCII.GetBytes(value); temp = SoftBasic.ArrayExpandToLengthEven(temp); return(Write(address, temp)); }
/// <summary> /// 批量读取PLC的数据,以字为单位,支持读取X,Y,M,S,D,T,C,具体的地址范围需要根据PLC型号来确认 /// </summary> /// <param name="address">地址信息</param> /// <param name="length">数据长度</param> /// <returns>读取结果信息</returns> public override OperateResult <byte[]> Read(string address, ushort length) { OperateResult <byte[]> operateResult = MelsecFxLinksOverTcp.BuildReadCommand(station, address, length, isBool: false, sumCheck, watiingTime); if (!operateResult.IsSuccess) { return(OperateResult.CreateFailedResult <byte[]>(operateResult)); } OperateResult <byte[]> operateResult2 = ReadBase(operateResult.Content); if (!operateResult2.IsSuccess) { return(OperateResult.CreateFailedResult <byte[]>(operateResult2)); } if (operateResult2.Content[0] != 2) { return(new OperateResult <byte[]>(operateResult2.Content[0], "Read Faild:" + SoftBasic.ByteToHexString(operateResult2.Content, ' '))); } byte[] array = new byte[length * 2]; for (int i = 0; i < array.Length / 2; i++) { ushort value = Convert.ToUInt16(Encoding.ASCII.GetString(operateResult2.Content, i * 4 + 5, 4), 16); BitConverter.GetBytes(value).CopyTo(array, i * 2); } return(OperateResult.CreateSuccessResult(array)); }
/// <summary> /// Extract actual data form plc response /// </summary> /// <param name="response">response data</param> /// <param name="isRead">read</param> /// <returns>result</returns> public static OperateResult <byte[]> ExtractActualData(byte[] response, bool isRead) { try { if (isRead) { if (response[0] == 0x06) { byte[] buffer = new byte[response.Length - 13]; Array.Copy(response, 10, buffer, 0, buffer.Length); return(OperateResult.CreateSuccessResult(SoftBasic.AsciiBytesToBytes(buffer))); } else { byte[] buffer = new byte[response.Length - 9]; Array.Copy(response, 6, buffer, 0, buffer.Length); return(new OperateResult <byte[]>(BitConverter.ToUInt16(SoftBasic.AsciiBytesToBytes(buffer), 0), "Data:" + SoftBasic.ByteToHexString(response))); } } else { if (response[0] == 0x06) { return(OperateResult.CreateSuccessResult(new byte[0])); } else { byte[] buffer = new byte[response.Length - 9]; Array.Copy(response, 6, buffer, 0, buffer.Length); return(new OperateResult <byte[]>(BitConverter.ToUInt16(SoftBasic.AsciiBytesToBytes(buffer), 0), "Data:" + SoftBasic.ByteToHexString(response))); } } } catch (Exception ex) { return(new OperateResult <byte[]>(ex.Message)); } }
/// <summary> /// 向寄存器中写入指定长度的字符串,超出截断,不够补0,编码格式为ASCII /// </summary> /// <param name="address">要写入的数据地址</param> /// <param name="value">要写入的实际数据</param> /// <param name="length">指定的字符串长度,必须大于0</param> /// <returns>返回写入结果</returns> public OperateResult Write(string address, string value, int length) { byte[] temp = ByteTransform.TransByte(value, Encoding.ASCII); temp = SoftBasic.ArrayExpandToLength(temp, length); return(Write(address, temp)); }
/// <summary> /// 用户账户验证的后台端 /// </summary> private void ThreadCheckAccount() { //定义委托 Action <string> message_show = delegate(string message) { label_status.Text = message; }; Action start_update = delegate { //需要该exe支持,否则将无法是实现自动版本控制 string update_file_name = Application.StartupPath + @"\软件自动更新.exe"; try { System.Diagnostics.Process.Start(update_file_name); Environment.Exit(0);//退出系统 } catch { MessageBox.Show("更新程序启动失败,请检查文件是否丢失,联系管理员获取。"); } }; Action thread_finish = delegate { UISettings(true); }; //延时 Thread.Sleep(200); //请求指令头数据,该数据需要更具实际情况更改 OperateResultString result = UserClient.Net_simplify_client.ReadFromServer(CommonLibrary.CommonHeadCode.SimplifyHeadCode.维护检查); if (result.IsSuccess) { byte[] temp = Encoding.Unicode.GetBytes(result.Content); //例如返回结果为1说明允许登录,0则说明服务器处于维护中,并将信息显示 if (result.Content != "1") { if (IsHandleCreated) { Invoke(message_show, result.Content.Substring(1)); } if (IsHandleCreated) { Invoke(thread_finish); } return; } } else { //访问失败 if (IsHandleCreated) { Invoke(message_show, result.Message); } if (IsHandleCreated) { Invoke(thread_finish); } return; } //检查账户 if (IsHandleCreated) { Invoke(message_show, "正在检查账户..."); } else { return; } //延时 Thread.Sleep(200); //=================================================================================== // 根据实际情况校验,选择数据库校验或是将用户名密码发至服务器校验 // 以下展示了服务器校验的方法,如您需要数据库校验,请删除下面并改成SQL访问验证的方式 //包装数据 JObject json = new JObject { { UserAccount.UserNameText, new Newtonsoft.Json.Linq.JValue(textBox_userName.Text) }, { UserAccount.PasswordText, new Newtonsoft.Json.Linq.JValue(textBox_password.Text) } }; result = UserClient.Net_simplify_client.ReadFromServer(CommonLibrary.CommonHeadCode.SimplifyHeadCode.账户检查, json.ToString()); if (result.IsSuccess) { //服务器应该返回账户的信息 UserAccount account = JObject.Parse(result.Content).ToObject <UserAccount>(); if (!account.LoginEnable) { //不允许登录 if (IsHandleCreated) { Invoke(message_show, account.ForbidMessage); } if (IsHandleCreated) { Invoke(thread_finish); } return; } UserClient.UserAccount = account; } else { //访问失败 if (IsHandleCreated) { Invoke(message_show, result.Message); } if (IsHandleCreated) { Invoke(thread_finish); } return; } //登录成功,进行保存用户名称和密码 UserClient.JsonSettings.LoginName = textBox_userName.Text; UserClient.JsonSettings.Password = checkBox_remeber.Checked ? textBox_password.Text : ""; UserClient.JsonSettings.LoginTime = DateTime.Now; UserClient.JsonSettings.SaveToFile(); //版本验证 if (IsHandleCreated) { Invoke(message_show, "正在验证版本..."); } else { return; } //延时 Thread.Sleep(200); result = UserClient.Net_simplify_client.ReadFromServer(CommonLibrary.CommonHeadCode.SimplifyHeadCode.更新检查); if (result.IsSuccess) { //服务器应该返回服务器的版本号 SystemVersion sv = new SystemVersion(result.Content); //系统账户跳过低版本检测 if (UserClient.UserAccount.UserName != "admin") { if (UserClient.CurrentVersion != sv) { //保存新版本信息 UserClient.JsonSettings.IsNewVersionRunning = true; UserClient.JsonSettings.SaveToFile(); //和当前系统版本号不一致,启动更新 if (IsHandleCreated) { Invoke(start_update); } return; } } else { if (UserClient.CurrentVersion < sv) { //保存新版本信息 UserClient.JsonSettings.IsNewVersionRunning = true; UserClient.JsonSettings.SaveToFile(); //和当前系统版本号不一致,启动更新 if (IsHandleCreated) { Invoke(start_update); } return; } } } else { //访问失败 if (IsHandleCreated) { Invoke(message_show, result.Message); } if (IsHandleCreated) { Invoke(thread_finish); } return; } //================================================================================ //验证结束后,根据需要是否下载服务器的数据,或是等到进入主窗口下载也可以 //如果有参数决定主窗口的显示方式,那么必要在下面向服务器请求数据 //以下展示了初始化参数的功能 if (IsHandleCreated) { Invoke(message_show, "正在下载参数..."); } else { return; } //延时 Thread.Sleep(200); result = UserClient.Net_simplify_client.ReadFromServer(CommonLibrary.CommonHeadCode.SimplifyHeadCode.参数下载); if (result.IsSuccess) { //服务器返回初始化的数据,此处进行数据的提取,有可能包含了多个数据 json = Newtonsoft.Json.Linq.JObject.Parse(result.Content); //例如公告数据 UserClient.Announcement = SoftBasic.GetValueFromJsonObject(json, nameof(UserClient.Announcement), ""); } else { //访问失败 if (IsHandleCreated) { Invoke(message_show, result.Message); } if (IsHandleCreated) { Invoke(thread_finish); } return; } //启动主窗口 if (IsHandleCreated) { Invoke(new Action(() => { DialogResult = DialogResult.OK; return; })); } }
private string TransBoolArrayToString(bool[] array) { return(SoftBasic.ArrayFormat(array.Select(m => m ? 1 : 0).ToArray( )).Replace(",", "")); }
/// <summary> /// bool数组变量转化缓存数据 /// </summary> /// <param name="values">等待转化的数组</param> /// <returns>buffer数据</returns> public virtual byte[] TransByte( bool[] values ) { if (values == null) return null; return SoftBasic.BoolArrayToByte( values ); }
/// <summary> /// 校验读取返回数据状态 /// </summary> /// <param name="ack"></param> /// <returns></returns> private OperateResult CheckPlcReadResponse(byte[] ack) { if (ack.Length == 0) { return(new OperateResult(StringResources.Language.MelsecFxReceiveZore)); } if (ack[0] == 0x45) { return(new OperateResult(StringResources.Language.MelsecFxAckWrong + " Actual: " + SoftBasic.ByteToHexString(ack, ' '))); } if ((ack[ack.Length - 1] != 0x0A) && (ack[ack.Length - 2] != 0x0D)) { return(new OperateResult(StringResources.Language.MelsecFxAckWrong + " Actual: " + SoftBasic.ByteToHexString(ack, ' '))); } return(OperateResult.CreateSuccessResult()); }
public void ModbusTcpUnitTest( ) { ModbusTcpNet modbus = new ModbusTcpNet("127.0.0.1", 502, 1); if (!modbus.ConnectServer( ).IsSuccess) { Console.WriteLine("无法连接modbus,将跳过单元测试。等待网络正常时,再进行测试"); return; } // 开始单元测试,从coil类型开始测试 string address = "1200"; bool[] boolTmp = new bool[] { true, true, false, true, false, true, false }; Assert.IsTrue(modbus.WriteCoil(address, true).IsSuccess); Assert.IsTrue(modbus.ReadCoil(address).Content == true); Assert.IsTrue(modbus.WriteCoil(address, boolTmp).IsSuccess); bool[] readBool = modbus.ReadCoil(address, (ushort)boolTmp.Length).Content; for (int i = 0; i < boolTmp.Length; i++) { Assert.IsTrue(readBool[i] == boolTmp[i]); } address = "300"; // short类型 Assert.IsTrue(modbus.Write(address, (short)12345).IsSuccess); Assert.IsTrue(modbus.ReadInt16(address).Content == 12345); short[] shortTmp = new short[] { 123, 423, -124, 5313, 2361 }; Assert.IsTrue(modbus.Write(address, shortTmp).IsSuccess); short[] readShort = modbus.ReadInt16(address, (ushort)shortTmp.Length).Content; for (int i = 0; i < readShort.Length; i++) { Assert.IsTrue(readShort[i] == shortTmp[i]); } // ushort类型 Assert.IsTrue(modbus.Write(address, (ushort)51234).IsSuccess); Assert.IsTrue(modbus.ReadUInt16(address).Content == 51234); ushort[] ushortTmp = new ushort[] { 5, 231, 12354, 5313, 12352 }; Assert.IsTrue(modbus.Write(address, ushortTmp).IsSuccess); ushort[] readUShort = modbus.ReadUInt16(address, (ushort)ushortTmp.Length).Content; for (int i = 0; i < ushortTmp.Length; i++) { Assert.IsTrue(readUShort[i] == ushortTmp[i]); } // int类型 Assert.IsTrue(modbus.Write(address, 12342323).IsSuccess); Assert.IsTrue(modbus.ReadInt32(address).Content == 12342323); int[] intTmp = new int[] { 123812512, 123534, 976124, -1286742 }; Assert.IsTrue(modbus.Write(address, intTmp).IsSuccess); int[] readint = modbus.ReadInt32(address, (ushort)intTmp.Length).Content; for (int i = 0; i < intTmp.Length; i++) { Assert.IsTrue(readint[i] == intTmp[i]); } // uint类型 Assert.IsTrue(modbus.Write(address, (uint)416123237).IsSuccess); Assert.IsTrue(modbus.ReadUInt32(address).Content == (uint)416123237); uint[] uintTmp = new uint[] { 81623123, 91712749, 91273123, 123, 21242, 5324 }; Assert.IsTrue(modbus.Write(address, uintTmp).IsSuccess); uint[] readuint = modbus.ReadUInt32(address, (ushort)uintTmp.Length).Content; for (int i = 0; i < uintTmp.Length; i++) { Assert.IsTrue(readuint[i] == uintTmp[i]); } // float类型 Assert.IsTrue(modbus.Write(address, 123.45f).IsSuccess); Assert.IsTrue(modbus.ReadFloat(address).Content == 123.45f); float[] floatTmp = new float[] { 123, 5343, 1.45f, 563.3f, 586.2f }; Assert.IsTrue(modbus.Write(address, floatTmp).IsSuccess); float[] readFloat = modbus.ReadFloat(address, (ushort)floatTmp.Length).Content; for (int i = 0; i < readFloat.Length; i++) { Assert.IsTrue(floatTmp[i] == readFloat[i]); } // double类型 Assert.IsTrue(modbus.Write(address, 1234.5434d).IsSuccess); Assert.IsTrue(modbus.ReadDouble(address).Content == 1234.5434d); double[] doubleTmp = new double[] { 1.4213d, 1223d, 452.5342d, 231.3443d }; Assert.IsTrue(modbus.Write(address, doubleTmp).IsSuccess); double[] readDouble = modbus.ReadDouble(address, (ushort)doubleTmp.Length).Content; for (int i = 0; i < doubleTmp.Length; i++) { Assert.IsTrue(readDouble[i] == doubleTmp[i]); } // long类型 Assert.IsTrue(modbus.Write(address, 123617231235123L).IsSuccess); Assert.IsTrue(modbus.ReadInt64(address).Content == 123617231235123L); long[] longTmp = new long[] { 12312313123L, 1234L, 412323812368L, 1237182361238123 }; Assert.IsTrue(modbus.Write(address, longTmp).IsSuccess); long[] readLong = modbus.ReadInt64(address, (ushort)longTmp.Length).Content; for (int i = 0; i < longTmp.Length; i++) { Assert.IsTrue(readLong[i] == longTmp[i]); } // ulong类型 Assert.IsTrue(modbus.Write(address, 1283823681236123UL).IsSuccess); Assert.IsTrue(modbus.ReadUInt64(address).Content == 1283823681236123UL); ulong[] ulongTmp = new ulong[] { 21316UL, 1231239127323UL, 1238612361283123UL }; Assert.IsTrue(modbus.Write(address, ulongTmp).IsSuccess); ulong[] readULong = modbus.ReadUInt64(address, (ushort)ulongTmp.Length).Content; for (int i = 0; i < readULong.Length; i++) { Assert.IsTrue(readULong[i] == ulongTmp[i]); } // string类型 Assert.IsTrue(modbus.Write(address, "123123").IsSuccess); Assert.IsTrue(modbus.ReadString(address, 3).Content == "123123"); // byte类型 byte[] byteTmp = new byte[] { 0x4F, 0x12, 0x72, 0xA7, 0x54, 0xB8 }; Assert.IsTrue(modbus.Write(address, byteTmp).IsSuccess); Assert.IsTrue(SoftBasic.IsTwoBytesEquel(modbus.Read(address, 3).Content, byteTmp)); modbus.ConnectClose( ); }
/// <summary> /// 生成位写入的数据报文信息,该报文可直接用于发送串口给PLC /// </summary> /// <param name="address">地址信息,每个地址存在一定的范围,需要谨慎传入数据。举例:M10,S10,X5,Y10,C10,T10</param> /// <param name="value"><c>True</c>或是<c>False</c></param> /// <returns>带报文信息的结果对象</returns> public static OperateResult <byte[]> BuildWriteBoolPacket(string address, bool value) { var analysis = FxAnalysisAddress(address); if (!analysis.IsSuccess) { return(OperateResult.CreateFailedResult <byte[]>(analysis)); } // 二次运算起始地址偏移量,根据类型的不同,地址的计算方式不同 ushort startAddress = analysis.Content2; if (analysis.Content1 == MelsecMcDataType.M) { if (startAddress >= 8000) { startAddress = (ushort)(startAddress - 8000 + 0x0F00); } else { startAddress = (ushort)(startAddress + 0x0800); } } else if (analysis.Content1 == MelsecMcDataType.S) { startAddress = (ushort)(startAddress + 0x0000); } else if (analysis.Content1 == MelsecMcDataType.X) { startAddress = (ushort)(startAddress + 0x0400); } else if (analysis.Content1 == MelsecMcDataType.Y) { startAddress = (ushort)(startAddress + 0x0500); } else if (analysis.Content1 == MelsecMcDataType.CS) { startAddress += (ushort)(startAddress + 0x01C0); } else if (analysis.Content1 == MelsecMcDataType.CC) { startAddress += (ushort)(startAddress + 0x03C0); } else if (analysis.Content1 == MelsecMcDataType.CN) { startAddress += (ushort)(startAddress + 0x0E00); } else if (analysis.Content1 == MelsecMcDataType.TS) { startAddress += (ushort)(startAddress + 0x00C0); } else if (analysis.Content1 == MelsecMcDataType.TC) { startAddress += (ushort)(startAddress + 0x02C0); } else if (analysis.Content1 == MelsecMcDataType.TN) { startAddress += (ushort)(startAddress + 0x0600); } else { return(new OperateResult <byte[]>(StringResources.Language.MelsecCurrentTypeNotSupportedBitOperate)); } byte[] _PLCCommand = new byte[9]; _PLCCommand[0] = 0x02; // STX _PLCCommand[1] = value ? (byte)0x37 : (byte)0x38; // Read _PLCCommand[2] = SoftBasic.BuildAsciiBytesFrom(startAddress)[2]; // 偏移地址 _PLCCommand[3] = SoftBasic.BuildAsciiBytesFrom(startAddress)[3]; _PLCCommand[4] = SoftBasic.BuildAsciiBytesFrom(startAddress)[0]; _PLCCommand[5] = SoftBasic.BuildAsciiBytesFrom(startAddress)[1]; _PLCCommand[6] = 0x03; // ETX MelsecHelper.FxCalculateCRC(_PLCCommand).CopyTo(_PLCCommand, 7); // CRC return(OperateResult.CreateSuccessResult(_PLCCommand)); }
private OperateResult CheckPlcWriteResponse(byte[] ack) { if (ack.Length == 0) { return(new OperateResult(StringResources.Language.MelsecFxReceiveZore)); } if (ack[0] == 0x15) { return(new OperateResult(StringResources.Language.MelsecFxAckNagative + " Actual: " + SoftBasic.ByteToHexString(ack, ' '))); } if (ack[0] != 0x06) { return(new OperateResult(StringResources.Language.MelsecFxAckWrong + ack[0] + " Actual: " + SoftBasic.ByteToHexString(ack, ' '))); } return(OperateResult.CreateSuccessResult( )); }
/// <summary> /// 向PLC中字软元件写入指定长度的字符串,超出截断,不够补0,编码格式为Unicode /// </summary> /// <param name="address">要写入的数据地址</param> /// <param name="value">要写入的实际数据</param> /// <param name="length">指定的字符串长度,必须大于0</param> /// <returns>返回读取结果</returns> public OperateResult WriteUnicodeString(string address, string value, int length) { byte[] temp = Encoding.Unicode.GetBytes(value); temp = SoftBasic.ArrayExpandToLength(temp, length * 2); return(Write(address, temp)); }
private void pictureBox_UserPortrait_Click(object sender, EventArgs e) { // UserPortrait.ChangePortrait(LoadLargeProtrait,UnloadLargeProtrait); using (FormPortraitSelect fps = new FormPortraitSelect()) { if (fps.ShowDialog() == DialogResult.OK) { string FileSavePath = Application.StartupPath + @"\Portrait\" + UserClient.UserAccount.UserName; string path300 = FileSavePath + @"\" + PortraitSupport.LargePortrait; string path32 = FileSavePath + @"\" + PortraitSupport.SmallPortrait; Bitmap bitmap300 = fps.GetSpecifiedSizeImage(300); Bitmap bitmap32 = fps.GetSpecifiedSizeImage(32); try { bitmap300.Save(path300, System.Drawing.Imaging.ImageFormat.Png); bitmap32.Save(path32, System.Drawing.Imaging.ImageFormat.Png); bitmap32.Dispose(); bitmap300.Dispose(); } catch (Exception ex) { // 文件被占用的时候无法进行覆盖 UserClient.LogNet?.WriteException("头像保存失败!", ex); MessageBox.Show("头像保存失败,原因:" + ex.Message); // 加载回旧的文件 pictureBox_UserPortrait.Load(path300); return; } // 传送服务器 using (FormFileOperate ffo = new FormFileOperate( UserClient.Net_File_Client, new string[] { path300, path32 }, "Files", "Portrait", UserClient.UserAccount.UserName)) { ffo.ShowDialog(); } ThreadPool.QueueUserWorkItem(new WaitCallback(obj => { // 上传文件MD5码 string SmallPortraitMD5 = ""; string LargePortraitMD5 = ""; try { SmallPortraitMD5 = SoftBasic.CalculateFileMD5(path32); LargePortraitMD5 = SoftBasic.CalculateFileMD5(path300); } catch (Exception ex) { UserClient.LogNet.WriteException("获取文件MD5码失败:", ex); MessageBox.Show("文件信息确认失败,请重新上传!"); return; } JObject json = new JObject { { UserAccount.UserNameText, new JValue(UserClient.UserAccount.UserName) }, { UserAccount.SmallPortraitText, new JValue(SmallPortraitMD5) }, { UserAccount.LargePortraitText, new JValue(LargePortraitMD5) } }; OperateResult <string> result = UserClient.Net_simplify_client.ReadFromServer( CommonHeadCode.SimplifyHeadCode.头像MD5, json.ToString()); if (result.IsSuccess) { if (result.Content.Substring(0, 2) == "成功") { UserClient.UserAccount.SmallPortraitMD5 = SmallPortraitMD5; UserClient.UserAccount.LargePortraitMD5 = LargePortraitMD5; } else { MessageBox.Show("上传头像失败!原因:" + result.Content); } } else { MessageBox.Show("上传头像失败!原因:" + result.Message); } // 先显示信息 try { pictureBox_UserPortrait.Image = new Bitmap(new System.IO.MemoryStream(File.ReadAllBytes(path300))); } catch { } }), null ); } } }
private OperateResult <byte[]> ExtractActualData(byte[] response) { try { if (response[response.Length - 1] != 0x01) { return(new OperateResult <byte[]>(response[response.Length - 1], "Wrong: " + SoftBasic.ByteToHexString(response, ' '))); } int length = response[5] * 256 + response[6]; byte[] buffer = new byte[length]; Array.Copy(response, 7, buffer, 0, length); return(OperateResult.CreateSuccessResult(buffer)); } catch (Exception ex) { return(new OperateResult <byte[]>("Wrong:" + ex.Message + " Code:" + SoftBasic.ByteToHexString(response, ' '))); } }
private void ThreadPoolLoadLargePortrait(object obj) { // 先获取服务器端的MD5码 string fileServerMd5 = UserClient.UserAccount.LargePortraitMD5; if (string.IsNullOrEmpty(fileServerMd5)) { return; // 没有文件 } string fileName = Application.StartupPath + @"\Portrait\" + UserClient.UserAccount.UserName + @"\" + PortraitSupport.LargePortrait; if (File.Exists(fileName)) { bool loadSuccess = false; Invoke(new Action(() => { try { pictureBox_UserPortrait.Image = new Bitmap(new MemoryStream(File.ReadAllBytes(fileName))); loadSuccess = true; } catch { } })); if (!loadSuccess) { goto P1; // 加载不成功,直接重新下载 } // 计算md5 string md5 = string.Empty; try { md5 = SoftBasic.CalculateFileMD5(fileName); } catch { } if (md5 == UserClient.UserAccount.LargePortraitMD5) { return; } } P1: MemoryStream ms = new MemoryStream(); OperateResult result = UserClient.Net_File_Client.DownloadFile( PortraitSupport.LargePortrait, "Files", "Portrait", UserClient.UserAccount.UserName, null, ms ); if (result.IsSuccess) { try { if (IsHandleCreated) { Invoke(new Action(() => { // 下载完成 Bitmap bitmap = new Bitmap(ms); pictureBox_UserPortrait.Image = bitmap; bitmap.Save(fileName); })); } } catch { // 不知道什么原因 } } else { // 下载异常,丢弃 } ms.Dispose(); }
public void GetEnumFromStringTest( ) { System.IO.FileMode fileMode = SoftBasic.GetEnumFromString <System.IO.FileMode>("Append"); Assert.IsTrue(fileMode == System.IO.FileMode.Append); }
/// <summary> /// 从缓存中提取出bool数组结果 /// </summary> /// <param name="buffer">缓存数据</param> /// <param name="index">位的索引</param> /// <param name="length">bool长度</param> /// <returns>bool数组</returns> public bool[] TransBool(byte[] buffer, int index, int length) { byte[] tmp = new byte[length]; Array.Copy(buffer, index, tmp, 0, length); return(SoftBasic.ByteToBoolArray(tmp, length * 8)); }
/**************************************************************************************************** * * * 数据处理中心,同步信息中的所有的细节处理均要到此处来处理 * * ****************************************************************************************************/ /// <summary> /// A指令块,处理系统基础运行的消息 /// </summary> /// <param name="state">网络状态对象</param> /// <param name="customer">用户自定义的指令头</param> /// <param name="data">实际的数据</param> private void DataProcessingWithStartA(AsyncStateOne state, int customer, string data) { if (customer == CommonHeadCode.SimplifyHeadCode.维护检查) { net_simplify_server.SendMessage(state, customer, "1"); //UserServer.ServerSettings.Can_Account_Login ? "1" : "0" + //UserServer.ServerSettings.Account_Forbidden_Reason); } else if (customer == CommonHeadCode.SimplifyHeadCode.更新检查) { net_simplify_server.SendMessage(state, customer, UserServer.ServerSettings.SystemVersion.ToString()); } else if (customer == CommonHeadCode.SimplifyHeadCode.参数下载) { JObject json = new JObject { { nameof(UserServer.ServerSettings.Announcement), new JValue(UserServer.ServerSettings.Announcement) } }; net_simplify_server.SendMessage(state, customer, json.ToString()); } else if (customer == CommonHeadCode.SimplifyHeadCode.账户检查) { //此处使用的是组件自带的验证的方式,如果使用SQL数据库,另行验证 JObject json = JObject.Parse(data); //提取账户,密码 string name = SoftBasic.GetValueFromJsonObject(json, UserAccount.UserNameText, ""); string password = SoftBasic.GetValueFromJsonObject(json, UserAccount.PasswordText, ""); net_simplify_server.SendMessage(state, customer, UserServer.ServerAccounts.CheckAccountJson( name, password, state.GetRemoteEndPoint().Address.ToString())); } else if (customer == CommonHeadCode.SimplifyHeadCode.更新公告) { UserServer.ServerSettings.Announcement = data; //通知所有客户端更新公告 net_socket_server.SendAllClients(customer, data); net_simplify_server.SendMessage(state, customer, "成功"); } else if (customer == CommonHeadCode.SimplifyHeadCode.获取账户) { //返回服务器的账户信息 net_simplify_server.SendMessage(state, customer, UserServer.ServerAccounts.GetAllAccountsJson()); } else if (customer == CommonHeadCode.SimplifyHeadCode.更细账户) { //更新服务器的账户信息 UserServer.ServerAccounts.LoadAllAccountsJson(data); net_simplify_server.SendMessage(state, customer, "成功"); } else if (customer == CommonHeadCode.SimplifyHeadCode.密码修改) { //更新服务器的账户密码,此处使用的是组件自带的验证的方式,如果使用SQL数据库,另行验证 JObject json = JObject.Parse(data); //提取账户,密码 string name = SoftBasic.GetValueFromJsonObject(json, UserAccount.UserNameText, ""); string password = SoftBasic.GetValueFromJsonObject(json, UserAccount.PasswordText, ""); UserServer.ServerAccounts.UpdatePassword(name, password); net_simplify_server.SendMessage(state, customer, "成功"); } else if (customer == CommonHeadCode.SimplifyHeadCode.更新版本) { try { UserServer.ServerSettings.SystemVersion = new SystemVersion(data); UserServer.ServerSettings.SaveToFile(); toolStripStatusLabel_version.Text = UserServer.ServerSettings.SystemVersion.ToString(); //记录数据 RuntimeLogHelper.SaveInformation($"更改了版本号:{data}"); net_simplify_server.SendMessage(state, customer, "1"); } catch { net_simplify_server.SendMessage(state, customer, "0"); } } else if (customer == CommonHeadCode.SimplifyHeadCode.注册账号) { bool result = UserServer.ServerAccounts.AddNewAccount(data); net_simplify_server.SendMessage(state, customer, result ? "1" : "0"); } else if (customer == CommonHeadCode.SimplifyHeadCode.请求文件) { net_simplify_server.SendMessage(state, customer, net_simple_file_server.ToJsonString()); } else if (customer == CommonHeadCode.SimplifyHeadCode.意见反馈) { AdviceLogHelper.SaveInformation(data); net_simplify_server.SendMessage(state, customer, "成功"); } else if (customer == CommonHeadCode.SimplifyHeadCode.群发消息) { net_socket_server.SendAllClients(CommonHeadCode.MultiNetHeadCode.弹窗新消息, data); net_simplify_server.SendMessage(state, customer, "成功"); } else { net_simplify_server.SendMessage(state, customer, data); } }
private byte[] ReadByCommand(byte[] command) { bool[] data = null; var data2 = new byte[20]; var result = new List <byte>(); Array.Copy(command, 0, data2, 0, 20); var resultLength = new List <byte>(); data2[9] = 0x11; data2[10] = 0x01; data2[12] = 0xA0; data2[13] = 0x11; data2[18] = 0x03; resultLength.Add(85); resultLength.Add(0); resultLength.Add(20); resultLength.Add(0); resultLength.Add(0x08); resultLength.Add(0x01); resultLength.Add(0); resultLength.Add(0); resultLength.Add(1); resultLength.Add(0); int NameLength = command[28]; int RequestCount = BitConverter.ToUInt16(command, 30 + NameLength); resultLength.AddRange(BitConverter.GetBytes((ushort)RequestCount)); string DeviceAddress = Encoding.ASCII.GetString(command, 30, NameLength); var StartAddress = DeviceAddress.Remove(0, 3); if (DeviceAddress.Substring(1, 2) == "MB" || DeviceAddress.Substring(1, 2) == "PB") { var dbint = RequestCount * 8; int startIndex = int.Parse(DeviceAddress.Remove(0, 3)); switch (DeviceAddress[1]) { case 'P': data = inputBuffer.GetBool(startIndex, dbint); break; case 'Q': data = outputBuffer.GetBool(startIndex, dbint); break; case 'M': data = memeryBuffer.GetBool(startIndex, dbint); break; case 'D': data = dbBlockBuffer.GetBool(startIndex, dbint); break; default: throw new Exception(StringResources.Language.NotSupportedDataType); } var data3 = SoftBasic.BoolArrayToByte(data); resultLength.AddRange(data3); data2[16] = (byte)resultLength.Count; result.AddRange(data2); result.AddRange(resultLength); return(result.ToArray()); } else { byte[] dataW = null; var subAddress = int.Parse(StartAddress) / 2; var sublength = RequestCount / 2; int startIndex = subAddress; switch (DeviceAddress[1]) { case 'P': dataW = inputBuffer.GetBytes(startIndex, (ushort)RequestCount); break; case 'Q': dataW = outputBuffer.GetBytes(startIndex, (ushort)RequestCount); break; case 'M': dataW = memeryBuffer.GetBytes(startIndex, (ushort)RequestCount); break; case 'D': dataW = dbBlockBuffer.GetBytes(startIndex, (ushort)RequestCount); break; default: throw new Exception(StringResources.Language.NotSupportedDataType); } resultLength.AddRange(dataW); data2[16] = (byte)resultLength.Count; result.AddRange(data2); result.AddRange(resultLength); return(result.ToArray()); } }
public async Task SiemensUnitTest( ) { SiemensS7Net plc = new SiemensS7Net(SiemensPLCS.S1200, "192.168.8.12"); // "192.168.8.12" if (!plc.ConnectServer( ).IsSuccess) { Console.WriteLine("无法连接PLC,将跳过单元测试。等待网络正常时,再进行测试"); return; } // 开始单元测试,从bool类型开始测试 string address = "M200.4"; Assert.IsTrue(plc.Write(address, true).IsSuccess); Assert.IsTrue(plc.ReadBool(address).Content == true); address = "M300"; // short类型 Assert.IsTrue(plc.Write(address, (short)12345).IsSuccess); Assert.IsTrue(plc.ReadInt16(address).Content == 12345); short[] shortTmp = new short[] { 123, 423, -124, 5313, 2361 }; Assert.IsTrue(plc.Write(address, shortTmp).IsSuccess); short[] readShort = plc.ReadInt16(address, (ushort)shortTmp.Length).Content; for (int i = 0; i < readShort.Length; i++) { Assert.IsTrue(readShort[i] == shortTmp[i]); } // 异步short类型 for (int j = 0; j < 100; j++) { Assert.IsTrue((await plc.WriteAsync(address, (short)12345)).IsSuccess); Assert.IsTrue((await plc.ReadInt16Async(address)).Content == 12345); Assert.IsTrue((await plc.WriteAsync(address, shortTmp)).IsSuccess); readShort = (await plc.ReadInt16Async(address, (ushort)shortTmp.Length)).Content; for (int i = 0; i < readShort.Length; i++) { Assert.IsTrue(readShort[i] == shortTmp[i]); } } // ushort类型 Assert.IsTrue(plc.Write(address, (ushort)51234).IsSuccess); Assert.IsTrue(plc.ReadUInt16(address).Content == 51234); ushort[] ushortTmp = new ushort[] { 5, 231, 12354, 5313, 12352 }; Assert.IsTrue(plc.Write(address, ushortTmp).IsSuccess); ushort[] readUShort = plc.ReadUInt16(address, (ushort)ushortTmp.Length).Content; for (int i = 0; i < ushortTmp.Length; i++) { Assert.IsTrue(readUShort[i] == ushortTmp[i]); } // int类型 Assert.IsTrue(plc.Write(address, 12342323).IsSuccess); Assert.IsTrue(plc.ReadInt32(address).Content == 12342323); int[] intTmp = new int[] { 123812512, 123534, 976124, -1286742 }; Assert.IsTrue(plc.Write(address, intTmp).IsSuccess); int[] readint = plc.ReadInt32(address, (ushort)intTmp.Length).Content; for (int i = 0; i < intTmp.Length; i++) { Assert.IsTrue(readint[i] == intTmp[i]); } // uint类型 Assert.IsTrue(plc.Write(address, (uint)416123237).IsSuccess); Assert.IsTrue(plc.ReadUInt32(address).Content == (uint)416123237); uint[] uintTmp = new uint[] { 81623123, 91712749, 91273123, 123, 21242, 5324 }; Assert.IsTrue(plc.Write(address, uintTmp).IsSuccess); uint[] readuint = plc.ReadUInt32(address, (ushort)uintTmp.Length).Content; for (int i = 0; i < uintTmp.Length; i++) { Assert.IsTrue(readuint[i] == uintTmp[i]); } // float类型 Assert.IsTrue(plc.Write(address, 123.45f).IsSuccess); Assert.IsTrue(plc.ReadFloat(address).Content == 123.45f); float[] floatTmp = new float[] { 123, 5343, 1.45f, 563.3f, 586.2f }; Assert.IsTrue(plc.Write(address, floatTmp).IsSuccess); float[] readFloat = plc.ReadFloat(address, (ushort)floatTmp.Length).Content; for (int i = 0; i < readFloat.Length; i++) { Assert.IsTrue(floatTmp[i] == readFloat[i]); } // double类型 Assert.IsTrue(plc.Write(address, 1234.5434d).IsSuccess); Assert.IsTrue(plc.ReadDouble(address).Content == 1234.5434d); double[] doubleTmp = new double[] { 1.4213d, 1223d, 452.5342d, 231.3443d }; Assert.IsTrue(plc.Write(address, doubleTmp).IsSuccess); double[] readDouble = plc.ReadDouble(address, (ushort)doubleTmp.Length).Content; for (int i = 0; i < doubleTmp.Length; i++) { Assert.IsTrue(readDouble[i] == doubleTmp[i]); } // long类型 Assert.IsTrue(plc.Write(address, 123617231235123L).IsSuccess); Assert.IsTrue(plc.ReadInt64(address).Content == 123617231235123L); long[] longTmp = new long[] { 12312313123L, 1234L, 412323812368L, 1237182361238123 }; Assert.IsTrue(plc.Write(address, longTmp).IsSuccess); long[] readLong = plc.ReadInt64(address, (ushort)longTmp.Length).Content; for (int i = 0; i < longTmp.Length; i++) { Assert.IsTrue(readLong[i] == longTmp[i]); } // ulong类型 Assert.IsTrue(plc.Write(address, 1283823681236123UL).IsSuccess); Assert.IsTrue(plc.ReadUInt64(address).Content == 1283823681236123UL); ulong[] ulongTmp = new ulong[] { 21316UL, 1231239127323UL, 1238612361283123UL }; Assert.IsTrue(plc.Write(address, ulongTmp).IsSuccess); ulong[] readULong = plc.ReadUInt64(address, (ushort)ulongTmp.Length).Content; for (int i = 0; i < readULong.Length; i++) { Assert.IsTrue(readULong[i] == ulongTmp[i]); } // string类型 Assert.IsTrue(plc.Write(address, "123123").IsSuccess); Assert.IsTrue(plc.ReadString(address).Content == "123123"); // 中文,编码可以自定义 Assert.IsTrue(plc.Write(address, "测试信息123", Encoding.Unicode).IsSuccess); Assert.IsTrue(plc.ReadString(address, 14, Encoding.Unicode).Content == "测试信息123"); // byte类型 byte[] byteTmp = new byte[] { 0x4F, 0x12, 0x72, 0xA7, 0x54, 0xB8 }; Assert.IsTrue(plc.Write(address, byteTmp).IsSuccess); Assert.IsTrue(SoftBasic.IsTwoBytesEquel(plc.Read(address, 6).Content, byteTmp)); // 批量写入测试 short[] shortValues = new short[50]; for (int i = 0; i < 50; i++) { shortValues[i] = (short)(i * 5 - 3); } Assert.IsTrue(plc.Write("M300", shortValues).IsSuccess); string[] addresses = new string[50]; ushort[] lengths = new ushort[50]; for (int i = 0; i < 50; i++) { addresses[i] = "M" + (i * 2 + 300); lengths[i] = 2; } OperateResult <byte[]> readBytes = plc.Read(addresses, lengths); Assert.IsTrue(readBytes.IsSuccess); Assert.IsTrue(readBytes.Content.Length == 100); for (int i = 0; i < 50; i++) { short shortTmp1 = plc.ByteTransform.TransInt16(readBytes.Content, i * 2); Assert.IsTrue(shortValues[i] == shortTmp1); } // 大数据写入测试 Assert.IsTrue(plc.Write("M100", (short)12345).IsSuccess); Assert.IsTrue(plc.Write("M500", (short)12345).IsSuccess); Assert.IsTrue(plc.Write("M800", (short)12345).IsSuccess); OperateResult <short[]> readBatchResult = plc.ReadInt16("M100", 351); Assert.IsTrue(readBatchResult.IsSuccess); Assert.IsTrue(readBatchResult.Content[0] == 12345); Assert.IsTrue(readBatchResult.Content[200] == 12345); Assert.IsTrue(readBatchResult.Content[350] == 12345); plc.ConnectClose( ); }
private byte[] ReadFromModbusCore(byte[] packet) { List <byte> command = new List <byte>(); command.Clear(); var StartAddress = string.Empty; var station = Encoding.ASCII.GetString(packet, 1, 2); var Read = Encoding.ASCII.GetString(packet, 3, 3); var nameLength = Encoding.ASCII.GetString(packet, 6, 2); var DeviceAddress = Encoding.ASCII.GetString(packet, 8, int.Parse(nameLength)); var size = Encoding.ASCII.GetString(packet, 8 + int.Parse(nameLength), 2); //===================================================================================== // Read Response if (Read.Substring(0, 2) == "rS") { command.Add(0x06); // ENQ command.AddRange(SoftBasic.BuildAsciiBytesFrom(byte.Parse(station))); command.Add(0x72); // command r command.Add(0x53); // command type: SB command.Add(0x42); command.AddRange(Encoding.ASCII.GetBytes("01")); StartAddress = DeviceAddress.Remove(0, 3); bool[] data; string txtValue; switch (DeviceAddress.Substring(1, 2)) { case "MB": case "PB": var dbint = Convert.ToInt32(size, 16) * 8; int startIndex = int.Parse(StartAddress); switch (DeviceAddress[1]) { case 'P': data = inputBuffer.GetBool(startIndex, dbint); break; case 'Q': data = outputBuffer.GetBool(startIndex, dbint); break; case 'M': data = memeryBuffer.GetBool(startIndex, dbint); break; case 'D': data = dbBlockBuffer.GetBool(startIndex, dbint); break; default: throw new Exception(StringResources.Language.NotSupportedDataType); } var data3 = SoftBasic.BoolArrayToByte(data); txtValue = GetValStr(data3, 0, Convert.ToInt32(size, 16)); command.AddRange(SoftBasic.BuildAsciiBytesFrom((byte)data3.Length)); command.AddRange(SoftBasic.BytesToAsciiBytes(data3)); command.Add(0x03); // ETX int sum1 = 0; for (int i = 0; i < command.Count; i++) { sum1 += command[i]; } command.AddRange(SoftBasic.BuildAsciiBytesFrom((byte)sum1)); break; case "DB": case "TB": var RequestCount = Convert.ToInt32(size, 16); byte[] dataW; var startIndexW = int.Parse(StartAddress); switch (DeviceAddress[1]) { case 'P': dataW = inputBuffer.GetBytes(startIndexW, (ushort)RequestCount); break; case 'Q': dataW = outputBuffer.GetBytes(startIndexW, (ushort)RequestCount); break; case 'M': dataW = memeryBuffer.GetBytes(startIndexW, (ushort)RequestCount); break; case 'D': dataW = dbBlockBuffer.GetBytes(startIndexW, (ushort)RequestCount); break; default: throw new Exception(StringResources.Language.NotSupportedDataType); } txtValue = GetValStr(dataW, 0, Convert.ToInt32(size, 16)); command.AddRange(SoftBasic.BuildAsciiBytesFrom((byte)dataW.Length)); command.AddRange(SoftBasic.BytesToAsciiBytes(dataW)); command.Add(0x03); // ETX int sum = 0; for (int i = 0; i < command.Count; i++) { sum += command[i]; } command.AddRange(SoftBasic.BuildAsciiBytesFrom((byte)sum)); break; } return(command.ToArray()); } else { StartAddress = DeviceAddress.Remove(0, 3); command.Add(0x06); // ENQ command.AddRange(SoftBasic.BuildAsciiBytesFrom(byte.Parse(station))); command.Add(0x77); // command w command.Add(0x53); // command type: SB command.Add(0x42); command.Add(0x03); // EOT string Value; if (Read.Substring(0, 3) == "WSS") { //nameLength = packet.Substring(8, 1); //DeviceAddress = packet.Substring(9, Convert.ToInt16(nameLength)); //AddressLength = packet.Substring(9 + Convert.ToInt16(nameLength), 1); nameLength = Encoding.ASCII.GetString(packet, 8, 2); DeviceAddress = Encoding.ASCII.GetString(packet, 10, int.Parse(nameLength)); Value = Encoding.ASCII.GetString(packet, 10 + int.Parse(nameLength), 2); } else { //Value = Encoding.ASCII.GetString(packet, 10 + int.Parse(nameLength), int.Parse(size)); Value = Encoding.ASCII.GetString(packet, 8 + int.Parse(nameLength) + int.Parse(size), int.Parse(size) * 2); var wdArys = HexToBytes(Value); } var startIndex = CheckAddress(StartAddress); switch (DeviceAddress.Substring(1, 2)) { case "MX": // Bit X Value = Encoding.ASCII.GetString(packet, 8 + int.Parse(nameLength) + int.Parse(size), int.Parse(size)); switch (DeviceAddress[1]) { //case 'M': inputBuffer.SetBool(value, startIndex); break; //case 'M': outputBuffer.SetBool(value, startIndex); break; case 'M': memeryBuffer.SetBool(Value == "01" ? true : false, startIndex); break; case 'D': dbBlockBuffer.SetBool(Value == "01" ? true : false, startIndex); break; default: throw new Exception(StringResources.Language.NotSupportedDataType); } return(command.ToArray()); case "DW": //Word Value = Encoding.ASCII.GetString(packet, 8 + int.Parse(nameLength) + int.Parse(size), int.Parse(size) * 2); var wdArys = HexToBytes(Value); switch (DeviceAddress[1]) { case 'C': inputBuffer.SetBytes(wdArys, startIndex); break; case 'T': outputBuffer.SetBytes(wdArys, startIndex); break; case 'M': memeryBuffer.SetBytes(wdArys, startIndex); break; case 'D': dbBlockBuffer.SetBytes(wdArys, startIndex); break; default: throw new Exception(StringResources.Language.NotSupportedDataType); } return(command.ToArray()); case "DD": //DWord break; case "DL": //LWord break; default: return(null); } } return(command.ToArray()); }
/// <summary> /// 批量读取bool类型数据,支持的类型为X,Y,S,T,C,具体的地址范围取决于PLC的类型 /// </summary> /// <param name="address">地址信息,比如X10,Y17,注意X,Y的地址是8进制的</param> /// <param name="length">读取的长度</param> /// <returns>读取结果信息</returns> public override OperateResult <bool[]> ReadBool(string address, ushort length) { OperateResult <byte[]> operateResult = MelsecFxLinksOverTcp.BuildReadCommand(station, address, length, isBool: true, sumCheck, watiingTime); if (!operateResult.IsSuccess) { return(OperateResult.CreateFailedResult <bool[]>(operateResult)); } OperateResult <byte[]> operateResult2 = ReadBase(operateResult.Content); if (!operateResult2.IsSuccess) { return(OperateResult.CreateFailedResult <bool[]>(operateResult2)); } if (operateResult2.Content[0] != 2) { return(new OperateResult <bool[]>(operateResult2.Content[0], "Read Faild:" + SoftBasic.ByteToHexString(operateResult2.Content, ' '))); } byte[] array = new byte[length]; Array.Copy(operateResult2.Content, 5, array, 0, length); return(OperateResult.CreateSuccessResult(array.Select((byte m) => m == 49).ToArray())); }
private byte[] ReadByCommand(byte[] command) { if (command[2] == 0x01) { // 位读取 ushort length = ByteTransform.TransUInt16(command, 8); int startIndex = (command[6] * 65536 + command[5] * 256 + command[4]); if (command[7] == MelsecMcDataType.M.DataCode) { byte[] buffer = mBuffer.GetBytes(startIndex, length); return(MelsecHelper.TransBoolArrayToByteData(buffer)); } else if (command[7] == MelsecMcDataType.X.DataCode) { byte[] buffer = xBuffer.GetBytes(startIndex, length); return(MelsecHelper.TransBoolArrayToByteData(buffer)); } else if (command[7] == MelsecMcDataType.Y.DataCode) { byte[] buffer = yBuffer.GetBytes(startIndex, length); return(MelsecHelper.TransBoolArrayToByteData(buffer)); } else { throw new Exception(StringResources.Language.NotSupportedDataType); } } else { // 字读取 ushort length = ByteTransform.TransUInt16(command, 8); int startIndex = (command[6] * 65536 + command[5] * 256 + command[4]); if (command[7] == MelsecMcDataType.M.DataCode) { bool[] buffer = mBuffer.GetBytes(startIndex, length * 16).Select(m => m != 0x00).ToArray( ); return(SoftBasic.BoolArrayToByte(buffer)); } else if (command[7] == MelsecMcDataType.X.DataCode) { bool[] buffer = xBuffer.GetBytes(startIndex, length * 16).Select(m => m != 0x00).ToArray( ); return(SoftBasic.BoolArrayToByte(buffer)); } else if (command[7] == MelsecMcDataType.Y.DataCode) { bool[] buffer = yBuffer.GetBytes(startIndex, length * 16).Select(m => m != 0x00).ToArray( ); return(SoftBasic.BoolArrayToByte(buffer)); } else if (command[7] == MelsecMcDataType.D.DataCode) { return(dBuffer.GetBytes(startIndex * 2, length * 2)); } else if (command[7] == MelsecMcDataType.W.DataCode) { return(wBuffer.GetBytes(startIndex * 2, length * 2)); } else { throw new Exception(StringResources.Language.NotSupportedDataType); } } }
/// <summary> /// 向寄存器中写入bool数组,返回值说明,比如你写入M100,那么data[0]对应M100.0 /// </summary> /// <param name="address">要写入的数据地址</param> /// <param name="values">要写入的实际数据,长度为8的倍数</param> /// <returns>返回写入结果</returns> public OperateResult Write(string address, bool[] values) { return(Write(address, SoftBasic.BoolArrayToByte(values))); }
private byte[] WriteByMessage(byte[] command) { if (command[2] == 0x01) { // 位写入 ushort length = ByteTransform.TransUInt16(command, 8); int startIndex = (command[6] * 65536 + command[5] * 256 + command[4]); if (command[7] == MelsecMcDataType.M.DataCode) { byte[] buffer = MelsecMcNet.ExtractActualData(SoftBasic.BytesArrayRemoveBegin(command, 10), true).Content; mBuffer.SetBytes(buffer.Take(length).ToArray( ), startIndex); return(new byte[0]); } else if (command[7] == MelsecMcDataType.X.DataCode) { byte[] buffer = MelsecMcNet.ExtractActualData(SoftBasic.BytesArrayRemoveBegin(command, 10), true).Content; xBuffer.SetBytes(buffer.Take(length).ToArray( ), startIndex); return(new byte[0]); } else if (command[7] == MelsecMcDataType.Y.DataCode) { byte[] buffer = MelsecMcNet.ExtractActualData(SoftBasic.BytesArrayRemoveBegin(command, 10), true).Content; yBuffer.SetBytes(buffer.Take(length).ToArray( ), startIndex); return(new byte[0]); } else { throw new Exception(StringResources.Language.NotSupportedDataType); } } else { // 字写入 ushort length = ByteTransform.TransUInt16(command, 8); int startIndex = (command[6] * 65536 + command[5] * 256 + command[4]); if (command[7] == MelsecMcDataType.M.DataCode) { byte[] buffer = SoftBasic.ByteToBoolArray(SoftBasic.BytesArrayRemoveBegin(command, 10)).Select(m => m ? (byte)1 : (byte)0).ToArray( ); mBuffer.SetBytes(buffer, startIndex); return(new byte[0]); } else if (command[7] == MelsecMcDataType.X.DataCode) { byte[] buffer = SoftBasic.ByteToBoolArray(SoftBasic.BytesArrayRemoveBegin(command, 10)).Select(m => m ? (byte)1 : (byte)0).ToArray( ); xBuffer.SetBytes(buffer, startIndex); return(new byte[0]); } else if (command[7] == MelsecMcDataType.Y.DataCode) { byte[] buffer = SoftBasic.ByteToBoolArray(SoftBasic.BytesArrayRemoveBegin(command, 10)).Select(m => m ? (byte)1 : (byte)0).ToArray( ); yBuffer.SetBytes(buffer, startIndex); return(new byte[0]); } else if (command[7] == MelsecMcDataType.D.DataCode) { dBuffer.SetBytes(SoftBasic.BytesArrayRemoveBegin(command, 10), startIndex * 2); return(new byte[0]); } else if (command[7] == MelsecMcDataType.W.DataCode) { wBuffer.SetBytes(SoftBasic.BytesArrayRemoveBegin(command, 10), startIndex * 2); return(new byte[0]); } else { throw new Exception(StringResources.Language.NotSupportedDataType); } } }
/// <summary> /// 检查当前的头子节信息的令牌是否是正确的 /// </summary> /// <param name="headBytes">头子节数据</param> /// <returns>令牌是验证成功</returns> protected bool CheckRemoteToken(byte[] headBytes) { return(SoftBasic.IsByteTokenEquel(headBytes, Token)); }
/// <summary> /// 系统统一的登录模型 /// </summary> /// <param name="message_show">信息提示方法</param> /// <param name="start_update">启动更新方法</param> /// <param name="thread_finish">线程结束后的复原方法</param> /// <param name="userName">用户名</param> /// <param name="password">密码</param> /// <param name="remember">是否记住登录密码</param> /// <param name="clientType">客户端登录类型</param> /// <returns></returns> public static bool AccountLoginServer( Action <string> message_show, Action start_update, Action thread_finish, string userName, string password, bool remember, string clientType ) { message_show.Invoke("正在维护检查..."); Thread.Sleep(200); // 请求指令头数据,该数据需要更具实际情况更改 OperateResult <string> result = UserClient.Net_simplify_client.ReadFromServer(CommonLibrary.CommonHeadCode.SimplifyHeadCode.维护检查); if (result.IsSuccess) { byte[] temp = Encoding.Unicode.GetBytes(result.Content); // 例如返回结果为1说明允许登录,0则说明服务器处于维护中,并将信息显示 if (result.Content != "1") { message_show.Invoke(result.Content.Substring(1)); thread_finish.Invoke(); return(false); } } else { // 访问失败 message_show.Invoke(result.Message); thread_finish.Invoke(); return(false); } // 检查账户 message_show.Invoke("正在检查账户..."); // 延时 Thread.Sleep(200); //======================================================================================= // // 根据实际情况校验,选择数据库校验或是将用户名密码发至服务器校验 // 以下展示了服务器校验的方法,如您需要数据库校验,请删除下面并改成SQL访问验证的方式 // 如果还有其他数据一并传到服务器进行验证的,都在下面进行数据包装 // 包装数据 JObject json = new JObject { { UserAccount.UserNameText, new JValue(userName) }, // 用户名 { UserAccount.PasswordText, new JValue(password) }, // 密码 { UserAccount.LoginWayText, new JValue(clientType) }, // 登录方式 { UserAccount.DeviceUniqueID, new JValue(UserClient.JsonSettings.SystemInfo) }, // 客户端唯一ID { UserAccount.FrameworkVersion, new JValue(SoftBasic.FrameworkVersion.ToString()) } // 客户端框架版本 }; result = UserClient.Net_simplify_client.ReadFromServer(CommonHeadCode.SimplifyHeadCode.账户检查, json.ToString()); if (result.IsSuccess) { // 服务器应该返回账户的信息 UserAccount account = JObject.Parse(result.Content).ToObject <UserAccount>(); if (!account.LoginEnable) { // 不允许登录 message_show.Invoke(account.ForbidMessage); thread_finish.Invoke(); return(false); } UserClient.UserAccount = account; } else { // 访问失败 message_show.Invoke(result.Message); thread_finish.Invoke(); return(false); } // 登录成功,进行保存用户名称和密码 UserClient.JsonSettings.LoginName = userName; UserClient.JsonSettings.Password = remember ? password : ""; UserClient.JsonSettings.LoginTime = DateTime.Now; UserClient.JsonSettings.SaveToFile(); // 版本验证 message_show.Invoke("正在验证版本..."); // 延时 Thread.Sleep(200); result = UserClient.Net_simplify_client.ReadFromServer(CommonHeadCode.SimplifyHeadCode.更新检查); if (result.IsSuccess) { // 服务器应该返回服务器的版本号 SystemVersion sv = new SystemVersion(result.Content); // 系统账户跳过低版本检测,该做法存在一定的风险,需要开发者仔细确认安全隐患 if (UserClient.UserAccount.UserName != "admin") { if (UserClient.CurrentVersion != sv) { // 保存新版本信息 UserClient.JsonSettings.IsNewVersionRunning = true; UserClient.JsonSettings.SaveToFile(); // 和当前系统版本号不一致,启动更新 start_update.Invoke(); return(false); } } else { // 超级管理员可以使用超前版本进行登录 if (UserClient.CurrentVersion < sv) { // 保存新版本信息 UserClient.JsonSettings.IsNewVersionRunning = true; UserClient.JsonSettings.SaveToFile(); // 和当前系统版本号不一致,启动更新 start_update.Invoke(); return(false); } } } else { // 访问失败 message_show.Invoke(result.Message); thread_finish.Invoke(); return(false); } // // 验证结束后,根据需要是否下载服务器的数据,或是等到进入主窗口下载也可以 // 如果有参数决定主窗口的显示方式,那么必要在下面向服务器请求数据 // 以下展示了初始化参数的功能 message_show.Invoke("正在下载参数..."); // 延时 Thread.Sleep(200); result = UserClient.Net_simplify_client.ReadFromServer(CommonLibrary.CommonHeadCode.SimplifyHeadCode.参数下载); if (result.IsSuccess) { // 服务器返回初始化的数据,此处进行数据的提取,有可能包含了多个数据 json = JObject.Parse(result.Content); // 例如公告数据和分厂数据 UserClient.Announcement = SoftBasic.GetValueFromJsonObject(json, nameof(UserClient.Announcement), ""); if (json[nameof(UserClient.SystemFactories)] != null) { UserClient.SystemFactories = json[nameof(UserClient.SystemFactories)].ToObject <List <string> >(); } CommonLibrary.DataBaseSupport.SqlServerSupport.ConnectionString = SoftBasic.GetValueFromJsonObject(json, nameof(ServerSettings.SqlServerStr), ""); } else { // 访问失败 message_show.Invoke(result.Message); thread_finish.Invoke(); return(false); } return(true); }