private OperateResult <Socket> ConnectAsync(IPEndPoint endPoint, int timeOut)
        {
            var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            var state  = new StateObjectAsync <Socket>( );

            state.Tcs        = new TaskCompletionSource <Socket>( );
            state.WorkSocket = socket;

            // timeout check
            HslTimeOut connectTimeout = new HslTimeOut( )
            {
                WorkSocket = socket,
                DelayTime  = timeOut
            };

            ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadPoolCheckTimeOut), connectTimeout);

            try
            {
                socket.BeginConnect(endPoint, new AsyncCallback(ConnectAsyncCallBack), state);
                socket = state.Tcs.Task.Result;
                return(OperateResult.CreateSuccessResult(socket));
            }
            catch (Exception ex)
            {
                return(new OperateResult <Socket>(ex.Message));
            }
        }
Esempio n. 2
0
        /// <summary>
        /// 读写ModBus服务器的基础方法,支持任意的数据操作
        /// </summary>
        /// <param name="socket">网络服务数据</param>
        /// <param name="send">发送的字节数据</param>
        /// <param name="result">结果对象</param>
        /// <returns></returns>
        private bool ReadFromModBusSocket(System.Net.Sockets.Socket socket, byte[] send, OperateResult <byte[]> result)
        {
            if (!SendBytesToSocket(socket, send, result, "发送数据到服务器失败"))
            {
                return(false);
            }

            HslTimeOut hslTimeOut = new HslTimeOut();

            hslTimeOut.WorkSocket = socket;
            hslTimeOut.DelayTime  = 2000;                      // 2秒内接收到数据
            try
            {
                System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(
                                                                  ThreadPoolCheckConnect), hslTimeOut);
                byte[] head = NetSupport.ReadBytesFromSocket(socket, 6);

                int    length = head[4] * 256 + head[5];
                byte[] data   = NetSupport.ReadBytesFromSocket(socket, length);

                byte[] buffer = new byte[6 + length];
                head.CopyTo(buffer, 0);
                data.CopyTo(buffer, 6);
                hslTimeOut.IsSuccessful = true;
                result.Content          = buffer;
            }
            catch (Exception ex)
            {
                socket?.Close();
                result.Message = "从服务器接收结果数据的时候发生错误:" + ex.Message;
                return(false);
            }

            return(true);
        }
Esempio n. 3
0
        /// <summary>
        /// 向PLC写入数据,数据格式为原始的字节类型
        /// </summary>
        /// <param name="type">写入的数据类型</param>
        /// <param name="address">初始地址</param>
        /// <param name="data">原始的字节数据</param>
        /// <returns>结果</returns>
        public OperateResult WriteIntoPLC(MelsecDataType type, ushort address, byte[] data)
        {
            OperateResult <byte[]> result = new OperateResult <byte[]>();

            byte[] _PLCCommand = GetWriteCommand(type, address, data);

            Array.Copy(data, 0, _PLCCommand, 21, data.Length);

            //测试指令数据
            //string test = ByteToHexString(_PLCCommand);

            Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            HslTimeOut timeout = new HslTimeOut()
            {
                WorkSocket = socket
            };

            try
            {
                ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadPoolCheckConnect), timeout);
                socket.Connect(new IPEndPoint(PLCIpAddress, PortWrite));
                timeout.IsSuccessful = true;
            }
            catch
            {
                result.Message = StringResources.ConnectedFailed;
                socket.Close();
                return(result);
            }
            byte[] DataHead = null;
            try
            {
                socket.Send(_PLCCommand);
                //先接收满9个数据
                int NeedReceived = 9;
                DataHead         = NetSupport.ReadBytesFromSocket(socket, NeedReceived);
                NeedReceived     = BitConverter.ToUInt16(DataHead, 7);
                DataHead         = NetSupport.ReadBytesFromSocket(socket, NeedReceived);
                result.ErrorCode = BitConverter.ToUInt16(DataHead, 0);
                result.IsSuccess = true;
            }
            catch (Exception ex)
            {
                result.Message = StringResources.SocketIOException + ex.Message;
                Thread.Sleep(10);
                socket.Close();
                return(result);
            }
            socket.Shutdown(SocketShutdown.Both);
            Thread.Sleep(10);
            socket.Close();
            socket = null;
            if (result.ErrorCode > 0)
            {
                result.IsSuccess = false;
            }
            return(result);
        }
