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
{
}
}