public async void ServerRespectsMaxClientConnectionLimit() { // Arrange var endpoint = EndpointSource.GetNext(); using var server = new ModbusTcpServer() { MaxConnections = 2 }; server.Start(endpoint); // Act var client1 = new ModbusTcpClient(); var client2 = new ModbusTcpClient(); var client3 = new ModbusTcpClient(); await Task.Run(() => { client1.Connect(endpoint); client1.WriteSingleRegister(0, 2, 3); client2.Connect(endpoint); client2.WriteSingleRegister(0, 2, 3); client3.Connect(endpoint); try { client3.WriteSingleRegister(0, 2, 3); throw new Exception("Modbus TCP server accepts too many clients."); } // Windows catch (IOException) { } // Linux catch (InvalidOperationException) { } server.MaxConnections = 3; client3.Connect(endpoint); client3.WriteSingleRegister(0, 2, 3); }); // Assert }
public void CanReadMaximumNumberOfRegisters() { // Arrange var endpoint = EndpointSource.GetNext(); var server = new ModbusTcpServer(); server.Start(endpoint); var client = new ModbusTcpClient(); client.Connect(endpoint); // Act client.ReadHoldingRegisters <ushort>(0, 0, 125); client.ReadInputRegisters <ushort>(0, 0, 125); }
public async void ServerHandlesMultipleClients() { // Arrange var endpoint = EndpointSource.GetNext(); using var server = new ModbusTcpServer(); server.Start(endpoint); // Act var clients = Enumerable.Range(0, 20).Select(index => new ModbusTcpClient()).ToList(); var tasks = clients.Select((client, index) => { var data = Enumerable.Range(0, 20).Select(i => (float)i).ToArray(); client.Connect(endpoint); _logger.WriteLine($"Client {index}: Connected."); return(Task.Run(async() => { _logger.WriteLine($"Client {index}: Task started."); for (int i = 0; i < 10; i++) { client.ReadHoldingRegisters <short>(0, 0, 100); _logger.WriteLine($"Client {index}: ReadHoldingRegisters({i})"); await Task.Delay(50); client.WriteMultipleRegisters(0, 0, data); _logger.WriteLine($"Client {index}: WriteMultipleRegisters({i})"); await Task.Delay(50); client.ReadCoils(0, 0, 25); _logger.WriteLine($"Client {index}: ReadCoils({i})"); await Task.Delay(50); client.ReadInputRegisters <float>(0, 0, 20); _logger.WriteLine($"Client {index}: ReadInputRegisters({i})"); await Task.Delay(50); } client.Disconnect(); })); }).ToList(); await Task.WhenAll(tasks); // Assert }
public void ThrowsWhenWritingTooManyRegisters() { // Arrange var endpoint = EndpointSource.GetNext(); using var server = new ModbusTcpServer(); server.Start(endpoint); var client = new ModbusTcpClient(); client.Connect(endpoint); // Act Action action = () => client.WriteMultipleRegisters <ushort>(0, 0, new ushort[124]); // Assert Assert.Throws <ModbusException>(action); }
public void ThrowsIfZeroBytesAreRequested() { // Arrange var endpoint = EndpointSource.GetNext(); using var server = new ModbusTcpServer(); server.Start(endpoint); var client = new ModbusTcpClient(); client.Connect(endpoint); // Act Action action = () => client.ReadHoldingRegisters <byte>(0, 0, 0); // Assert Assert.Throws <ModbusException>(action); }
public void ThrowsIfOddNumberOfBytesIsRequested() { // Arrange var endpoint = EndpointSource.GetNext(); using var server = new ModbusTcpServer(); server.Start(endpoint); var client = new ModbusTcpClient(); client.Connect(endpoint); // Act Action action = () => client.ReadHoldingRegisters <byte>(0, 0, 3); // Assert Assert.Throws <ArgumentOutOfRangeException>(action); }
public void ThrowsWhenReadingTooManyRegisters() { // Arrange var endpoint = EndpointSource.GetNext(); using var server = new ModbusTcpServer(); server.Start(endpoint); var client = new ModbusTcpClient(); client.Connect(endpoint); // Act Action action1 = () => client.ReadHoldingRegisters <ushort>(0, 0, 126); Action action2 = () => client.ReadInputRegisters <ushort>(0, 0, 126); // Assert Assert.Throws <ModbusException>(action1); Assert.Throws <ModbusException>(action2); }
public void ArraySizeIsCorrectForBooleanInput() { // Arrange var endpoint = EndpointSource.GetNext(); using var server = new ModbusTcpServer(); server.Start(endpoint); var client = new ModbusTcpClient(); client.Connect(endpoint); // Act var actual = client.ReadHoldingRegisters <bool>(0, 0, 10).ToArray().Count(); // Assert var expected = 10; Assert.True(actual == expected); }
public async Task FC023Test() { // Arrange var endpoint = EndpointSource.GetNext(); using var server = new ModbusTcpServer(); server.Start(endpoint); void AsyncWorkaround() { var buffer = server.GetHoldingRegisterBuffer <float>(); buffer[6] = 65.455F; buffer[7] = 24; buffer[8] = 25; } lock (server.Lock) { AsyncWorkaround(); } var client = new ModbusTcpClient(); client.Connect(endpoint); // Act var actual1 = await client.ReadWriteMultipleRegistersAsync <float, float>(0, 2, 10, 12, new float[] { 1.211F }); // Assert var expected = new float[] { 0, 0, 0, 0, 0, 1.211F, 24, 25, 0, 0 }; Assert.True(expected.SequenceEqual(actual1.ToArray())); lock (server.Lock) { var actual2 = server.GetHoldingRegisterBuffer <float>().Slice(1, 10).ToArray(); Assert.True(expected.SequenceEqual(actual2)); } }
public async void ServerWorksWithExternalTcpClient() { // Arrange var endpoint = EndpointSource.GetNext(); var listener = new TcpListener(endpoint); using var server = new ModbusTcpServer(); var client = new ModbusTcpClient(); var expected = new double[] { 0.1, 0.2, 0.3, 0.4, 0.5 }; double[] actual = null; // Act listener.Start(); var clientTask = Task.Run(() => { client.Connect(endpoint); actual = client .ReadWriteMultipleRegisters <double, double>(0, 0, 5, 0, expected) .ToArray(); client.Disconnect(); }); var serverTask = Task.Run(() => { var tcpClient = listener.AcceptTcpClient(); server.Start(tcpClient); }); await clientTask; // Assert Assert.True(actual.SequenceEqual(expected)); }
public void BigEndianWritePerformanceTest() { // Arrange var endpoint = EndpointSource.GetNext(); using var server = new ModbusTcpServer(); server.Start(endpoint); var buffer = server.GetHoldingRegisters(); // Act var sw = Stopwatch.StartNew(); for (int i = 0; i < 1_000_000; i++) { buffer.SetBigEndian(address: 1, 12334234.0); } // Assert var elapsed = sw.Elapsed; _logger.WriteLine($"Time per 1000 write operations: {elapsed.TotalMilliseconds / 1000} ms"); }
public void FC16Test() { // Arrange var endpoint = EndpointSource.GetNext(); using var server = new ModbusTcpServer(); server.Start(endpoint); var client = new ModbusTcpClient(); client.Connect(endpoint); // Act client.WriteMultipleRegisters(0, 2, _array); // Assert var expected = _array; lock (server.Lock) { var actual = server.GetHoldingRegisterBuffer <float>().Slice(1, 10); Assert.True(expected.SequenceEqual(actual.ToArray())); } }
public void HandlesBigEndian() { // Arrange var endpoint = EndpointSource.GetNext(); using var server = new ModbusTcpServer(); server.Start(endpoint); var client = new ModbusTcpClient(); client.Connect(endpoint, ModbusEndianness.BigEndian); // Act client.WriteMultipleRegisters(0, 0, new int[] { 0x20302020, 0x40101010, 0x11220000 }); // Assert var expected = new int[] { 0x20203020, 0x10101040, 0x00002211 }; lock (server.Lock) { var actual = server.GetHoldingRegisterBuffer <int>().Slice(0, 3); Assert.True(expected.SequenceEqual(actual.ToArray())); } }