Esempio n. 4
0
        /// <summary>
        /// [自校验] 接收一条完整的同步数据,包含头子节和内容字节,基础的数据,如果结果异常,则结束通讯
        /// </summary>
        /// <param name="socket">套接字</param>
        /// <param name="timeout">超时时间设置,如果为负数,则不检查超时</param>
        /// <returns></returns>
        /// <exception cref="ArgumentNullException">result</exception>
        protected OperateResult <byte[], byte[]> ReceiveAndCheckBytes(Socket socket, int timeout)
        {
            // 30秒超时接收验证
            HslTimeOut hslTimeOut = new HslTimeOut( )
            {
                DelayTime    = timeout,
                IsSuccessful = false,
                StartTime    = DateTime.Now,
                WorkSocket   = socket,
            };

            if (timeout > 0)
            {
                ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadPoolCheckTimeOut), hslTimeOut);
            }

            // 接收头指令
            OperateResult <byte[]> headResult = Receive(socket, HslProtocol.HeadByteLength);

            if (!headResult.IsSuccess)
            {
                hslTimeOut.IsSuccessful = true;
                return(OperateResult.CreateFailedResult <byte[], byte[]>(headResult));
            }
            hslTimeOut.IsSuccessful = true;

            // 检查令牌
            if (!CheckRemoteToken(headResult.Content))
            {
                socket?.Close( );
                return(new OperateResult <byte[], byte[]>( )
                {
                    Message = StringResources.TokenCheckFailed
                });
            }

            int contentLength = BitConverter.ToInt32(headResult.Content, HslProtocol.HeadByteLength - 4);
            // 接收内容
            OperateResult <byte[]> contentResult = Receive(socket, contentLength);

            if (!contentResult.IsSuccess)
            {
                return(OperateResult.CreateFailedResult <byte[], byte[]>(contentResult));
            }

            // 返回成功信息
            OperateResult checkResult = SendLong(socket, HslProtocol.HeadByteLength + contentLength);

            if (!checkResult.IsSuccess)
            {
                return(OperateResult.CreateFailedResult <byte[], byte[]>(checkResult));
            }

            byte[] head    = headResult.Content;
            byte[] content = contentResult.Content;
            content = HslProtocol.CommandAnalysis(head, content);
            return(OperateResult.CreateSuccessResult(head, content));
        }
Esempio n. 5
0
        /// <summary>
        /// 创建一个新的socket对象并连接到远程的地址
        /// </summary>
        /// <param name="endPoint">连接的目标终结点</param>
        /// <param name="timeOut">连接的超时时间</param>
        /// <returns>返回套接字的封装结果对象</returns>
        /// <example>
        /// <code lang="cs" source="HslCommunication_Net45.Test\Documentation\Samples\Core\NetworkBase.cs" region="CreateSocketAndConnectExample" title="创建连接示例" />
        /// </example>
        protected OperateResult <Socket> CreateSocketAndConnect(IPEndPoint endPoint, int timeOut)
        {
            var result      = new OperateResult <Socket>( );
            var connectDone = new ManualResetEvent(false);
            var state       = new StateObject( );
            var socket      = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            // 超时验证的信息
            HslTimeOut connectTimeout = new HslTimeOut( )
            {
                WorkSocket = socket,
                DelayTime  = timeOut
            };

            ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadPoolCheckTimeOut), connectTimeout);

            try
            {
                state.WaitDone   = connectDone;
                state.WorkSocket = socket;
                socket.BeginConnect(endPoint, new AsyncCallback(ConnectCallBack), state);
            }
            catch (Exception ex)
            {
                // 直接失败
                connectTimeout.IsSuccessful = true;                      // 退出线程池的超时检查
                LogNet?.WriteException(ToString( ), ex);                 // 记录错误日志
                socket.Close( );                                         // 关闭网络信息
                connectDone.Close( );                                    // 释放等待资源
                result.Message = "Connect Failed : " + ex.Message;       // 传递错误消息
                return(result);
            }



            // 等待连接完成
            connectDone.WaitOne( );
            connectDone.Close( );
            connectTimeout.IsSuccessful = true;

            if (state.IsError)
            {
                // 连接失败
                result.Message = "Connect Failed : " + state.ErrerMsg;
                socket?.Close( );
                return(result);
            }


            result.Content   = socket;
            result.IsSuccess = true;
            state.Clear( );
            state = null;
            return(result);
        }
