コード例 #1
0
        /// <summary>
        /// Catches all exceptions thrown when action is executed and removes the master end point.
        /// The exception is ignored when it simply signals a master closing its connection.
        /// </summary>
        internal void CatchExceptionAndRemoveMasterEndPoint(Action action, string endPoint)
        {
            if (action == null)
                throw new ArgumentNullException("action");
            if (endPoint == null)
                throw new ArgumentNullException("endPoint");
            if (endPoint.IsNullOrEmpty())
                throw new ArgumentException("Argument endPoint cannot be empty.");

            try
            {
                action.Invoke();
            }
            catch (IOException ioe)
            {
                _log.DebugFormat("IOException encountered in ReadHeaderCompleted - {0}", ioe.Message);
                ModbusMasterTcpConnectionClosed.Raise(this, new TcpConnectionEventArgs(EndPoint));

                SocketException socketException = ioe.InnerException as SocketException;
                if (socketException != null && socketException.ErrorCode == Modbus.ConnectionResetByPeer)
                {
                    _log.Debug("Socket Exception ConnectionResetByPeer, Master closed connection.");
                    return;
                }

                throw;
            }
            catch (Exception e)
            {
                _log.Error("Unexpected exception encountered", e);
                throw;
            }
        }
コード例 #2
0
        private async Task HandleRequestAsync()
        {
            while (true)
            {
#if ModBusDebug
                Debug.WriteLine($"Begin reading header from Master at IP: {EndPoint}");
#endif
                int readBytes = await Stream.ReadAsync(_mbapHeader, 0, 6).ConfigureAwait(false);

                if (readBytes == 0)
                {
#if ModBusDebug
                    Debug.WriteLine($"0 bytes read, Master at {EndPoint} has closed Socket connection.");
#endif
                    ModbusMasterTcpConnectionClosed?.Invoke(this, new TcpConnectionEventArgs(EndPoint));
                    return;
                }

                ushort frameLength = (ushort)IPAddress.HostToNetworkOrder(BitConverter.ToInt16(_mbapHeader, 4));
#if ModBusDebug
                Debug.WriteLine($"Master at {EndPoint} sent header: \"{string.Join(", ", _mbapHeader)}\" with {frameLength} bytes in PDU");
#endif

                _messageFrame = new byte[frameLength];
                readBytes     = await Stream.ReadAsync(_messageFrame, 0, frameLength).ConfigureAwait(false);

                if (readBytes == 0)
                {
#if ModBusDebug
                    Debug.WriteLine($"0 bytes read, Master at {EndPoint} has closed Socket connection.");
#endif
                    ModbusMasterTcpConnectionClosed?.Invoke(this, new TcpConnectionEventArgs(EndPoint));
                    return;
                }
#if ModBusDebug
                Debug.WriteLine($"Read frame from Master at {EndPoint} completed {readBytes} bytes");
#endif
                byte[] frame = _mbapHeader.Concat(_messageFrame).ToArray();
#if ModBusDebug
                Debug.WriteLine($"RX from Master at {EndPoint}: {string.Join(", ", frame)}");
#endif

                var request = ModbusMessageFactory.CreateModbusRequest(_messageFrame);
                request.TransactionId = (ushort)IPAddress.NetworkToHostOrder(BitConverter.ToInt16(frame, 0));

                // perform action and build response
                IModbusMessage response = _slave.ApplyRequest(request);
                response.TransactionId = request.TransactionId;

                // write response
                byte[] responseFrame = Transport.BuildMessageFrame(response);
#if ModBusDebug
                Debug.WriteLine($"TX to Master at {EndPoint}: {string.Join(", ", responseFrame)}");
#endif
                await Stream.WriteAsync(responseFrame, 0, responseFrame.Length).ConfigureAwait(false);
            }
        }
