using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net; using System.Net.Sockets; using System.Threading; using HslCommunication.Core; namespace HslCommunication.Profinet.Melsec { // internal sealed class MelsecNetMultiAsync : PlcNetBase // { // /// // /// 实例化一个多PLC请求的对象 // /// // /// 要求所有网络号一致 // /// 要求所有站号一致 // /// 要求所有读取类型一致 // /// 要求所有起始地址一致 // /// 要求所有读取数据长度一致 // /// 连接PLC过程中的超时时间 // /// 每次请求访问的间隔时间 // /// 所有等待访问的PLC的IP地址 // /// 访问PLC时的主端口 // /// 访问PLC时的备用端口 // public MelsecNetMultiAsync( // byte networkNumber, // byte networkStationNumber, // MelsecMcDataType type, // ushort address, // ushort length, // int timeout, // int readCycle, // IPAddress[] allAddress, // int portMain, // int portBackup ) // { // NetworkNumber = networkNumber; // NetworkStationNumber = networkStationNumber; // MelsecType = type; // Address = address; // Length = length; // Timeout = timeout; // ReadCycle = readCycle; // //初始化数据对象 // EveryMachineLength = GetLengthFromPlcType( type, length ); // BytesResult = new byte[EveryMachineLength * allAddress.Length]; // PlcStates = new PlcStateOne[allAddress.Length]; // for (int i = 0; i < PlcStates.Length; i++) // { // PlcStates[i] = new PlcStateOne( ) // { // Index = i, // PlcDataHead = new byte[9], // PlcDataContent = new byte[EveryMachineLength], // LengthDataContent = 0, // LengthDataHead = 0, // IsConnect = false, // PlcIpAddress = allAddress[i], // PortMain = portMain, // PortBackup = portBackup, // }; // } // //启动线程 // Thread thread = new Thread( new ThreadStart( ThreadDealWithTimeout ) ) // { // IsBackground = true // }; // thread.Start( ); // } // /********************************************************************************************* // * // * 拷贝的数据方式仍然需要修改 // * // * // *********************************************************************************************/ // private MelsecMcDataType MelsecType = MelsecMcDataType.D; // private ushort Address = 0; // private ushort Length = 0; // /// // /// 超时时间 // /// // private int Timeout = 600; // /// // /// 访问周期 // /// // private int ReadCycle = 1000; // /// // /// 系统的连接状态,0未连接,1连接中 // /// // private int ConnectStatus = 0; // /// // /// 用于存储结果的字节数组 // /// // private byte[] BytesResult = null; // /// // /// 每台设备的长度 // /// // private int EveryMachineLength = 0; // /// // /// 接收到所有的PLC数据时候触发 // /// // public event IEDelegate OnReceivedData = null; // private PlcStateOne[] PlcStates = null; // /// // /// 维护超时连接的线程方法 // /// // private void ThreadDealWithTimeout() // { // LogNet?.WriteInfo( LogHeaderText, "waitting one second" ); // Thread.Sleep( 1000 );// 刚启动的时候进行休眠一小会 // LogNet?.WriteInfo( LogHeaderText, "begining recyle for reading plc" ); // while (true) // { // DateTime firstTime = DateTime.Now;// 连接时间 // TimerCallBack( );// 启动访问PLC // while ((DateTime.Now - firstTime).TotalMilliseconds < Timeout) // { // // 超时时间等待 // } // // 连接超时处理 // for (int i = 0; i < PlcStates.Length; i++) // { // if (!PlcStates[i].IsConnect) PlcStates[i].WorkSocket.Close( ); // } // while ((DateTime.Now - firstTime).TotalMilliseconds < ReadCycle) // { // // 等待下次连接 // } // } // } // private void TimerCallBack() // { // // 如果已经连接就返回,此处采用原子操作实现 // if (Interlocked.CompareExchange( ref ConnectStatus, 1, 0 ) == 0) // { // m_ac = new AsyncCoordinator( ); // for (int i = 0; i < PlcStates.Length; i++) // { // PlcStates[i].IsConnect = false; // PlcStates[i].WorkSocket = new Socket( AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp ); // PlcStates[i].WorkSocket.BeginConnect( new IPEndPoint( PlcStates[i].PlcIpAddress, PlcStates[i].GetPort( ) ), new AsyncCallback( PlcConnectCallBack ), PlcStates[i] ); // PlcStates[i].LengthDataHead = 0; // PlcStates[i].LengthDataContent = 0; // m_ac.AboutToBegin( 1 ); // } // // 启动检查连接情况 // m_ac.AllBegun( AllDown ); // } // } // private byte[] ConnectWrongHead = new byte[] { 0x00, 0x01 }; // private void PlcConnectCallBack( IAsyncResult ar ) // { // if (ar.AsyncState is PlcStateOne stateone) // { // try // { // stateone.WorkSocket.EndConnect( ar ); // stateone.WorkSocket.BeginReceive( // stateone.PlcDataHead, // stateone.LengthDataHead, // stateone.PlcDataHead.Length - stateone.LengthDataHead, // SocketFlags.None, // new AsyncCallback( PlcHeadReceiveCallBack ), // stateone ); // stateone.IsConnect = true;// 指示访问成功 // } // catch (Exception ex) // { // LogNet?.WriteException( ToString(), "connect failed", ex ); // // 访问失败 // stateone.WorkSocket.Close( ); // // 初始化数据 // Array.Copy( ConnectWrongHead, 0, BytesResult, stateone.Index * EveryMachineLength, 2 ); // // 更换端口 // stateone.ChangePort( ); // // 结束任务 // m_ac.JustEnded( ); // } // } // } // private void PlcHeadReceiveCallBack( IAsyncResult ar ) // { // if (ar.AsyncState is PlcStateOne stateone) // { // try // { // stateone.LengthDataHead += stateone.WorkSocket.EndReceive( ar ); // if (stateone.LengthDataHead < stateone.PlcDataHead.Length) // { // // 继续接收头格式 // stateone.WorkSocket.BeginReceive( // stateone.PlcDataHead, // stateone.LengthDataHead, // stateone.PlcDataHead.Length - stateone.LengthDataHead, // SocketFlags.None, // new AsyncCallback( PlcHeadReceiveCallBack ), // stateone ); // } // else // { // // 计算接下来的接收长度,最少还有2个长度的字节数据 // int NeedReceived = BitConverter.ToUInt16( stateone.PlcDataHead, 7 ); // stateone.PlcDataContent = new byte[NeedReceived]; // // 接收内容 // stateone.WorkSocket.BeginReceive( // stateone.PlcDataContent, // 0, // stateone.PlcDataContent.Length - stateone.LengthDataContent, // SocketFlags.None, // new AsyncCallback( PlcContentReceiveCallBack ), // stateone ); // } // } // catch (Exception ex) // { // LogNet?.WriteException( LogHeaderText, "Head receive", ex ); // // 由于未知原因,数据接收失败 // stateone.WorkSocket.Close( ); // // 初始化数据 // Array.Copy( ConnectWrongHead, 0, BytesResult, stateone.Index * EveryMachineLength, 2 ); // // 结束任务 // m_ac.JustEnded( ); // } // } // } // private void PlcContentReceiveCallBack( IAsyncResult ar ) // { // if (ar.AsyncState is PlcStateOne stateone) // { // try // { // stateone.LengthDataContent += stateone.WorkSocket.EndReceive( ar ); // if (stateone.LengthDataHead < stateone.PlcDataHead.Length) // { // // 继续接内容格式 // stateone.WorkSocket.BeginReceive( // stateone.PlcDataContent, // stateone.LengthDataContent, // stateone.PlcDataContent.Length - stateone.LengthDataContent, // SocketFlags.None, // new AsyncCallback( PlcContentReceiveCallBack ), // stateone ); // } // else // { // // 所有内容接收完成 // int error = BitConverter.ToUInt16( stateone.PlcDataContent, 0 ); // if (error > 0) // { // Array.Copy( ConnectWrongHead, 0, BytesResult, stateone.Index * EveryMachineLength, 2 ); // } // else // { // Array.Copy( stateone.PlcDataContent, 0, BytesResult, stateone.Index * EveryMachineLength, stateone.PlcDataContent.Length ); // } // // 关闭连接 // stateone.WorkSocket.Close( ); // // 结束任务 // m_ac.JustEnded( ); // } // } // catch (Exception ex) // { // LogNet?.WriteException( LogHeaderText, "Data receive", ex ); // // 由于未知原因,数据接收失败 // stateone.WorkSocket.Close( ); // // 初始化数据 // Array.Copy( ConnectWrongHead, 0, BytesResult, stateone.Index * EveryMachineLength, 2 ); // // 结束任务 // m_ac.JustEnded( ); // } // } // } // private void AllDown( CoordinationStatus status ) // { // // 此处没有取消和超时状态,直接完成 // if (status == CoordinationStatus.AllDone) // { // Interlocked.Exchange( ref ConnectStatus, 0 ); // LogNet?.WriteDebug( LogHeaderText, "All bytes read complete." ); // OnReceivedData?.Invoke( BytesResult.ToArray( ) ); // } // } // private AsyncCoordinator m_ac = new AsyncCoordinator( ); // } }