Esempio n. 6
0
        /// <summary>
        /// 读写ModBus服务器的基础方法,支持任意的数据操作
        /// </summary>
        /// <param name="send">发送的字节数据</param>
        /// <returns></returns>
        public OperateResult <byte[]> ReadFromModBusServer(byte[] send)
        {
            OperateResult <byte[]> result = new OperateResult <byte[]>();

            readModbusLock.Enter();

            if (!CreateSocketAndConnect(out System.Net.Sockets.Socket socket, iPEndPoint, result))
            {
                readModbusLock.Leave();
                socket = null;
                return(result);
            }

            if (!SendBytesToSocket(socket, send, result, "发送数据到服务器失败"))
            {
                readModbusLock.Leave();
                return(result);
            }


            HslTimeOut hslTimeOut = new HslTimeOut();

            hslTimeOut.WorkSocket = socket;
            hslTimeOut.DelayTime  = 5000;                      // 2秒内接收到数据
            try
            {
                System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(
                                                                  ThreadPoolCheckConnect), hslTimeOut);
                byte[] head = NetSupport.ReadBytesFromSocket(socket, 6);

                int    length = head[4] * 256 + head[5];
                byte[] data   = NetSupport.ReadBytesFromSocket(socket, length);

                byte[] buffer = new byte[6 + length];
                head.CopyTo(buffer, 0);
                data.CopyTo(buffer, 6);
                hslTimeOut.IsSuccessful = true;
                result.Content          = buffer;
            }
            catch (Exception ex)
            {
                socket?.Close();
                result.Message = "从服务器接收结果数据的时候发生错误:" + ex.Message;
                readModbusLock.Leave();
                return(result);
            }

            socket?.Close();

            readModbusLock.Leave();

            result.IsSuccess = true;
            return(result);
        }
 /// <summary>
 /// 检查是否超时的静态方法
 /// </summary>
 /// <param name="timeout">数据封送对象</param>
 /// <param name="millisecond">超时的时间</param>
 internal static void ThreadPoolCheckConnect(HslTimeOut timeout, int millisecond)
 {
     while (!timeout.IsSuccessful)
     {
         if ((DateTime.Now - timeout.StartTime).TotalMilliseconds > millisecond)
         {
             // 连接超时或是验证超时
             if (!timeout.IsSuccessful)
             {
                 timeout.WorkSocket?.Close( );
             }
             break;
         }
         Thread.Sleep(100);
     }
 }
