Commit f7630a88 顾剑亮

删除 AIOBOX - 副本.cs

1 个父辈 00438b6f
正在显示 1 个修改的文件 包含 0 行增加1149 行删除
using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Collections.Generic;
namespace Asa.IOModule
{
/// <summary>
/// AIOBOX操作类
/// </summary>
public class AIOBOX
{
private Socket _client; //客户端
private bool _loop;
private string _logPath; //日志的文件夹路径
private LogFile _log; //日志的类
private LogType _logType; //日志输出类型
private bool _frontInputOutput; //True:Input False:Output
private int countInput; //输入总数
private int countOutput; //输出总数
private int sleepInput; //自动读取DI间隔
private int sleepOutput; //自动读取DO间隔
private Box_Type _typeInput; //输入类型
private Box_Type _typeOutput; //输出类型
private byte[] _addressInput; //输入地址
private byte[] _addressOutput; //输出地址
private bool _autoReadInput; //自动读取DI
private bool _autoReadOutput; //自动读取DO
private bool _manualReadOutput; //手动读取DO
private bool _changeDI; //DI收到数据触发事件
private bool _changeDO; //DO收到数据触发事件
private bool _changeAI; //AI收到数据触发事件
private bool _changeAO; //AO收到数据触发事件
private Box_Sta[] _stateDI; //状态
private Box_Sta[] _stateDO; //状态
private int[] _valueAI; //模拟量
private int[] _valueAO; //模拟量
private System.Collections.Concurrent.ConcurrentQueue<ushort> _flag;
private System.Collections.Concurrent.ConcurrentQueue<byte[]> _send;
private System.Collections.Concurrent.ConcurrentQueue<byte[]> _receive;
private Thread tSend; //发送命令处理
private Thread tReceive; //接收信息处理
private Thread tListen; //监听网络
private Thread tTrigger; //触发DI、DO改变事件
private Thread tReadInput; //自动读取DI线程
private Thread tReadOutput; //自动读取DO线程
private Thread tFlag; //ModBusTCP标识
private UdpClient broadcastClient; //广播客户端
private IPEndPoint broadcastEndPoint; //广播远程节点
private byte[] broadcastBuffer; //远程返回数据
/// <summary>
/// 每条命令发送的间隔
/// 不能小于15,会出现IO接收不到的情况
/// 小于30时,会出现接收数据连包的情况
/// </summary>
private const int SEND_SLEEP = 30;
/// <summary>
/// ModBus端口
/// </summary>
public const int PORT = 502;
/// <summary>
/// 自动读取DI委托
/// </summary>
/// <param name="box">AIOBOX</param>
/// <param name="sta">所有DI状态</param>
public delegate void DIO_Changed(AIOBOX box, Box_Sta[] sta);
/// <summary>
/// 自动读取DI事件触发
/// </summary>
public event DIO_Changed DI_Changed_Event;
/// <summary>
/// 自动读取DO事件触发
/// </summary>
public event DIO_Changed DO_Changed_Event;
/// <summary>
/// 自动读取AI委托
/// </summary>
/// <param name="box">AIOBOX</param>
/// <param name="val">所有AI的值</param>
public delegate void AIO_Changed(AIOBOX box, int[] val);
/// <summary>
/// 自动读取AI事件触发
/// </summary>
public event AIO_Changed AI_Changed_Event;
/// <summary>
/// 自动读取AO事件触发
/// </summary>
public event AIO_Changed AO_Changed_Event;
/// <summary>
/// AIOBOX
/// </summary>
public AIOBOX()
{
_log = null;
_logPath = null;
_autoReadInput = false;
_autoReadOutput = false;
_manualReadOutput = false;
sleepInput = 100;
sleepOutput = 100;
}
/// <summary>
/// IP地址
/// </summary>
public string IP { set; get; } = "192.168.1.100";
/// <summary>
/// 是否连接
/// </summary>
public bool IsConn { get; private set; } = false;
/// <summary>
/// 错误信息
/// </summary>
public string ErrInfo { get; private set; } = "";
/// <summary>
/// 日志路径,连接前设置路径会自动保存日志
/// </summary>
/// <param name="path">文件夹路径</param>
/// <param name="type">输出类型</param>
public void LogPath(string path, LogType type)
{
_logPath = path;
_logType = type;
}
/// <summary>
/// 设置输入端
/// </summary>
/// <param name="type">类型</param>
/// <param name="count">数量</param>
public void SetInput(Box_Type type, int count)
{
_typeInput = type;
countInput = count;
_frontInputOutput = false;
}
/// <summary>
/// 设置输出端
/// </summary>
/// <param name="type">类型</param>
/// <param name="count">数量</param>
public void SetOutput(Box_Type type, int count)
{
_typeOutput = type;
countOutput = count;
_frontInputOutput = true;
}
/// <summary>
/// 自动获取IP地址,未连接前使用,必须在同一网段
/// </summary>
/// <param name="localIP">本地IP地址</param>
/// <returns></returns>
public bool AutoIP(string localIP)
{
try
{
IPEndPoint local = new IPEndPoint(IPAddress.Parse(localIP), 55654);
broadcastClient = new UdpClient(local);
broadcastBuffer = null;
Thread tTemp = new Thread(new ThreadStart(GetIP));
tTemp.Start();
broadcastEndPoint = new IPEndPoint(IPAddress.Parse("255.255.255.255"), 1024);
byte[] dgram = new byte[] { 0x05, 0x00, 0x07, 0x00, 0x00, 0xC1, 0x59 };
broadcastClient.Send(dgram, dgram.Length, broadcastEndPoint);
Thread.Sleep(1000);
tTemp.Abort();
broadcastClient.Close();
ErrInfo = "无法访问";
if (broadcastBuffer == null) return false;
if (broadcastBuffer[0] != 0x3B) return false;
byte[] buff = new byte[broadcastBuffer[7]];
Array.Copy(broadcastBuffer, 9, buff, 0, buff.Length);
IP = buff[buff.Length - 12] + "." + buff[buff.Length - 11] + "." + buff[buff.Length - 10] + "." + buff[buff.Length - 9];
ErrInfo = "OK";
return true;
}
catch (Exception ex)
{
ErrInfo = ex.Message;
return false;
}
}
/// <summary>
/// 检查IP地址
/// </summary>
/// <param name="ip"></param>
/// <returns></returns>
public bool CheckIP(string ip)
{
//IP合法
string pattern = @"^((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)$";
bool rtn = System.Text.RegularExpressions.Regex.IsMatch(ip, pattern);
if (!rtn)
{
ErrInfo = "非法的IP地址";
return false;
}
//Ping服务端
System.Net.NetworkInformation.Ping ping = new System.Net.NetworkInformation.Ping();
System.Net.NetworkInformation.PingReply result = ping.Send(ip, 1000);
ping.Dispose();
if (result.Status != System.Net.NetworkInformation.IPStatus.Success)
{
ErrInfo = "Ping " + ip + " 请求没有响应";
return false;
}
return true;
}
/// <summary>
/// 连接
/// </summary>
/// <returns></returns>
public bool Connect()
{
try
{
//初始化地址
InitAddr();
//检查IP地址
bool rtn = CheckIP(IP);
if (!rtn) return false;
_send = new System.Collections.Concurrent.ConcurrentQueue<byte[]>();
_receive = new System.Collections.Concurrent.ConcurrentQueue<byte[]>();
_flag = new System.Collections.Concurrent.ConcurrentQueue<ushort>();
//建立连接
_client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
_client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, 500);
_client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 500);
_client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.NoDelay, 1);
_client.Connect(IPAddress.Parse(IP), PORT);
Thread.Sleep(100); //需要等待一会才能获取连接状态
tFlag = new Thread(new ThreadStart(Flag));
tFlag.Start();
Thread.Sleep(10);
if (_logPath == null)
_log = null;
else
_log = new LogFile(_logPath, IP);
tSend = new Thread(new ThreadStart(Send));
tReceive = new Thread(new ThreadStart(Receive));
tListen = new Thread(new ThreadStart(Listen));
tTrigger = new Thread(new ThreadStart(TriggerDIO));
tReadInput = new Thread(new ThreadStart(AutoReadInput));
tReadOutput = new Thread(new ThreadStart(AutoReadOutput));
tListen.Start();
tTrigger.Start();
tSend.Start();
tReceive.Start();
tReadInput.Start();
tReadOutput.Start();
IsConn = true;
ErrInfo = "";
if (_log != null) _log.OutData("Connect OK");
return true;
}
catch (Exception ex)
{
IsConn = false;
ErrInfo = ex.Message;
if (_log != null) _log.OutError(ex.Message);
return false;
}
}
/// <summary>
/// 关闭连接
/// </summary>
public void Close()
{
IsConn = false;
if (tListen != null) tListen.Abort();
tListen = null;
if (tReadInput != null) tReadInput.Abort();
tReadInput = null;
if (tReadOutput != null) tReadOutput.Abort();
tReadOutput = null;
if (tTrigger != null) tTrigger.Abort();
tTrigger = null;
if (tSend != null) tSend.Abort();
tSend = null;
if (tReceive != null) tReceive.Abort();
tReceive = null;
if (tFlag != null) tFlag.Abort();
tFlag = null;
if (_client != null)
{
_client.Shutdown(SocketShutdown.Both);
_client.Close();
}
_client = null;
if (_log != null)
{
_log.OutData("Close OK");
_log.Close();
_log = null;
}
}
/// <summary>
/// 自动读取输入端并触发事件(主动上传数据 = 禁止)
/// </summary>
/// <param name="read">是否自动读取</param>
/// <param name="sleep">间隔,必须大于等于15ms</param>
public void AutoReadInput(bool read, int sleep)
{
if (countInput < 1)
_autoReadInput = false;
else if (sleep < 15)
_autoReadInput = false;
else if (read)
{
_autoReadInput = true;
sleepInput = sleep;
}
else
_autoReadInput = false;
}
/// <summary>
/// 自动读取输入端并触发事件(主动上传数据 = 使能)
/// </summary>
/// <param name="read">是否自动读取</param>
public void AutoReadInput(bool read)
{
if (countInput < 1)
_autoReadInput = false;
else if (read)
{
_autoReadInput = true;
sleepInput = 8000; //IO模块最大10s,避免超过时间,每8秒发送一次心跳包
}
else
_autoReadInput = false;
}
/// <summary>
/// 自动读取输出端,触发事件
/// </summary>
/// <param name="read">是否自动读取</param>
/// <param name="sleep">间隔,必须大于等于15ms</param>
public void AutoReadOutput(bool read, int sleep)
{
if (countOutput < 1)
{
_autoReadOutput = false;
sleepOutput = 100;
}
else if (sleep < 15)
{
_autoReadOutput = false;
sleepOutput = 100;
}
else if (read)
{
_autoReadOutput = true;
sleepOutput = sleep;
}
else
{
_autoReadOutput = false;
_manualReadOutput = true; //用于第一次连接的时候读取一次状态
sleepOutput = sleep;
}
}
/// <summary>
/// 相反状态(ON/OFF)
/// </summary>
/// <param name="sta"></param>
/// <returns></returns>
public Box_Sta ReverseStatus(Box_Sta sta)
{
return sta == Box_Sta.On ? Box_Sta.Off : Box_Sta.On;
}
/// <summary>
/// 相反状态(ON/OFF)
/// </summary>
/// <param name="sta"></param>
public void ReverseStatus(ref Box_Sta sta)
{
if (sta == Box_Sta.On)
sta = Box_Sta.Off;
else
sta = Box_Sta.On;
}
/// <summary>
/// 读取单个DI输入状态(ON/OFF)
/// </summary>
/// <param name="add">输入地址,从0开始</param>
/// <returns></returns>
public Box_Sta ReadDI(int add)
{
return _stateDI[add];
}
/// <summary>
/// 读取多个DI输入状态(ON/OFF)
/// </summary>
/// <param name="add">起始地址,从0开始</param>
/// <param name="count">数量</param>
/// <returns></returns>
public Box_Sta[] ReadDI(int add, int count)
{
Box_Sta[] sta = new Box_Sta[count];
Array.Copy(_stateDI, add, sta, 0, count);
return sta;
}
/// <summary>
/// 读取单个AI模拟量的值
/// </summary>
/// <param name="add">模拟量地址,从0开始</param>
/// <returns></returns>
public int ReadAI(int add)
{
return _valueAI[add];
}
/// <summary>
/// 读取多个AI模拟量的值
/// </summary>
/// <param name="add">起始地址,从0开始</param>
/// <param name="count">数量</param>
/// <returns></returns>
public int[] ReadAI(int add, int count)
{
int[] sta = new int[count];
Array.Copy(_valueAI, add, sta, 0, count);
return sta;
}
/// <summary>
/// 读取单个DO输出状态(ON/OFF)
/// </summary>
/// <param name="add">输出地址,从0开始</param>
/// <returns></returns>
public Box_Sta ReadDO(int add)
{
return _stateDO[add];
}
/// <summary>
/// 读取多个DO输出状态(ON/OFF)
/// </summary>
/// <param name="add">起始地址,从0开始</param>
/// <param name="count">数量</param>
/// <returns></returns>
public Box_Sta[] ReadDO(int add, int count)
{
Box_Sta[] sta = new Box_Sta[count];
Array.Copy(_stateDO, add, sta, 0, count);
return sta;
}
/// <summary>
/// 读取单个AO模拟量的值
/// </summary>
/// <param name="add">输出地址,从0开始</param>
/// <returns></returns>
public int ReadAO(int add)
{
return _valueAO[add];
}
/// <summary>
/// 读取多个AO模拟量的值
/// </summary>
/// <param name="add">起始地址,从0开始</param>
/// <param name="count">数量</param>
/// <returns></returns>
public int[] ReadAO(int add, int count)
{
int[] sta = new int[count];
Array.Copy(_valueAO, add, sta, 0, count);
return sta;
}
/// <summary>
/// 写入单个DO输出状态(ON/OFF)
/// </summary>
/// <param name="add">输出地址,从0开始</param>
/// <param name="sta"></param>
/// <returns></returns>
public bool WriteDO(int add, Box_Sta sta)
{
try
{
byte[] data = Command();
byte[] buff = new byte[12];
Array.Copy(data, 0, buff, 0, data.Length);
buff[7] = 5; //功能码
buff[9] = _addressOutput[add]; //地址
buff[10] = (byte)sta; //写入值
_send.Enqueue(buff);
if (!_autoReadOutput)
_manualReadOutput = true;
return true;
}
catch (Exception ex)
{
ErrInfo = ex.Message;
return false;
}
}
/// <summary>
/// 获取本地IPv4地址
/// </summary>
/// <returns></returns>
public string[] GetLocalIP()
{
List<string> str = new List<string>();
IPAddress[] add = Dns.GetHostEntry(Dns.GetHostName()).AddressList;
foreach (IPAddress ip in add)
{
if (ip.AddressFamily.ToString() == "InterNetwork")
str.Add(ip.ToString());
}
return str.ToArray();
}
/// <summary>
/// 发送命令
/// </summary>
private void Send()
{
while (_loop)
{
bool rtn = _send.TryDequeue(out byte[] result);
if (rtn)
{
try
{
_client.Send(result);
if (_log != null)
{
if (_logType == LogType.All)
_log.OutData("Send ", result);
}
}
catch (Exception ex)
{
if (_log != null)
_log.OutError(ex.Message);
}
}
Thread.Sleep(SEND_SLEEP);
}
}
/// <summary>
/// 接收命令
/// </summary>
private void Receive()
{
while (_loop)
{
if (_receive.TryDequeue(out byte[] buff))
{
if (_log != null)
{
if (_logType == LogType.All)
_log.OutData("Receive ", buff);
}
if (buff.Length < 7)
continue;
if (buff[7] == 1)
{
ReadDO(buff);
_changeDO = true;
}
else if (buff[7] == 2)
{
ReadDI(buff);
_changeDI = true;
}
else if (buff[7] == 4)
{
ReadAI(buff);
_changeAI = true;
}
else if (buff[7] == 5)
{
//ReadSingle(buff);
}
}
Thread.Sleep(10);
}
}
/// <summary>
/// 读取写入单个DO,功能码5
/// </summary>
/// <param name="buff"></param>
private void ReadSingle(byte[] buff)
{
string s;
//if (LogOut)
//{
// byte[] bb = new byte[2];
// bb[0] = buff[1];
// bb[1] = buff[0];
// ushort flag = BitConverter.ToUInt16(bb, 0);
// s = string.Format("{0:HH:mm:ss:fff} WriteDO {1} fun={2} len={3}", DateTime.Now, flag, buff[7], buff.Length);
// _log.Add(s);
//}
// int n = 0;
// int move = 0;
// byte val = _receive[0][9];
// for (int i = 0; i < 8; i++)
// {
// n = (val & Convert.ToInt32(Math.Pow(2, move))) >> move;
// _sta[i + 16] = n == 1 ? Box_Sta.On : Box_Sta.Off;
// move++;
// }
// if (_receive[0][8] == 2)
// {
// move = 0;
// val = _receive[0][10];
// for (int i = 8; i < 16; i++)
// {
// n = (val & Convert.ToInt32(Math.Pow(2, move))) >> move;
// _sta[i + 16] = n == 1 ? Box_Sta.On : Box_Sta.Off;
// move++;
// }
// }
// ErrInfo = "OK";
//}
//catch (Exception ex)
//{
// ErrInfo = ex.Message;
//}
}
/// <summary>
/// 读取所有DO状态,功能码1
/// </summary>
/// <param name="buff"></param>
private void ReadDO(byte[] buff)
{
try
{
int idx = 0;
int count = buff[8];
for (int i = 1; i <= count; i++)
{
int n = 0;
int move = 0;
byte val = buff[8 + i];
for (int j = 0; j < 8; j++)
{
n = (val & Convert.ToInt32(Math.Pow(2, move))) >> move;
_stateDO[idx++] = n == 1 ? Box_Sta.On : Box_Sta.Off;
move++;
}
}
if (_log != null)
{
if (_logType == LogType.All)
_log.OutData("Read All DO");
}
}
catch (Exception ex)
{
if (_log != null)
_log.OutError(ex.Message);
}
}
/// <summary>
/// 读取所有DI状态,功能码2
/// </summary>
private void ReadDI(byte[] buff)
{
try
{
int idx = 0;
int count = buff[8];
for (int i = 1; i <= count; i++)
{
int n = 0;
int move = 0;
byte val = buff[8 + i];
for (int j = 0; j < 8; j++)
{
n = (val & Convert.ToInt32(Math.Pow(2, move))) >> move;
_stateDI[idx++] = n == 1 ? Box_Sta.On : Box_Sta.Off;
move++;
}
}
if (_log != null)
{
if (_logType == LogType.All)
_log.OutData("Read All DI");
}
}
catch (Exception ex)
{
if (_log != null)
_log.OutError(ex.Message);
}
}
/// <summary>
/// 读取所有AI的值,功能码4
/// </summary>
/// <param name="buff"></param>
private void ReadAI(byte[] buff)
{
try
{
if (countInput * 2 == buff[8])
{
_valueAI[0] = buff[9] * 256 + buff[10];
_valueAI[1] = buff[11] * 256 + buff[12];
_valueAI[2] = buff[13] * 256 + buff[14];
_valueAI[3] = buff[15] * 256 + buff[16];
}
if (_log != null)
{
if (_logType == LogType.All)
_log.OutData("Read All AI");
}
}
catch (Exception ex)
{
if (_log != null)
_log.OutError(ex.Message);
}
}
/// <summary>
/// 命令,前7个字节
/// </summary>
/// <returns></returns>
private byte[] Command()
{
_flag.TryDequeue(out ushort result);
byte[] flag = BitConverter.GetBytes(result);
byte[] data = new byte[7];
data[0] = flag[1];
data[1] = flag[0];
data[2] = 0;
data[3] = 0;
data[4] = 0;
data[5] = 0;
data[6] = 255;
return data;
}
/// <summary>
/// 触发DIO改变事件
/// </summary>
private void TriggerDIO()
{
Box_Sta[] sta = null;
int[] val = null;
while (_loop)
{
//if (_autoReadInput)
//{
if (_typeInput == Box_Type.DI && DI_Changed_Event != null)
{
if (_changeDI)
{
sta = new Box_Sta[countInput];
Array.Copy(_stateDI, 0, sta, 0, sta.Length);
if (_log != null)
{
if (_logType == LogType.All)
_log.OutData("Trigger DI Event");
}
DI_Changed_Event.Invoke(this, sta);
_changeDI = false;
}
}
else if (_typeInput == Box_Type.AI && AI_Changed_Event != null)
{
if (_changeAI)
{
val = new int[countInput];
Array.Copy(_valueAI, 0, val, 0, val.Length);
if (_log != null)
{
if (_logType == LogType.All)
_log.OutData("Trigger AI Event");
}
AI_Changed_Event.Invoke(this, val);
_changeAI = false;
}
}
//}
//if (_autoReadOutput)
//{
if (_typeOutput == Box_Type.DO && DO_Changed_Event != null)
{
if (_changeDO)
{
sta = new Box_Sta[countOutput];
Array.Copy(_stateDO, 0, sta, 0, sta.Length);
if (_log != null)
{
if (_logType == LogType.All)
_log.OutData("Trigger DO Event");
}
DO_Changed_Event.Invoke(this, sta);
_changeDO = false;
}
}
else if (_typeOutput == Box_Type.AO && AO_Changed_Event != null)
{
if (_changeAO)
{
val = new int[countOutput];
Array.Copy(_valueAO, 0, val, 0, val.Length);
if (_log != null)
{
if (_logType == LogType.All)
_log.OutData("Trigger AO Event");
}
AO_Changed_Event.Invoke(this, val);
_changeAO = false;
}
}
//}
Thread.Sleep(10);
}
}
/// <summary>
/// 自动读取输入端线程
/// </summary>
private void AutoReadInput()
{
while (_loop)
{
if (IsConn && _autoReadInput)
{
//if (suspendDI && suspend > 0)
//{
// suspendDI = false;
// suspend--;
//}
//else
//{
byte[] data = Command();
byte[] buff = new byte[12];
Array.Copy(data, 0, buff, 0, data.Length);
buff[5] = 6; //后面字节数
//功能码
if (_typeInput == Box_Type.DI)
buff[7] = 2;
else if (_typeInput == Box_Type.AI)
buff[7] = 4;
buff[9] = _addressInput[0]; //地址
buff[11] = (byte)countInput; //个数
_send.Enqueue(buff);
//suspendDI = true;
//}
}
Thread.Sleep(sleepInput);
}
}
/// <summary>
/// 自动读取输出端线程
/// </summary>
private void AutoReadOutput()
{
while (_loop)
{
Thread.Sleep(sleepOutput);
if (!IsConn) continue;
if (!_autoReadOutput)
{
if (_manualReadOutput)
_manualReadOutput = false;
else
continue;
}
byte[] data = Command();
byte[] buff = new byte[12];
Array.Copy(data, 0, buff, 0, data.Length);
buff[5] = 6; //后面字节数
buff[7] = 1; //功能码
buff[9] = _addressOutput[0]; //地址
buff[11] = (byte)countOutput; //个数
_send.Enqueue(buff);
}
}
/// <summary>
/// 监听结果线程
/// </summary>
private void Listen()
{
byte[] temp = new byte[200];
int start, len;
while (_loop)
{
try
{
if (_client.Available > 0)
{
start = 0;
int count = _client.Receive(temp);
while (count - start > 6)
{
len = temp[start + 5];
len += 6;
if (start + len > count) break;
byte[] aa = new byte[len];
Array.Copy(temp, start, aa, 0, len);
_receive.Enqueue(aa);
start += len;
}
}
}
catch (Exception ex)
{
if (_log != null)
_log.OutError(ex.Message);
}
Thread.Sleep(10);
}
}
private void InitAddr()
{
byte n = 0;
if (_frontInputOutput)
{
_addressInput = new byte[countInput];
for (int i = 0; i < countInput; i++)
_addressInput[i] = n++;
_addressOutput = new byte[countOutput];
for (int i = 0; i < countOutput; i++)
_addressOutput[i] = n++;
}
else
{
_addressOutput = new byte[countOutput];
for (int i = 0; i < countOutput; i++)
_addressOutput[i] = n++;
_addressInput = new byte[countInput];
for (int i = 0; i < countInput; i++)
_addressInput[i] = n++;
}
_stateDI = new Box_Sta[countInput];
_stateDO = new Box_Sta[countOutput];
_valueAI = new int[countInput];
_valueAO = new int[countOutput];
}
private void GetIP()
{
broadcastBuffer = broadcastClient.Receive(ref broadcastEndPoint);
}
private void Flag()
{
ushort n = 0;
while (true)
{
if (_flag.Count < 10)
{
_flag.Enqueue(++n);
if (n == ushort.MaxValue) n = 0;
}
Thread.Sleep(5);
}
}
private bool ReConnect()
{
try
{
//初始化地址
InitAddr();
//检查IP地址
bool rtn = CheckIP(IP);
if (!rtn) return false;
_send = new System.Collections.Concurrent.ConcurrentQueue<byte[]>();
_receive = new System.Collections.Concurrent.ConcurrentQueue<byte[]>();
_flag = new System.Collections.Concurrent.ConcurrentQueue<ushort>();
//建立连接
_client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
_client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, 500);
_client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 500);
_client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.NoDelay, 1);
_client.Connect(IPAddress.Parse(IP), PORT);
Thread.Sleep(100); //需要等待一会才能获取连接状态
tFlag = new Thread(new ThreadStart(Flag));
tFlag.Start();
Thread.Sleep(10);
if (_logPath == null)
_log = null;
else
_log = new LogFile(_logPath, IP);
tSend = new Thread(new ThreadStart(Send));
tReceive = new Thread(new ThreadStart(Receive));
tListen = new Thread(new ThreadStart(Listen));
tTrigger = new Thread(new ThreadStart(TriggerDIO));
tReadInput = new Thread(new ThreadStart(AutoReadInput));
tReadOutput = new Thread(new ThreadStart(AutoReadOutput));
IsConn = true;
_loop = true;
tListen.Start();
tTrigger.Start();
tSend.Start();
tReceive.Start();
tReadInput.Start();
tReadOutput.Start();
ErrInfo = "";
if (_log != null) _log.OutData("Connect OK");
return true;
}
catch (Exception ex)
{
IsConn = false;
ErrInfo = ex.Message;
if (_log != null) _log.OutError(ex.Message);
return false;
}
}
}
/// <summary>
/// IO模块类型
/// </summary>
public enum Box_Type : int
{
/// <summary>
/// 数字信号输入
/// </summary>
DI,
/// <summary>
/// 数字信号输出
/// </summary>
DO,
/// <summary>
/// 模拟量输入
/// </summary>
AI,
/// <summary>
/// 模拟量输出
/// </summary>
AO
}
/// <summary>
/// IO模块寄存器状态
/// </summary>
public enum Box_Sta : int
{
/// <summary>
/// 断开,关闭,低电平
/// </summary>
Off = 0,
/// <summary>
/// 闭合,打开,高电平
/// </summary>
On = 255
}
/// <summary>
/// 日志类型
/// </summary>
public enum LogType : int
{
/// <summary>
/// 仅错误信息
/// </summary>
OnlyError,
/// <summary>
/// 所有
/// </summary>
All
}
}
\ No newline at end of file \ No newline at end of file
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!