Files
T-DAS/Common/LightHelper.cs
2023-01-13 15:30:20 +08:00

190 lines
7.8 KiB
C#

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);
}
//单线圈
/// <summary>Write single coil in slave asynchronous. The result is given in the response function.</summary>
/// <param name="id">Unique id that marks the transaction. In asynchonous mode this id is given to the callback function.</param>
/// <param name="startAddress">Address from where the data read begins.</param>
/// <param name="OnOff">Specifys if the coil should be switched on or off.</param>
/// <param name="SlaveID">ID of modbus slave.</param>
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;
}
}
}