Esempio n. 8
0
        /// <summary>
        /// 接收一条完整的 <seealso cref="INetMessage"/> 数据内容 ->
        /// Receive a complete <seealso cref="INetMessage"/> data content
        /// </summary>
        /// <param name="socket">网络的套接字</param>
        /// <param name="timeOut">超时时间</param>
        /// <param name="netMessage">消息的格式定义</param>
        /// <returns>带有是否成功的byte数组对象</returns>
        protected OperateResult <byte[]> ReceiveByMessage(Socket socket, int timeOut, INetMessage netMessage)
        {
            HslTimeOut hslTimeOut = new HslTimeOut( )
            {
                DelayTime  = timeOut,
                WorkSocket = socket,
            };

            if (timeOut > 0)
            {
                ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadPoolCheckTimeOut), hslTimeOut);
            }

            // 接收指令头
            OperateResult <byte[]> headResult = Receive(socket, netMessage.ProtocolHeadBytesLength);

            if (!headResult.IsSuccess)
            {
                hslTimeOut.IsSuccessful = true;
                return(headResult);
            }

            netMessage.HeadBytes = headResult.Content;
            int contentLength = netMessage.GetContentLengthByHeadBytes( );

            if (contentLength <= 0)
            {
                hslTimeOut.IsSuccessful = true;
                return(headResult);
            }

            OperateResult <byte[]> contentResult = Receive(socket, contentLength);

            if (!contentResult.IsSuccess)
            {
                hslTimeOut.IsSuccessful = true;
                return(contentResult);
            }

            // 防止没有实例化造成后续的操作失败
            hslTimeOut.IsSuccessful = true;
            netMessage.ContentBytes = contentResult.Content;
            return(OperateResult.CreateSuccessResult(SoftBasic.SpliceTwoByteArray(headResult.Content, contentResult.Content)));
        }
Esempio n. 9
0
        /// <summary>
        /// 从西门子PLC中读取想要的数据,返回结果类说明
        /// </summary>
        /// <param name="type">想要读取的数据类型</param>
        /// <param name="address">读取数据的起始地址</param>
        /// <param name="lengh">读取的数据长度</param>
        /// <returns>返回读取结果</returns>
        public OperateResult <byte[]> ReadFromPLC(SiemensDataType type, ushort address, ushort lengh)
        {
            OperateResult <byte[]> result = new OperateResult <byte[]>();

            byte[] _PLCCommand = new byte[16];
            _PLCCommand[0] = 0x53;
            _PLCCommand[1] = 0x35;
            _PLCCommand[2] = 0x10;
            _PLCCommand[3] = 0x01;
            _PLCCommand[4] = 0x03;
            _PLCCommand[5] = 0x05;
            _PLCCommand[6] = 0x03;
            _PLCCommand[7] = 0x08;

            //指定数据区
            _PLCCommand[8] = type.DataCode;
            _PLCCommand[9] = 0x00;

            //指定数据地址
            _PLCCommand[10] = (byte)(address / 256);
            _PLCCommand[11] = (byte)(address % 256);

            //指定数据长度
            _PLCCommand[12] = (byte)(lengh / 256);
            _PLCCommand[13] = (byte)(lengh % 256);

            _PLCCommand[14] = 0xff;
            _PLCCommand[15] = 0x02;


            //超时验证的线程池技术
            Socket     socket  = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            HslTimeOut timeout = new HslTimeOut()
            {
                WorkSocket = socket
            };

            try
            {
                ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadPoolCheckConnect), timeout);
                socket.Connect(new IPEndPoint(PLCIpAddress, GetPort()));
                timeout.IsSuccessful = true;
            }
            catch
            {
                ChangePort();
                result.Message = StringResources.ConnectedFailed;
                Thread.Sleep(10);
                socket?.Close();
                return(result);
            }
            try
            {
                //连接成功,发送数据
                socket.Send(_PLCCommand);
                byte[] rec_head = NetSupport.ReadBytesFromSocket(socket, 16);
                if (rec_head[8] != 0x00)
                {
                    result.ErrorCode = rec_head[8];
                    Thread.Sleep(10);
                    socket?.Close();
                    return(result);
                }
                result.Content   = NetSupport.ReadBytesFromSocket(socket, lengh);
                result.IsSuccess = true;
                result.Message   = "读取成功";
            }
            catch (Exception ex)
            {
                result.Message = StringResources.SocketIOException + ex.Message;
                Thread.Sleep(10);
                socket?.Close();
                return(result);
            }
            Thread.Sleep(10);
            socket?.Close();
            //所有的数据接收完成,进行返回
            return(result);
        }
