190 lines
7.8 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|