using System.Net.Sockets; using InnovEnergy.Lib.Protocols.Modbus.Protocol; namespace InnovEnergy.Lib.Protocols.Modbus.Connections; public class ModbusTcpConnection : ModbusConnection { private String Hostname { get; } private Int32 Port { get; } private Byte[] Buffer { get; } = new Byte[1024]; private TcpClient? _TcpClient; public ModbusTcpConnection(String hostname, Int32 port = 502) { Hostname = hostname; Port = port; } public override IReadOnlyList Receive(UInt16 bytesToRead) { var bytesReceived = 0; var stream = TcpClient().GetStream(); do { var maxBytes = Math.Min(bytesToRead, Buffer.Length) - bytesReceived; var read = stream.Read(Buffer, bytesReceived, maxBytes); if (read <= 0) throw new NotConnectedException("The TCP Connection was closed"); bytesReceived += read; } while (bytesReceived < bytesToRead); return new ArraySegment(Buffer, 0, bytesToRead); } public override void Transmit(IEnumerable data) { var array = data.ToArray(); TcpClient().GetStream().Write(array, 0, array.Length); } public override void Open() => TcpClient(); private TcpClient TcpClient() { return _TcpClient ??= new TcpClient(Hostname, Port); } public override void Close() { try { _TcpClient?.Dispose(); } catch (Exception) { // ignored } _TcpClient = null; } }