Esempio n. 10
0
        /// <summary>
        /// 向PLC中写入数据,返回值说明
        /// </summary>
        /// <param name="type">要写入的数据类型</param>
        /// <param name="address">要写入的数据地址</param>
        /// <param name="data">要写入的实际数据</param>
        /// <exception cref="ArgumentNullException">写入的数据不能为空</exception>
        /// <returns>返回写入结果</returns>
        public OperateResult <byte[]> WriteIntoPLC(SiemensDataType type, ushort address, byte[] data)
        {
            var result = new OperateResult <byte[]>();

            byte[] _PLCCommand = new byte[16 + data.Length];
            _PLCCommand[0] = 0x53;
            _PLCCommand[1] = 0x35;
            _PLCCommand[2] = 0x10;
            _PLCCommand[3] = 0x01;
            _PLCCommand[4] = 0x03;
            _PLCCommand[5] = 0x03;
            _PLCCommand[6] = 0x03;
            _PLCCommand[7] = 0x08;

            //指定数据区
            _PLCCommand[8] = type.DataCode;
            _PLCCommand[9] = 0x00;

            //指定数据地址
            _PLCCommand[10] = (byte)(address / 256);
            _PLCCommand[11] = (byte)(address % 256);

            //指定数据长度
            _PLCCommand[12] = (byte)(data.Length / 256);
            _PLCCommand[13] = (byte)(data.Length % 256);

            _PLCCommand[14] = 0xff;
            _PLCCommand[15] = 0x02;

            //放置数据
            Array.Copy(data, 0, _PLCCommand, 16, data.Length);


            //超时验证的线程池技术
            var socket  = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            var timeout = new HslTimeOut()
            {
                WorkSocket = socket
            };

            try
            {
                ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadPoolCheckConnect), timeout);
                socket.Connect(new IPEndPoint(PLCIpAddress, PortWrite));
                timeout.IsSuccessful = true;
            }
            catch
            {
                result.Message = StringResources.ConnectedFailed;
                Thread.Sleep(10);
                socket?.Close();
                return(result);
            }
            try
            {
                //连接成功,发送数据
                socket.Send(_PLCCommand);
                byte[] rec_head = NetSupport.ReadBytesFromSocket(socket, 16);
                //分析数据
                if (rec_head[8] != 0x00)
                {
                    result.ErrorCode = rec_head[8];
                    Thread.Sleep(10);
                    socket?.Close();
                    return(result);
                }
                socket.Shutdown(SocketShutdown.Both);
                socket.Close();
                result.IsSuccess = true;
                result.Message   = "写入成功";
            }
            catch (Exception ex)
            {
                result.Message = StringResources.SocketIOException + ex.Message;
                Thread.Sleep(10);
                socket?.Close();
                return(result);
            }
            return(result);
        }
