using System.Net.Sockets; using InnovEnergy.Lib.Protocols.Modbus.Protocol; namespace InnovEnergy.Lib.Protocols.Modbus.Channels; public class TcpChannel : ConnectionChannel { public TcpChannel(String hostname, Int32 port, Boolean closeAfterSuccessfulRead = false, Boolean closeAfterSuccessfulWrite = false) : base(closeAfterSuccessfulRead, closeAfterSuccessfulWrite) { TcpClient Open() => new(hostname, port); _Open = Open; } private readonly Func _Open; protected override TcpClient Open() => _Open(); protected override void Close(TcpClient tcpClient) => tcpClient.Close(); protected override IReadOnlyList Read(TcpClient tcpClient, Int32 nToRead) { var buffer = new Byte[nToRead]; var stream = tcpClient.GetStream(); var nReceived = 0; do { var nRemaining = nToRead - nReceived; var read = stream.Read(buffer, nReceived, nRemaining); if (read <= 0) throw new NotConnectedException("The TCP Connection was closed"); nReceived += read; } while (nReceived < nToRead); return buffer; } protected override void Write(TcpClient tcpClient, IReadOnlyList data) { var array = data.ToArray(); tcpClient.GetStream().Write(array, 0, array.Length); } }