12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788 |
- using System;
- using System.Diagnostics;
- using System.Linq;
- using System.Net;
- using System.Net.Sockets;
- using System.Threading;
- using System.Threading.Tasks;
- using NModbus.IO;
- using NModbus.Logging;
- using NModbus.Unme.Common;
- namespace NModbus.Device
- {
- using Extensions;
- /// <summary>
- /// Modbus UDP slave device.
- /// </summary>
- public class ModbusUdpSlaveNetwork : ModbusSlaveNetwork
- {
- private readonly UdpClient _udpClient;
- public ModbusUdpSlaveNetwork(UdpClient udpClient, IModbusFactory modbusFactory, IModbusLogger logger)
- : base(new ModbusIpTransport(new UdpClientAdapter(udpClient), modbusFactory, logger), modbusFactory, logger)
- {
- _udpClient = udpClient;
- }
- /// <summary>
- /// Start slave listening for requests.
- /// </summary>
- public override async Task ListenAsync(CancellationToken cancellationToken = new CancellationToken())
- {
- using (cancellationToken.Register(() =>
- {
- _udpClient.Dispose();
- }))
- {
- 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( ObjectDisposedException) when (cancellationToken.IsCancellationRequested)
- {
- // Swallow this error.
- }
- catch (SocketException se)
- {
- // this hapens when slave stops
- if (se.SocketErrorCode != SocketError.Interrupted)
- {
- throw;
- }
- }
- }
- }
- }
- }
|