Esempio n. 11
0
        /// <summary>
        /// 接收一条完整的数据,使用异步接收完成,包含了指令头信息
        /// </summary>
        /// <param name="socket">已经打开的网络套接字</param>
        /// <param name="timeOut">超时时间</param>
        /// <param name="netMsg">消息规则</param>
        /// <returns>数据的接收结果对象</returns>
        protected OperateResult <TNetMessage> ReceiveMessage <TNetMessage>(Socket socket, int timeOut, TNetMessage netMsg) where TNetMessage : INetMessage
        {
            OperateResult <TNetMessage> result = new OperateResult <TNetMessage>();

            // 超时接收的代码验证
            HslTimeOut hslTimeOut = new HslTimeOut()
            {
                DelayTime  = timeOut,
                WorkSocket = socket,
            };

            if (timeOut > 0)
            {
                ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadPoolCheckTimeOut), hslTimeOut);
            }

            // 接收指令头
            OperateResult <byte[]> headResult = Receive(socket, netMsg.ProtocolHeadBytesLength);

            if (!headResult.IsSuccess)
            {
                hslTimeOut.IsSuccessful = true;
                result.CopyErrorFromOther(headResult);
                return(result);
            }

            netMsg.HeadBytes = headResult.Content;
            if (!netMsg.CheckHeadBytesLegal(Token.ToByteArray()))
            {
                // 令牌校验失败
                hslTimeOut.IsSuccessful = true;
                socket?.Close();
                LogNet?.WriteError(ToString(), StringResources.TokenCheckFailed);
                result.Message = StringResources.TokenCheckFailed;
                return(result);
            }


            int contentLength = netMsg.GetContentLengthByHeadBytes();

            if (contentLength == 0)
            {
                netMsg.ContentBytes = new byte[0];
            }
            else
            {
                OperateResult <byte[]> contentResult = Receive(socket, contentLength);
                if (!headResult.IsSuccess)
                {
                    hslTimeOut.IsSuccessful = true;
                    result.CopyErrorFromOther(contentResult);
                    return(result);
                }

                netMsg.ContentBytes = contentResult.Content;
            }

            // 防止没有实例化造成后续的操作失败
            if (netMsg.ContentBytes == null)
            {
                netMsg.ContentBytes = new byte[0];
            }
            hslTimeOut.IsSuccessful = true;
            result.Content          = netMsg;
            result.IsSuccess        = true;
            return(result);
        }
Esempio n. 12
0
        /// <summary>
        /// 创建一个新的socket对象并连接到远程的地址
        /// </summary>
        /// <param name="endPoint">连接的目标终结点</param>
        /// <param name="timeOut">连接的超时时间</param>
        /// <returns>返回套接字的封装结果对象</returns>
        /// <example>
        /// <code lang="cs" source="HslCommunication_Net45.Test\Documentation\Samples\Core\NetworkBase.cs" region="CreateSocketAndConnectExample" title="创建连接示例" />
        /// </example>
        protected OperateResult <Socket> CreateSocketAndConnect(IPEndPoint endPoint, int timeOut)
        {
            if (UseSynchronousNet)
            {
                var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                try
                {
                    HslTimeOut connectTimeout = new HslTimeOut( )
                    {
                        WorkSocket = socket,
                        DelayTime  = timeOut
                    };
                    ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadPoolCheckTimeOut), connectTimeout);
                    socket.Connect(endPoint);
                    connectTimeout.IsSuccessful = true;

                    return(OperateResult.CreateSuccessResult(socket));
                }
                catch (Exception ex)
                {
                    socket?.Close( );
                    LogNet?.WriteException("CreateSocketAndConnect", ex);
                    return(new OperateResult <Socket>(ex.Message));
                }
            }
            else
            {
#if NET35
                OperateResult <Socket> result      = new OperateResult <Socket>( );
                ManualResetEvent       connectDone = null;
                StateObject            state       = null;
                try
                {
                    connectDone = new ManualResetEvent(false);
                    state       = new StateObject( );
                }
                catch (Exception ex)
                {
                    return(new OperateResult <Socket>(ex.Message));
                }


                var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                // 超时验证的信息
                HslTimeOut connectTimeout = new HslTimeOut( )
                {
                    WorkSocket = socket,
                    DelayTime  = timeOut
                };
                ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadPoolCheckTimeOut), connectTimeout);

                try
                {
                    state.WaitDone   = connectDone;
                    state.WorkSocket = socket;
                    socket.BeginConnect(endPoint, new AsyncCallback(ConnectCallBack), state);
                }
                catch (Exception ex)
                {
                    // 直接失败
                    connectTimeout.IsSuccessful = true;                                     // 退出线程池的超时检查
                    LogNet?.WriteException(ToString( ), ex);                                // 记录错误日志
                    socket.Close( );                                                        // 关闭网络信息
                    connectDone.Close( );                                                   // 释放等待资源
                    result.Message = StringResources.Language.ConnectedFailed + ex.Message; // 传递错误消息
                    return(result);
                }



                // 等待连接完成
                connectDone.WaitOne( );
                connectDone.Close( );
                connectTimeout.IsSuccessful = true;

                if (state.IsError)
                {
                    // 连接失败
                    result.Message = StringResources.Language.ConnectedFailed + state.ErrerMsg;
                    socket?.Close( );
                    return(result);
                }


                result.Content   = socket;
                result.IsSuccess = true;
                state.Clear( );
                state = null;
                return(result);