コード例 #3
0
        /// <summary>
        /// Catches all exceptions thrown when action is executed and removes the master end point.
        /// The exception is ignored when it simply signals a master closing its connection.
        /// </summary>
        internal void CatchExceptionAndRemoveMasterEndPoint(Action action, string endPoint)
        {
            try
            {
                if (action == null)
                {
                    throw new ArgumentNullException("action");
                }
                if (endPoint == null)
                {
                    throw new ArgumentNullException("endPoint");
                }
                if (endPoint.IsNullOrEmpty())
                {
                    throw new ArgumentException("Argument endPoint cannot be empty.");
                }

                try
                {
                    action.Invoke();
                }
                catch (IOException ioe)
                {
                    _log.DebugFormat("IOException encountered in ReadHeaderCompleted - {0}", ioe.Message);
                    ModbusMasterTcpConnectionClosed.Raise(this, new TcpConnectionEventArgs(EndPoint));

                    SocketException socketException = ioe.InnerException as SocketException;
                    if (socketException != null && socketException.ErrorCode == Modbus.ConnectionResetByPeer)
                    {
                        _log.Debug("Socket Exception ConnectionResetByPeer, Master closed connection.");
                        return;
                    }

                    Console.WriteLine("Caught some unknown exception but not throwing it: " + ioe.Message);
                    throw;
                }
                catch (ArgumentException e)
                {
                    //We don't have handle this but we don't want to crash
                    if (e.Message.Contains("Unsupported function code"))
                    {
                        Console.WriteLine(e.Message);
                    }
                }
                catch (Exception e)
                {
                    _log.Error("Unexpected exception encountered", e);
                    Console.WriteLine("Caught some unknown exception but not throwing it: " + e.Message);
                    throw;
                }
            }
            catch (Exception err)
            {
                Console.WriteLine("Caught Some Exception not thowing " + err.Message);
            }
        }
コード例 #4
0
        internal void ReadHeaderCompleted(IAsyncResult ar)
        {
            Debug.WriteLine("Read header completed.");

            CatchExceptionAndRemoveMasterEndPoint(() =>
            {
                // this is the normal way a master closes its connection
                if (Stream.EndRead(ar) == 0)
                {
                    Debug.WriteLine("0 bytes read, Master has closed Socket connection.");
                    ModbusMasterTcpConnectionClosed.Raise(this, new TcpConnectionEventArgs(EndPoint));
                    return;
                }

                Debug.WriteLine("MBAP header: {0}", string.Join(", ", _mbapHeader));
                ushort frameLength = (ushort)IPAddress.HostToNetworkOrder(BitConverter.ToInt16(_mbapHeader, 4));
                Debug.WriteLine("{0} bytes in PDU.", frameLength);
                _messageFrame = new byte[frameLength];

                Stream.BeginRead(_messageFrame, 0, frameLength, ReadFrameCompleted, null);
            }, EndPoint);
        }
コード例 #5
0
        /// <summary>
        ///     Catches all exceptions thrown when action is executed and removes the master end point.
        ///     The exception is ignored when it simply signals a master closing its connection.
        /// </summary>
        internal void CatchExceptionAndRemoveMasterEndPoint(Action action, string endPoint)
        {
            if (action == null)
            {
                throw new ArgumentNullException("action");
            }
            if (endPoint == null)
            {
                throw new ArgumentNullException("endPoint");
            }
            if (endPoint == string.Empty)
            {
                throw new ArgumentException(Resources.EmptyEndPoint);
            }

            try
            {
                action.Invoke();
            }
            catch (IOException ioe)
            {
                Debug.WriteLine("IOException encountered in ReadHeaderCompleted - {0}", ioe.Message);
                ModbusMasterTcpConnectionClosed.Raise(this, new TcpConnectionEventArgs(EndPoint));

                SocketException socketException = ioe.InnerException as SocketException;
                if (socketException != null && socketException.ErrorCode == Modbus.ConnectionResetByPeer)
                {
                    Debug.WriteLine("Socket Exception ConnectionResetByPeer, Master closed connection.");
                    return;
                }

                throw;
            }
            catch (Exception e)
            {
                Debug.WriteLine("Unexpected exception encountered: [{0}] {1}", e.GetType().Name, e.Message);
                throw;
            }
        }
コード例 #6
0
        internal void ReadHeaderCompleted(IAsyncResult ar)
        {
            Log.Debug("XmlSettingsReadFile header completed.");

            CatchExceptionAndRemoveMasterEndPoint(() =>
            {
                // this is the normal way a master closes its connection
                if (Stream.EndRead(ar) == 0)
                {
                    Log.Debug("0 bytes read, Master has closed Socket connection.");
                    ModbusMasterTcpConnectionClosed.Raise(this, new TcpConnectionEventArgs(EndPoint));
                    return;
                }

                Log.Debug($"MBAP header: {_mbapHeader.JoinByCommas()}");
                ushort frameLength = (ushort)IPAddress.HostToNetworkOrder(BitConverter.ToInt16(_mbapHeader, 4));
                Log.Debug($"{frameLength} bytes in PDU.");
                _messageFrame = new byte[frameLength];

                Stream.BeginRead(_messageFrame, 0, frameLength, ReadFrameCompleted, null);
            }, EndPoint);
        }
