/// <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 = ModbusFactory.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; } } }