#else
                var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                var state  = new StateObjectAsync <Socket>( );
                state.Tcs        = new TaskCompletionSource <Socket>( );
                state.WorkSocket = socket;

                // timeout check
                HslTimeOut connectTimeout = new HslTimeOut( )
                {
                    WorkSocket = socket,
                    DelayTime  = timeOut
                };
                ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadPoolCheckTimeOut), connectTimeout);

                try
                {
                    socket.BeginConnect(endPoint, new AsyncCallback(ConnectAsyncCallBack), state);
                    socket = state.Tcs.Task.Result;
                    return(OperateResult.CreateSuccessResult(socket));
                }
                catch (Exception ex)
                {
                    return(new OperateResult <Socket>(ex.Message));
                }
#endif
            }
        }
Esempio n. 13
0
        /// <summary>
        /// 从三菱PLC中读取想要的数据,返回读取结果
        /// </summary>
        /// <param name="type">想要读取的数据类型</param>
        /// <param name="address">读取数据的起始地址</param>
        /// <param name="length">读取的数据长度,字最大值960,位最大值7168</param>
        /// <returns>带数据头的字节数组</returns>
        public OperateResult <byte[]> ReadFromPLC(MelsecDataType type, ushort address, ushort length)
        {
            OperateResult <byte[]> result = new OperateResult <byte[]>();

            //获取指令
            byte[] _PLCCommand = GetReadCommand(type, address, length);


            Socket     socket  = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            HslTimeOut timeout = new HslTimeOut()
            {
                WorkSocket = socket
            };

            try
            {
                ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadPoolCheckConnect), timeout);
                socket.Connect(new IPEndPoint(PLCIpAddress, GetPort()));
                timeout.IsSuccessful = true;
            }
            catch
            {
                ChangePort();
                result.Message = StringResources.ConnectedFailed;;
                socket.Close();
                return(result);
            }
            byte[] DataHead = null;
            try
            {
                socket.Send(_PLCCommand);
                //先接收满9个数据
                int NeedReceived = 9;
                DataHead     = NetSupport.ReadBytesFromSocket(socket, NeedReceived);
                NeedReceived = BitConverter.ToUInt16(DataHead, 7);
                DataHead     = NetSupport.ReadBytesFromSocket(socket, NeedReceived);
                //获取读取代码
                result.ErrorCode = BitConverter.ToUInt16(DataHead, 0);
                result.Content   = new byte[DataHead.Length - 2];
                Array.Copy(DataHead, 2, result.Content, 0, DataHead.Length - 2);
                if (type.DataType == 1)
                {
                    result.Content = ReceiveBytesTranslate(result.Content);
                }
                result.IsSuccess = true;
            }
            catch (Exception ex)
            {
                result.Message = StringResources.SocketIOException + ex.Message;
                socket.Close();
                return(result);
            }
            socket.Shutdown(SocketShutdown.Both);
            socket.Close();
            socket = null;
            if (result.ErrorCode > 0)
            {
                result.IsSuccess = false;
            }
            return(result);
        }