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