예제 #1
0
        internal void ReceiveRequestCompleted(IAsyncResult ar)
        {
            IPEndPoint masterEndPoint = null;

            byte[] frame;

            try
            {
                frame = _udpClient.EndReceive(ar, ref masterEndPoint);
            }
            catch (ObjectDisposedException)
            {
                // this hapens when slave stops
                return;
            }

            ModbusUdpSlave slave = (ModbusUdpSlave)ar.AsyncState;

            _logger.DebugFormat("Read Frame completed {0} bytes", frame.Length);
            _logger.InfoFormat("RX: {0}", frame.Join(", "));

            IModbusMessage request = ModbusMessageFactory.CreateModbusRequest(frame.Slice(6, frame.Length - 6).ToArray());

            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);
            _logger.InfoFormat("TX: {0}", responseFrame.Join(", "));
            _udpClient.BeginSend(responseFrame, responseFrame.Length, masterEndPoint, WriteResponseCompleted, null);
        }
예제 #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
        public byte[] BuildWriteMessage(byte slaveAddress, ushort registerAddress, ushort value)
        {
            var request = new WriteSingleRegisterRequestResponse(
                slaveAddress,
                registerAddress,
                value);

            return(Transport.BuildMessageFrame(request));
        }
예제 #4
0
        public byte[] BuildReadMessage(byte slaveAddress, ushort startAddress, ushort numberOfPoints)
        {
            var request = new ReadHoldingInputRegistersRequest(
                Modbus.ReadHoldingRegisters,
                slaveAddress,
                startAddress,
                numberOfPoints);

            return(Transport.BuildMessageFrame(request));
        }
예제 #5
0
        /// <summary>
        ///     Start slave listening for requests.
        /// </summary>
        public override async Task ListenAsync(CancellationToken cancellationToken = new CancellationToken())
        {
            Logger.Information("Start Modbus Udp Server.");

            try
            {
                while (!cancellationToken.IsCancellationRequested)
                {
                    UdpReceiveResult receiveResult = await _udpClient.ReceiveAsync().ConfigureAwait(false);

                    IPEndPoint masterEndPoint = receiveResult.RemoteEndPoint;
                    byte[]     frame          = receiveResult.Buffer;

                    Debug.WriteLine($"Read Frame completed {frame.Length} bytes");

                    Logger.LogFrameRx(frame);

                    IModbusMessage request =
                        ModbusMessageFactory.CreateModbusRequest(frame.Slice(6, frame.Length - 6).ToArray());
                    request.TransactionId = (ushort)IPAddress.NetworkToHostOrder(BitConverter.ToInt16(frame, 0));

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

                    if (response != null)
                    {
                        response.TransactionId = request.TransactionId;

                        // write response
                        byte[] responseFrame = Transport.BuildMessageFrame(response);

                        Logger.LogFrameTx(frame);

                        await _udpClient.SendAsync(responseFrame, responseFrame.Length, masterEndPoint)
                        .ConfigureAwait(false);
                    }
                }
            }
            catch (SocketException se)
            {
                // this hapens when slave stops
                if (se.SocketErrorCode != SocketError.Interrupted)
                {
                    throw;
                }
            }
        }
예제 #6
0
        /// <summary>
        ///     Start slave listening for requests.
        /// </summary>
        public override async Task ListenAsync()
        {
            Debug.WriteLine("Start Modbus Udp Server.");

            try
            {
                while (true)
                {
                    UdpReceiveResult receiveResult = await _udpClient.ReceiveAsync().ConfigureAwait(false);

                    IPEndPoint masterEndPoint = receiveResult.RemoteEndPoint;
                    byte[]     frame          = receiveResult.Buffer;
#if ModBusDebug
                    Debug.WriteLine($"Read Frame completed {frame.Length} bytes");
                    Debug.WriteLine($"RX: {string.Join(", ", frame)}");
#endif
                    IModbusMessage request =
                        ModbusMessageFactory.CreateModbusRequest(frame.Slice(6, frame.Length - 6).ToArray());
                    request.TransactionId = (ushort)IPAddress.NetworkToHostOrder(BitConverter.ToInt16(frame, 0));

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

                    // write response
                    byte[] responseFrame = Transport.BuildMessageFrame(response);
#if ModBusDebug
                    Debug.WriteLine($"TX: {string.Join(", ", responseFrame)}");
#endif
                    await _udpClient.SendAsync(responseFrame, responseFrame.Length, masterEndPoint).ConfigureAwait(false);
                }
            }
            catch (SocketException se)
            {
                // this hapens when slave stops
                if (se.SocketErrorCode != SocketError.Interrupted)
                {
                    throw;
                }
            }
        }
예제 #7
0
        internal void ReadFrameCompleted(IAsyncResult ar)
        {
            CatchExceptionAndRemoveMasterEndPoint(() =>
            {
                Log.Debug($"XmlSettingsReadFile Frame completed {Stream.EndRead(ar)} bytes");
                byte[] frame = _mbapHeader.Concat(_messageFrame).ToArray();
                Log.Info($"RX: {frame.JoinByCommas()}");

                IModbusMessage request = ModbusMessageFactory.CreateModbusRequest(frame.Slice(6, frame.Length - 6).ToArray());
                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);
                Log.Info($"TX: {responseFrame.JoinByCommas()}");
                Stream.BeginWrite(responseFrame, 0, responseFrame.Length, WriteCompleted, null);
            }, EndPoint);
        }
예제 #8
0
        /// <summary>
        ///     Start slave listening for requests.
        /// </summary>
        public override void Listen()
        {
            Debug.WriteLine("Start Modbus Udp Server.");

            try
            {
                while (true)
                {
                    IPEndPoint masterEndPoint = null;
                    byte[]     frame;

                    frame = _udpClient.Receive(ref masterEndPoint);

                    Debug.WriteLine("Read Frame completed {frame.Length} bytes");
                    Debug.WriteLine("RX: {string.Join(", ", frame)}");

                    IModbusMessage request =
                        ModbusMessageFactory.CreateModbusRequest(frame.Slice(6, frame.Length - 6).ToArray());
                    request.TransactionId = (ushort)IPAddress.NetworkToHostOrder(BitConverter.ToInt16(frame, 0));

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

                    // write response
                    byte[] responseFrame = Transport.BuildMessageFrame(response);
                    Debug.WriteLine("TX: {string.Join(", ", responseFrame)}");
                    _udpClient.Send(responseFrame, responseFrame.Length, masterEndPoint);
                }
            }
            catch (SocketException se)
            {
                // this hapens when slave stops
                if (se.ErrorCode != Modbus.WSACancelBlockingCall)
                {
                    throw;
                }
            }
        }
예제 #9
0
        private void ReadFrameCompleted(IAsyncResult ar)
        {
            CatchExceptionAndRemoveMasterEndPoint(() =>
            {
                Debug.WriteLine("Read Frame completed {0} bytes", Stream.EndRead(ar));
                byte[] frame = _mbapHeader.Concat(_messageFrame).ToArray();
                Debug.WriteLine("RX: {0}", string.Join(", ", frame));

                IModbusMessage request =
                    ModbusMessageFactory.CreateModbusRequest(frame.Slice(6, frame.Length - 6).ToArray());
                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);
                Debug.WriteLine("TX: {0}", string.Join(", ", responseFrame));
                Stream.BeginWrite(responseFrame, 0, responseFrame.Length, WriteCompleted, null);
            }, EndPoint);
        }