using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading.Tasks; namespace Epost.Common { public class LightHelper { private Socket tcpAsyCl; private static bool _connected = false; private byte[] tcpAsyClBuffer = new byte[2048]; private static ushort _timeout = 500; private const byte fctWriteMultipleCoils = 15; public bool connect(string ip, ushort port) { try { if ((tcpAsyCl != null) && (tcpAsyCl.Connected)) { _connected = true; return _connected; } else { IPAddress _ip; if (IPAddress.TryParse(ip, out _ip) == false) { IPHostEntry hst = Dns.GetHostEntry(ip); ip = hst.AddressList[0].ToString(); } // ---------------------------------------------------------------- if (5020 == port) { //M281-A 的5020端口为单一连接,所有仅能创建异步通信对象; // Connect asynchronous client tcpAsyCl = new Socket(IPAddress.Parse(ip).AddressFamily, SocketType.Stream, ProtocolType.Tcp); tcpAsyCl.Connect(new IPEndPoint(IPAddress.Parse(ip), port)); tcpAsyCl.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, _timeout); tcpAsyCl.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, _timeout); tcpAsyCl.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.NoDelay, 1); } else { // Connect asynchronous client tcpAsyCl = new Socket(IPAddress.Parse(ip).AddressFamily, SocketType.Stream, ProtocolType.Tcp); tcpAsyCl.Connect(new IPEndPoint(IPAddress.Parse(ip), port)); tcpAsyCl.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, _timeout); tcpAsyCl.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, _timeout); tcpAsyCl.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.NoDelay, 1); //---------------------------------------------------------------- // Connect synchronous client //tcpSynCl = new Socket(IPAddress.Parse(ip).AddressFamily, SocketType.Stream, ProtocolType.Tcp); //tcpSynCl.Connect(new IPEndPoint(IPAddress.Parse(ip), port)); //tcpSynCl.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, _timeout); //tcpSynCl.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, _timeout); //tcpSynCl.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.NoDelay, 1); } _connected = true; return _connected; } } catch (System.IO.IOException error) { _connected = false; return _connected; throw (error); } } private void WriteAsyncData(byte[] write_data, ushort id) { if ((tcpAsyCl != null) && (tcpAsyCl.Connected)) { try { tcpAsyCl.BeginSend(write_data, 0, write_data.Length, SocketFlags.None, new AsyncCallback(OnSend), null); tcpAsyCl.BeginReceive(tcpAsyClBuffer, 0, tcpAsyClBuffer.Length, SocketFlags.None, new AsyncCallback(OnReceive), tcpAsyCl); } catch (SystemException error) { // CallException(id, write_data[7], excExceptionConnectionLost); } } else { } } private void OnSend(System.IAsyncResult result) { if (result.IsCompleted == false) { } } private void OnReceive(System.IAsyncResult result) { } public byte[] GetData(int num,int show) { bool[] bits = new bool[num]; byte[] data = new Byte[num]; int[] word = new int[num]; bits[0] = Convert.ToBoolean(Convert.ToByte(show)); int numBytes = (byte)(num / 8 + (num % 8 > 0 ? 1 : 0)); data = new Byte[numBytes]; BitArray bitArray = new BitArray(bits); bitArray.CopyTo(data, 0); return data; } //多线圈 public void WriteMultipleCoils(ushort id, ushort startAddress, ushort numBits, byte[] values, byte SlaveID) { byte numBytes = Convert.ToByte(values.Length); byte[] data; data = CreateWriteHeader(id, startAddress, numBits, (byte)(numBytes + 2), fctWriteMultipleCoils, SlaveID); Array.Copy(values, 0, data, 13, numBytes); WriteAsyncData(data, id); } //单线圈 /// Write single coil in slave asynchronous. The result is given in the response function. /// Unique id that marks the transaction. In asynchonous mode this id is given to the callback function. /// Address from where the data read begins. /// Specifys if the coil should be switched on or off. /// ID of modbus slave. public void WriteSingleCoils(ushort id, ushort startAddress, bool OnOff, byte SlaveID) { byte[] data; data = CreateWriteHeader(id, startAddress, 1, 1, 5, SlaveID); if (OnOff == true) data[10] = 255; else data[10] = 0; WriteAsyncData(data, id); } public void Dispose() { if (tcpAsyCl != null) { if (tcpAsyCl.Connected) { try { tcpAsyCl.Shutdown(SocketShutdown.Both); } catch { } tcpAsyCl.Close(); } tcpAsyCl = null; } } private byte[] CreateWriteHeader(ushort id, ushort startAddress, ushort numData, ushort numBytes, byte function, byte SlaveID) { byte[] data = new byte[numBytes + 11]; byte[] _id = BitConverter.GetBytes((short)id); data[0] = _id[0]; // Slave id high byte data[1] = _id[1]; // Slave id low byte+ byte[] _size = BitConverter.GetBytes((short)IPAddress.HostToNetworkOrder((short)(5 + numBytes))); data[4] = _size[0]; // Complete message size in bytes data[5] = _size[1]; // Complete message size in bytes data[6] = SlaveID; // Slave address //必须设置为"1": 2012.04-24 覃发光; data[7] = function; // Function code byte[] _adr = BitConverter.GetBytes((short)IPAddress.HostToNetworkOrder((short)startAddress)); data[8] = _adr[0]; // Start address data[9] = _adr[1]; // Start address if (function >= fctWriteMultipleCoils) { byte[] _cnt = BitConverter.GetBytes((short)IPAddress.HostToNetworkOrder((short)numData)); data[10] = _cnt[0]; // Number of bytes data[11] = _cnt[1]; // Number of bytes data[12] = (byte)(numBytes - 2); } return data; } } }