| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616 |
- using System;
- using System.Collections.Generic;
- using System.Net;
- using System.Net.Sockets;
- using System.Text;
- using Curtain.Framework.Utils;
- using HslCommunication;
- using HslCommunication.Profinet.Melsec;
- namespace PCLCommunication
- {
- public class MelsecA1EAscii : IDisposable
- {
- private bool _always = false;
- [NonSerialized]
- public Socket _socket = null;
- //[NonSerialized]
- private StringBuilder _command = null;
- //[NonSerialized]
- private string _receive = null;
- [NonSerialized]
- public MelsecA1EAsciiNet _MelsecA1EAsciiNet = null;
- public string Command
- {
- get
- {
- return this._command?.ToString();
- }
- }
- public string Receive
- {
- get
- {
- return this._receive;
- }
- }
- /// <summary>
- /// 是:长连接;否:短连接
- /// </summary>
- public bool Always
- {
- get
- {
- return this._always;
- }
- set
- {
- this._always = value;
- if (!this._always)
- {
- this.CloseSocket();
- }
- else
- {
- this.ConnectSocket();
- }
- }
- }
- ///// <summary>
- ///// Socket
- ///// </summary>
- //[System.Xml.Serialization.XmlIgnore]
- //[System.Web.Script.Serialization.ScriptIgnore]
- //public Socket Socket
- //{
- // get
- // {
- // return this._socket;
- // }
- //}
- /// <summary>
- /// 通信超时(3s)
- /// </summary>
- public int Timeout
- {
- get;
- set;
- } = 10000;//3000;
- /// <summary>
- /// 关闭连接
- /// </summary>
- public void CloseSocket()
- {
- try
- {
- //_socket?.Close();
- this._MelsecA1EAsciiNet?.ConnectClose();
- }
- catch (Exception ex)
- {
- // TODO log
- string j = JsonUtil.FromObject(this);
- LogOut.Error(null, ex, j);
- //throw ex;
- }
- finally
- {
- //_socket = null;
- //this._MelsecA1EAsciiNet = null;
- }
- }
- /// <summary>
- /// 打开连接
- /// </summary>
- public void ConnectSocket()
- {
- try
- {
- //_socket?.Close();
- //this._socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
- //this._socket.Connect(IPAddress.Parse(this.IP), this.Port);
- //this._socket.SendTimeout = this.Timeout;
- //this._socket.ReceiveTimeout = this.Timeout;
- this._MelsecA1EAsciiNet?.ConnectClose();
- if (this._MelsecA1EAsciiNet == null)
- {
- this._MelsecA1EAsciiNet = new MelsecA1EAsciiNet(this.IP, this.Port);
- }
- this._MelsecA1EAsciiNet.ConnectTimeOut = this.Timeout;
- this._MelsecA1EAsciiNet.ReceiveTimeOut = this.Timeout;
- this._MelsecA1EAsciiNet.ConnectServer();
- }
- catch (Exception ex)
- {
- // TODO log
- throw ex;
- }
- finally
- {
- if (!this._always)
- {
- CloseSocket();
- }
- }
- }
- /// <summary>
- /// PLC IP
- /// </summary>
- public string IP
- {
- get
- {
- return this._MelsecA1EAsciiNet.IpAddress;
- }
- set
- {
- this._MelsecA1EAsciiNet.IpAddress = value;
- }
- }
- /// <summary>
- /// PLC Port
- /// </summary>
- public int Port
- {
- get
- {
- return this._MelsecA1EAsciiNet.Port;
- }
- set
- {
- this._MelsecA1EAsciiNet.Port = value;
- }
- }
- public MelsecA1EAscii(string ip, int port)
- {
- _MelsecA1EAsciiNet = new MelsecA1EAsciiNet(ip, port);
- this._MelsecA1EAsciiNet.ConnectTimeOut = this.Timeout;
- this._MelsecA1EAsciiNet.ReceiveTimeOut = this.Timeout;
- //this.IP = ip;
- //this.Port = port;
- }
- /// <summary>
- /// 读取PLC
- /// </summary>
- /// <param name="type"></param>
- /// <param name="begin"></param>
- /// <param name="length"></param>
- /// <returns></returns>
- public string GetHexData(string type, int begin, int length)
- {
- this._command = null;
- this._receive = null;
- string mm = "\r\ntype:" + type + "\r\nbegin:" + begin + "\r\nlength:" + length;
- try
- {
- //if (this._socket == null || !this._always)
- //{
- // this.CloseSocket();
- // this._socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
- // this._socket.Connect(IPAddress.Parse(this.IP), this.Port);
- // this._socket.SendTimeout = this.Timeout;
- // this._socket.ReceiveTimeout = this.Timeout;
- //}
- // 副标题: 01 【命令:字单位读取】
- // PC号: FF 【固定】
- // 监视定时器:00 0C 【3秒(单位250毫秒)】
- this._command = new StringBuilder("01FF000C");
- // 起始软元件编码 D100 => 4420 0000 0064
- // 软元件代码
- if (type.Length == 1)
- {
- this._command.Append(MelsecA1EAscii.GetHexAscii(type) + "20");
- }
- else
- {
- this._command.Append(MelsecA1EAscii.GetHexAscii(type));
- }
- // 软元件编码
- this._command.Append(begin.ToString("X8"));
- // 软元件点数
- this._command.Append(length.ToString("X2"));
- // 命令结束
- this._command.Append("00");
- byte[] cmdBytes = Encoding.ASCII.GetBytes(this._command.ToString());
- //int cmdResult = this._socket.Send(cmdBytes);
- //byte[] receiveBytes = new byte[length * 4 + 4];
- //int receiveResult = this._socket.Receive(receiveBytes);
- //this._receive = Encoding.ASCII.GetString(receiveBytes, 0, receiveResult);
- //if (!this._receive.StartsWith("8100"))
- //{
- // // TODO log ip port command receive
- // string j = JsonUtil.FromObject(this) + mm;
- // LogOut.Error(null, null, j);
- // return null;
- //}
- OperateResult<byte[]> result = this._MelsecA1EAsciiNet.ReadFromCoreServer(cmdBytes);
- if (result.IsSuccess)
- {
- this._receive = Encoding.ASCII.GetString(result.Content);
- if (!this._receive.StartsWith("8100"))
- {
- // TODO log ip port command receive
- string j = JsonUtil.FromObject(this) + mm;
- LogOut.Error(null, null, j);
- return null;
- }
- }
- else
- {
- // TODO log ip port command receive
- string j = JsonUtil.FromObject(this) + mm + "\r\nError:" + result.ToMessageShowString();
- LogOut.Error(null, null, j);
- return null;
- }
- //return receive.Substring(4);
- return this._receive;
- }
- catch (Exception ex)
- {
- // TODO log
- string j = JsonUtil.FromObject(this) + mm;
- LogOut.Error(null, ex, j);
- return null;
- }
- finally
- {
- if (!this._always)
- {
- this.CloseSocket();
- }
- }
- }
- /// <summary>
- /// 读取PLC
- /// </summary>
- /// <param name="type"></param>
- /// <param name="begin"></param>
- /// <param name="length"></param>
- /// <returns></returns>
- public byte[] GetByteData(string type, int begin, int length)
- {
- string mm = "\r\ntype:" + type + "\r\nbegin:" + begin + "\r\nlength:" + length;
- try
- {
- string str = this.GetHexData(type, begin, length);
- if (string.IsNullOrEmpty(str))
- {
- return null;
- }
- List<byte> list = new List<byte>();
- for (int i = 4; i < str.Length; i = i + 2)
- {
- list.Add(Convert.ToByte(str.Substring(i, 2), 16));
- }
- return list.ToArray();
- }
- catch (Exception ex)
- {
- // TODO log
- string j = JsonUtil.FromObject(this) + mm;
- LogOut.Error(null, ex, j);
- return null;
- }
- finally
- {
- }
- }
- /// <summary>
- /// 写入PLC
- /// </summary>
- /// <param name="type"></param>
- /// <param name="begin"></param>
- /// <param name="length"></param>
- /// <returns></returns>
- public bool SetData(string type, int begin, int length, string hexData)
- {
- this._command = null;
- this._receive = null;
- string mm = "\r\ntype:" + type + "\r\nbegin:" + begin + "\r\nlength:" + length + "\r\nhexData:" + hexData;
- try
- {
- //if (this._socket == null || !this._always)
- //{
- // this.CloseSocket();
- // this._socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
- // this._socket.Connect(IPAddress.Parse(this.IP), this.Port);
- // this._socket.SendTimeout = this.Timeout;
- // this._socket.ReceiveTimeout = this.Timeout;
- //}
- // 副标题: 03 【命令:字单位写入】
- // PC号: FF 【固定】
- // 监视定时器:00 0C 【3秒(单位250毫秒)】
- this._command = new StringBuilder("03FF000C");
- // 起始软元件编码 D100 => 4420 0000 0064
- // 软元件代码
- if (type.Length == 1)
- {
- this._command.Append(MelsecA1EAscii.GetHexAscii(type) + "20");
- }
- else
- {
- this._command.Append(MelsecA1EAscii.GetHexAscii(type));
- }
- // 软元件编码
- this._command.Append(begin.ToString("X8"));
- // 软元件点数
- this._command.Append(length.ToString("X2"));
- // 命令结束
- this._command.Append("00");
- // 写入补齐
- int count = length * 4;
- if (hexData.Length < count)
- {
- hexData = hexData.PadRight(count, '0');
- }
- //if (hexData.Length > count)
- //{
- // hexData = hexData.Substring(0, count);
- //}
- // 写入
- this._command.Append(hexData);
- byte[] cmdBytes = Encoding.ASCII.GetBytes(this._command.ToString());
- //int cmdResult = this._socket.Send(cmdBytes);
- //byte[] receiveBytes = new byte[1024];
- //int receiveResult = this._socket.Receive(receiveBytes);
- //this._receive = Encoding.ASCII.GetString(receiveBytes, 0, receiveResult);
- //if (!this._receive.StartsWith("8300"))
- //{
- // // TODO log ip port command receive
- // string j = JsonUtil.FromObject(this) + mm;
- // LogOut.Error(null, null, j);
- // return false;
- //}
- OperateResult<byte[]> result = this._MelsecA1EAsciiNet.ReadFromCoreServer(cmdBytes);
- if (result.IsSuccess)
- {
- this._receive = Encoding.ASCII.GetString(result.Content);
- if (!this._receive.StartsWith("8300"))
- {
- // TODO log ip port command receive
- string j = JsonUtil.FromObject(this) + mm;
- LogOut.Error(null, null, j);
- return false;
- }
- }
- else
- {
- // TODO log ip port command receive
- string j = JsonUtil.FromObject(this) + mm + "\r\nError:" + result.ToMessageShowString();
- LogOut.Error(null, null, j);
- return false;
- }
- return true;
- }
- catch (Exception ex)
- {
- // TODO log
- string j = JsonUtil.FromObject(this) + mm;
- LogOut.Error(null, ex, j);
- return false;
- }
- finally
- {
- if (!this._always)
- {
- this.CloseSocket();
- }
- }
- }
- /// <summary>
- /// 写入PLC
- /// </summary>
- /// <param name="type"></param>
- /// <param name="begin"></param>
- /// <param name="hexData"></param>
- /// <returns></returns>
- public bool SetData(string type, int begin, string hexData)
- {
- int length = (int)(hexData.Length / 4.0 + 0.5);
- return this.SetData(type, begin, length, hexData);
- }
- /// <summary>
- /// 写入PLC
- /// </summary>
- /// <param name="type"></param>
- /// <param name="begin"></param>
- /// <returns></returns>
- public bool SetData(string type, int begin, byte[] data)
- {
- try
- {
- StringBuilder sb = new StringBuilder();
- foreach (byte item in data)
- {
- sb.Append(item.ToString("X2"));
- }
- return SetData(type, begin, sb.ToString());
- }
- catch (Exception ex)
- {
- // TODO log
- LogOut.Error(null, ex);
- return false;
- }
- finally
- {
- }
- }
- /// <summary>
- /// 写入PLC
- /// </summary>
- /// <param name="type"></param>
- /// <param name="begin"></param>
- /// <param name="length"></param>
- /// <returns></returns>
- public bool SetData(string type, int begin, int length, byte[] data)
- {
- try
- {
- StringBuilder sb = new StringBuilder();
- foreach (byte item in data)
- {
- sb.Append(item.ToString("X2"));
- }
- return SetData(type, begin, length, sb.ToString());
- }
- catch (Exception ex)
- {
- // TODO log
- LogOut.Error(null, ex);
- return false;
- }
- finally
- {
- if (!this._always)
- {
- this.CloseSocket();
- }
- }
- }
- public void Do(string command)
- {
- this._command = null;
- this._receive = null;
- try
- {
- //if (this._socket == null || !this._always)
- //{
- // this.CloseSocket();
- // this._socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
- // this._socket.Connect(IPAddress.Parse(this.IP), this.Port);
- // this._socket.SendTimeout = this.Timeout;
- // this._socket.ReceiveTimeout = this.Timeout;
- //}
- this._command = new StringBuilder(command);
- byte[] cmdBytes = Encoding.ASCII.GetBytes(command);
- //int cmdResult = this._socket.Send(cmdBytes);
- //byte[] receiveBytes = new byte[4096];
- //int receiveResult = this._socket.Receive(receiveBytes);
- //this._receive = Encoding.ASCII.GetString(receiveBytes, 0, receiveResult);
- OperateResult<byte[]> result = this._MelsecA1EAsciiNet.ReadFromCoreServer(cmdBytes);
- if (result.IsSuccess)
- {
- this._receive = Encoding.ASCII.GetString(result.Content);
- }
- else
- {
- // TODO log ip port command receive
- string j = JsonUtil.FromObject(this) + "\r\nError:" + result.ToMessageShowString();
- LogOut.Error(null, null, j);
- }
- }
- catch (Exception ex)
- {
- // TODO log
- string j = JsonUtil.FromObject(this);
- LogOut.Error(null, ex, j);
- }
- finally
- {
- if (!this._always)
- {
- this.CloseSocket();
- }
- }
- }
- /// <summary>
- /// 获取字符串对应的2进制Ascii码(字符=>命令)
- /// </summary>
- /// <param name="value"></param>
- /// <returns></returns>
- public static string GetHexAscii(string value)
- {
- if (string.IsNullOrEmpty(value))
- {
- return "";
- }
- byte[] bs = Encoding.ASCII.GetBytes(value);
- if (bs.Length > 1)
- {
- StringBuilder sb = new StringBuilder();
- foreach (byte item in bs)
- {
- sb.Append(item.ToString("X2"));
- }
- return sb.ToString();
- }
- else
- {
- return bs[0].ToString("X2");
- }
- }
- /// <summary>
- /// 获取2进制Ascii码对应的字符串(命令=>字符)
- /// </summary>
- /// <param name="value"></param>
- /// <returns></returns>
- public static string GetByHexAscii(string value)
- {
- if (string.IsNullOrWhiteSpace(value))
- {
- return null;
- }
- List<byte> list = new List<byte>();
- for (int i = 0; i < value.Length; i = i + 2)
- {
- list.Add(Convert.ToByte(value.Substring(i, 2), 16));
- }
- return Encoding.ASCII.GetString(list.ToArray());
- }
- /// <summary>
- /// 销毁
- /// </summary>
- public void Dispose()
- {
- try
- {
- this.CloseSocket();
- }
- catch
- {
- }
- }
- }
- }
|