コード例 #7
0
        private async Task HandleRequestAsync()
        {
            var serialTransport = (IModbusSerialTransport)Transport;

            while (true)
            {
                try
                {
                    // read request and build message
                    byte[] frame = serialTransport.ReadRequest();

                    //Create the request
                    IModbusMessage request = _modbusFactory.CreateModbusRequest(frame);

                    //Check the message
                    if (serialTransport.CheckFrame && !serialTransport.ChecksumsMatch(request, frame))
                    {
                        string msg = $"Checksums failed to match {string.Join(", ", request.MessageFrame)} != {string.Join(", ", frame)}.";
                        //Logger.Warning(msg);
                        throw new IOException(msg);
                    }

                    //Apply the request
                    // TODO: почистить класс и предусмотреть броадкаст request.SlaveAddress ==0
                    IModbusMessage response = _slaveNetwork.GetSlave(request.SlaveAddress)
                                              .ApplyRequest(request);

                    if (response == null)
                    {
                        serialTransport.IgnoreResponse();
                    }
                    else
                    {
                        Transport.Write(response);
                    }
                }
                catch (IOException /*ioe*/)
                {
                    //Logger.Warning($"IO Exception encountered while listening for requests - {ioe.Message}");
                    serialTransport.DiscardInBuffer();

                    ModbusMasterTcpConnectionClosed?.Invoke(this, new TcpConnectionEventArgs(EndPoint));
                }
                catch (TimeoutException /*te*/)
                {
                    //Logger.Trace($"Timeout Exception encountered while listening for requests - {te.Message}");
                    serialTransport.DiscardInBuffer();
                }
                catch (InvalidOperationException)
                {
                    // when the underlying transport is disposed
                    break;
                }
                catch (Exception /*ex*/)
                {
                    //Logger.Error($"{GetType()}: {ex.Message}");
                    serialTransport.DiscardInBuffer();
                }

                /* // OLD CODE
                 * // //Logger.Debug($"Begin reading header from Master at IP: {EndPoint}");
                 *
                 * int readBytes = await Stream.ReadAsync(_mbapHeader, 0, 6).ConfigureAwait(false);
                 * if (readBytes == 0)
                 * {
                 *  //Logger.Debug($"0 bytes read, Master at {EndPoint} has closed Socket connection.");
                 *  ModbusMasterTcpConnectionClosed?.Invoke(this, new TcpConnectionEventArgs(EndPoint));
                 *  return;
                 * }
                 *
                 * ushort frameLength = (ushort)IPAddress.HostToNetworkOrder(BitConverter.ToInt16(_mbapHeader, 4));
                 * //Logger.Debug($"Master at {EndPoint} sent header: \"{string.Join(", ", _mbapHeader)}\" with {frameLength} bytes in PDU");
                 *
                 * _messageFrame = new byte[frameLength];
                 * readBytes = await Stream.ReadAsync(_messageFrame, 0, frameLength).ConfigureAwait(false);
                 * if (readBytes == 0)
                 * {
                 *  //Logger.Debug($"0 bytes read, Master at {EndPoint} has closed Socket connection.");
                 *  ModbusMasterTcpConnectionClosed?.Invoke(this, new TcpConnectionEventArgs(EndPoint));
                 *  return;
                 * }
                 *
                 * //Logger.Debug($"Read frame from Master at {EndPoint} completed {readBytes} bytes");
                 * byte[] frame = _mbapHeader.Concat(_messageFrame).ToArray();
                 * //Logger.Trace($"RX from Master at {EndPoint}: {string.Join(", ", frame)}");
                 *
                 * var request = _modbusFactory.CreateModbusRequest(_messageFrame);
                 * request.TransactionId = (ushort)IPAddress.NetworkToHostOrder(BitConverter.ToInt16(frame, 0));
                 *
                 * IModbusSlave slave = _slaveNetwork.GetSlave(request.SlaveAddress);
                 *
                 * if (slave != null)
                 * {
                 *  //TODO: Determine if this is appropriate
                 *
                 *  // perform action and build response
                 *  IModbusMessage response = slave.ApplyRequest(request);
                 *  response.TransactionId = request.TransactionId;
                 *
                 *  // write response
                 *  byte[] responseFrame = Transport.BuildMessageFrame(response);
                 *  //Logger.Information($"TX to Master at {EndPoint}: {string.Join(", ", responseFrame)}");
                 *  await Stream.WriteAsync(responseFrame, 0, responseFrame.Length).ConfigureAwait(false);
                 * }
                 */
            }
        }