using System; using System.Collections.Generic; using System.Text; using System.Text.RegularExpressions; namespace Curtain.Net.Sockets.PLC.Model { /// /// SocketModel /// public interface ISocketModel { /// /// 接收通信超时(毫秒) /// int ReceiveTimeout { get; } /// /// 发送通信超时(毫秒) /// int SendTimeout { get; } /// /// 响应报文-头长度 /// int HeadLength { get; } } /// /// PLC通信模型 /// public interface IClientModel : ISocketModel { #region /// /// 初始化Socket连接 /// /// void OnSocketConnect(PLCSocket socket); /// /// 根据响应报文-头,计算响应报文-文本长度 /// /// 报文 /// 响应报文-文本长度 int GetContentLength(PLCMessage m); /// /// 验证响应报文-头 /// /// 报文 /// 是否通过 bool CheckHead(PLCMessage m); /// /// 命令报文转换为发送字节 /// /// 命令报文 /// 发送字节 byte[] ToSendFromCommand(string command); /// /// 接收字节转换为响应报文 /// /// 接收字节 /// 响应报文 string ToResponseFromReceive(byte[] receive); #endregion #region Value /// /// 设定读取的数据值 /// /// /// void SetReadValueFromBytes(PLCMessage plc_m); #endregion #region ReadMessage /// /// 获取读取命令报文 /// /// /// /// /// PLCMessage GetReadMessage(char code, int number, int length = 1); /// /// 获取读取命令报文 /// /// /// /// /// PLCMessage GetReadMessage(string code, string number, int length = 1); /// /// 获取读取命令报文 /// /// /// /// PLCMessage GetReadMessage(string code, int length = 1); #endregion #region WriteMessage /// /// 获取写入命令报文 /// /// /// /// /// /// /// PLCMessage GetWriteMessage(char code, int number, TValue value, int length = 0); /// /// 获取写入命令报文 /// /// /// /// /// /// /// PLCMessage GetWriteMessage(string code, string number, TValue value, int length = 0); /// /// 获取写入命令报文 /// /// /// /// /// /// PLCMessage GetWriteMessage(string code, TValue value, int length = 0); /// /// 获取写入命令报文 /// /// /// /// /// /// /// PLCMessage GetWriteMessage(char code, int number, string value, Encoding encoding, int length = 0); /// /// 获取写入命令报文 /// /// /// /// /// /// /// PLCMessage GetWriteMessage(string code, string number, string value, Encoding encoding, int length = 0); /// /// 获取写入命令报文 /// /// /// /// /// /// PLCMessage GetWriteMessage(string code, string value, Encoding encoding, int length = 0); #endregion #region SendMessage /// /// 获取发送命令报文 /// /// /// PLCMessage GetSendMessage(string value); /// /// 获取发送命令报文 /// /// /// /// PLCMessage GetSendMessage(string value, Encoding encoding); #endregion } /// /// PLC通信模型 /// public abstract class ClientModel : IClientModel { #region factory private static readonly Dictionary _factory = new Dictionary(); /// /// 创建PLC通信模型 /// /// /// public static T CreateModel() where T: IClientModel, new() { System.Type t = typeof(T); if (_factory.ContainsKey(t)) { return (T)_factory[t]; } T tt = new T(); _factory.Add(t, tt); return tt; } #endregion #region client /// /// 接收通信超时(毫秒) /// public virtual int ReceiveTimeout => 3000; /// /// 发送通信超时(毫秒) /// public virtual int SendTimeout => 3000; /// /// 响应报文-头长度 /// public virtual int HeadLength => 0; /// /// 初始化Socket连接 /// /// public virtual void OnSocketConnect(PLCSocket socket) { } /// /// 根据响应报文-头,计算响应报文-文本长度 /// /// 报文 /// 响应报文-文本长度 public virtual int GetContentLength(PLCMessage m) { return 0; } /// /// 验证响应报文-头 /// /// 报文 /// 是否通过 public virtual bool CheckHead(PLCMessage m) { return false; } /// /// 命令报文转换为发送字节 /// /// 命令报文 /// 发送字节 public virtual byte[] ToSendFromCommand(string command) { return null; } /// /// 接收字节转换为响应报文 /// /// 接收字节 /// 响应报文 public virtual string ToResponseFromReceive(byte[] receive) { return null; } #endregion #region Value /// /// 设定读取的数据值 /// /// /// public virtual void SetReadValueFromBytes(PLCMessage plc_m) { throw new NotSupportedException(typeof(TValue).Name); } #endregion #region ReadMessage /// /// 获取读取命令报文 /// /// /// /// /// public virtual PLCMessage GetReadMessage(char code, int number, int length = 1) { return GetReadMessage(code.ToString(), number.ToString(), length); } /// /// 获取读取命令报文 /// /// /// /// /// public virtual PLCMessage GetReadMessage(string code, string number, int length = 1) { throw new NotSupportedException($"[{typeof(TValue).Name}][{code}{number}][{length}]"); } /// /// 获取读取命令报文 /// /// /// /// public virtual PLCMessage GetReadMessage(string code, int length = 1) { string strPatten = @"([a-zA-Z]+)([~a-zA-Z]+)"; Regex rex = new Regex(strPatten); MatchCollection matches = rex.Matches(code); if (matches.Count > 0) { return GetReadMessage(matches[0].Groups[0].Value, matches[0].Groups[1].Value, length); } throw new NotSupportedException($"[{typeof(TValue).Name}][{code}][{length}]"); } #endregion #region WriteMessage /// /// 获取写入命令报文 /// /// /// /// /// /// /// public virtual PLCMessage GetWriteMessage(char code, int number, TValue value, int length = 0) { return GetWriteMessage(code.ToString(), number.ToString(), value); } /// /// 获取写入命令报文 /// /// /// /// /// /// /// public virtual PLCMessage GetWriteMessage(string code, string number, TValue value, int length = 0) { throw new NotSupportedException($"[{typeof(TValue).Name}][{code}{number}][{value}]"); } /// /// 获取写入命令报文 /// /// /// /// /// /// public virtual PLCMessage GetWriteMessage(string code, TValue value, int length = 0) { string strPatten = @"([a-zA-Z]+)([~a-zA-Z]+)"; Regex rex = new Regex(strPatten); MatchCollection matches = rex.Matches(code); if (matches.Count > 0) { return GetWriteMessage(matches[0].Groups[0].Value, matches[0].Groups[1].Value, value); } throw new NotSupportedException($"{typeof(TValue).Name}[{code}]"); } /// /// 获取写入命令报文 /// /// /// /// /// /// /// public virtual PLCMessage GetWriteMessage(char code, int number, string value, Encoding encoding, int length = 0) { return GetWriteMessage(code.ToString(), number.ToString(), value, encoding); } /// /// 获取写入命令报文 /// /// /// /// /// /// /// public virtual PLCMessage GetWriteMessage(string code, string number, string value, Encoding encoding, int length = 0) { throw new NotSupportedException($"[{encoding.EncodingName}][{code}{number}][{value}]"); } /// /// 获取写入命令报文 /// /// /// /// /// /// public virtual PLCMessage GetWriteMessage(string code, string value, Encoding encoding, int length = 0) { string strPatten = @"([a-zA-Z]+)([~a-zA-Z]+)"; Regex rex = new Regex(strPatten); MatchCollection matches = rex.Matches(code); if (matches.Count > 0) { return GetWriteMessage(matches[0].Groups[0].Value, matches[0].Groups[1].Value, value, encoding); } throw new NotSupportedException($"[{encoding.EncodingName}][{code}][{value}]"); } #endregion #region SendMessage /// /// 获取发送命令报文 /// /// /// public virtual PLCMessage GetSendMessage(string value) { throw new NotSupportedException(); } /// /// 获取发送命令报文 /// /// /// /// public virtual PLCMessage GetSendMessage(string value, Encoding encoding) { throw new NotSupportedException(); } #endregion } ///// ///// ///// ///// //public abstract class PLCModel : PLCModel // where TModel : IPLCModel, new() //{ // /// // /// // /// // public ClientSocket ClientSocket // { // get; // internal set; // } //} /// /// 命令格式 /// public enum CommandFormatType { /// /// PLC命令格式 /// PLCCommand = 1, /// /// 起止符格式 /// StartStopChar = 2, } /// /// 服务端模型 /// public interface IServerModel : ISocketModel { /// /// 命令格式 /// CommandFormatType FormatType { get; set; } /// /// 开始字符 /// char StartChar { get; set; } /// /// 结束字符 /// char StopChar { get; set; } /// /// 转义字符 /// char EscapeChar { get; set; } /// /// 根据响应报文-头,计算响应报文-文本长度 /// /// 报文 /// 响应报文-文本长度 int GetContentLength(ReceiveSession rs); /// /// 验证响应报文-头 /// /// 报文 /// 是否通过 bool CheckHead(ReceiveSession rs); /// /// 接收字节转换为命令 /// /// 接收字节 /// 响应报文 string ToCommandFromReceive(byte[] receive); /// /// 接收字节转换为报文头 /// /// 接收字节 /// 响应报文 string ToHeadFromReceive(byte[] receive); /// /// 接收字节转换为报文正文 /// /// 接收字节 /// 响应报文 string ToContentFromReceive(byte[] receive); /// /// 命令报文转换为发送字节 /// /// 命令报文 /// 发送字节 byte[] ToSendFromCommand(string command); } /// /// 服务端模型 /// public abstract class ServerModel : IServerModel { #region factory private static readonly Dictionary _factory = new Dictionary(); /// /// 创建服务端模型 /// /// /// public static T CreateModel() where T : IServerModel, new() { System.Type t = typeof(T); if (_factory.ContainsKey(t)) { return (T)_factory[t]; } T tt = new T(); _factory.Add(t, tt); return tt; } #endregion /// /// 命令格式 /// public virtual CommandFormatType FormatType { get; set; } = CommandFormatType.PLCCommand; /// /// 开始字符 /// public virtual char StartChar { get; set; } = '@'; /// /// 结束字符 /// public virtual char StopChar { get; set; } = '$'; /// /// 转义字符 /// public virtual char EscapeChar { get; set; } = '\\'; #region server /// /// 接收通信超时(毫秒) /// public virtual int ReceiveTimeout => 3000; /// /// 发送通信超时(毫秒) /// public virtual int SendTimeout => 3000; /// /// 响应报文-头长度 /// public abstract int HeadLength { get; } /// /// 根据响应报文-头,计算响应报文-文本长度 /// /// 报文 /// 响应报文-文本长度 public virtual int GetContentLength(ReceiveSession rs) { return -1; } /// /// 验证响应报文-头 /// /// 报文 /// 是否通过 public virtual bool CheckHead(ReceiveSession rs) { return false; } /// /// 验证命令头 /// /// /// public virtual bool CheckHeadChar(byte[] headBytes) { char[] s = System.Text.Encoding.ASCII.GetChars(headBytes); return (s[0] == this.StartChar); } /// /// 接收字节转换为命令 /// /// 接收字节 /// 响应报文 public virtual string ToCommandFromReceive(byte[] receive) { return null; } /// /// 接收字节转换为报文头 /// /// 接收字节 /// 响应报文 public virtual string ToHeadFromReceive(byte[] receive) { return null; } /// /// 接收字节转换为报文正文 /// /// 接收字节 /// 响应报文 public virtual string ToContentFromReceive(byte[] receive) { return null; } /// /// 命令报文转换为发送字节 /// /// 命令报文 /// 发送字节 public virtual byte[] ToSendFromCommand(string command) { return null; } #endregion } /// /// PLC地址信息 /// public interface IAddressData { } }